Exemple #1
0
def _submit_order(order_book_id, amount, side, position_effect, style,
                  quantity, auto_switch_order_value):
    # param: amount: the target quantity of this order
    # param: quantity: the quantity of exist position of order_book_id
    context = Context.get_instance()
    if isinstance(style, LimitOrder):
        if not is_valid_price(style.get_limit_price()):
            raise RuntimeError((u"Limit order price should be positive"))
    price = context.get_last_price(order_book_id)
    if not is_valid_price(price):
        print("Order Creation Failed: [{order_book_id}] No market data"
              ).format(order_book_id=order_book_id)
        return
    round_lot = 100

    if side in [SIDE.BUY, side.SELL]:
        if not (side == SIDE.SELL and quantity == abs(amount)):
            # KSH can buy(sell) 201, 202 shares
            amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot

    if amount == 0:
        print(
            "Order Creation Failed: 0 order quantity, order_book_id={order_book_id}"
        ).format(order_book_id=order_book_id)
        return
    order = Order.__from_create__(order_book_id, abs(amount), side, style,
                                  position_effect)
    if order.type == ORDER_TYPE.MARKET:
        order.set_frozen_price(price)
    if side == SIDE.BUY and auto_switch_order_value:
        account, position = _get_account_position_ins(order_book_id)
        if not is_cash_enough(order, account):
            print(
                "insufficient cash, use all remaining cash({}) to create order"
            ).format(account.cash)
            return _order_value(account, position, order_book_id, account.cash,
                                style)
    return order
Exemple #2
0
def _order_value(account, position, order_book_id, cash_amount, style):
    context = Context.get_instance()
    if cash_amount > 0:
        cash_amount = min(cash_amount, account.cash)
    if isinstance(style, LimitOrder):
        price = style.get_limit_price()
    else:
        price = context.get_last_price(order_book_id)
        if not is_valid_price(price):
            print("Order Creation Failed: [{order_book_id}] No market data"
                  ).format(order_book_id=order_book_id)
            return

    amount = int(Decimal(cash_amount) / Decimal(price))

    round_lot = 100  #int(ins.round_lot)
    if cash_amount > 0:
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
        while amount > 0:
            expected_transaction_cost = context.get_order_transaction_cost(
                Order.__from_create__(order_book_id, amount, SIDE.BUY,
                                      LimitOrder(price), POSITION_EFFECT.OPEN))
            if amount * price + expected_transaction_cost <= cash_amount:
                break
            amount -= round_lot
        else:
            print("Order Creation Failed: 0 order quantity")
            return

    if amount < 0:
        amount = max(amount, -position.closable)

    return _order_shares(order_book_id,
                         amount,
                         style,
                         position.quantity,
                         auto_switch_order_value=False)
Exemple #3
0
def order_target_weights(target_weights: Dict[str, float]) -> List[Order]:
    """
    make the account position to touch the target position
    :param target_weights: a dictionary contain the target weight of position
    :example:
    .. code-block:: python
        # adjust positions, to make the '000001.XSHE' to touch the target percent of account 10%
        # make the '000002.XSHE' to touch the target percent of account 15% 
        order_target_weights({
            '000001.XSHE': 0.1
            '000002.XSHE': 0.15
        })
    """

    total_percent = sum(six.itervalues(target_weights))
    if total_percent > 1 and not np.isclose(total_percent, 1):
        raise RuntimeError("total percent should be lower than 1, current: {}"
                           ).format(total_percent)

    context = Context.get_instance()
    account = context.portfolio.accounts[DEFAULT_ACCOUNT_TYPE.STOCK]
    account_value = account.get_current_trading_dt_total_value()

    #
    target_quantities = {}
    for order_book_id, target_percent in target_weights.items():

        if target_percent < 0:
            raise RuntimeError(
                "target percent of {} should between 0 and 1, current: {}".
                format(order_book_id, target_percent))
        price = context.get_last_price(order_book_id)
        #print("trading_dt:{} current price: {}".format(context.trading_dt, price))
        if not is_valid_price(price):
            print("Order Creation Failed: [{order_book_id}] No market data".
                  format(order_book_id=order_book_id))

            continue
        target_quantity = account_value * target_percent / price
        target_quantities[order_book_id] = int(
            round(target_quantity / 100) * 100)  #target_quantity#

    close_orders, open_orders = [], []
    current_quantities = {
        p.order_book_id: p.quantity
        for p in account.get_positions()
        if p.direction == POSITION_DIRECTION.LONG
    }
    for order_book_id, quantity in current_quantities.items():
        if order_book_id not in target_weights:
            close_orders.append(
                Order.__from_create__(order_book_id, quantity, SIDE.SELL,
                                      MarketOrder(), POSITION_EFFECT.CLOSE))

    round_lot = 100
    for order_book_id, target_quantity in target_quantities.items():
        if order_book_id in current_quantities:
            delta_quantity = target_quantity - current_quantities[order_book_id]
        else:
            delta_quantity = target_quantity

        if delta_quantity >= round_lot:
            delta_quantity = math.floor(delta_quantity / round_lot) * round_lot
            open_orders.append(
                Order.__from_create__(order_book_id, delta_quantity, SIDE.BUY,
                                      MarketOrder(), POSITION_EFFECT.OPEN))
        elif delta_quantity < -1:
            delta_quantity = math.floor(delta_quantity)
            close_orders.append(
                Order.__from_create__(order_book_id,
                                      abs(delta_quantity), SIDE.SELL,
                                      MarketOrder(), POSITION_EFFECT.CLOSE))

    to_submit_orders = []
    for order in chain(close_orders, open_orders):
        #print("to submit order: {}".format(order))
        to_submit_orders.append(order)
    return to_submit_orders
Exemple #4
0
 def prev_close(self):
     if not is_valid_price(self._prev_close):
         context = Context.get_instance()
         self._prev_close = context.data_source.get_prev_close(self._order_book_id, context.trading_dt)
     return self._prev_close