コード例 #1
0
ファイル: api_booking.py プロジェクト: gaoyunhua/rqalpha
def order_shares(id_or_ins, amount, price=None, style=None):
    order_book_id = assure_order_book_id(id_or_ins)
    env = Environment.get_instance()

    if amount > 0:
        side = SIDE.BUY
        position_effect = POSITION_EFFECT.OPEN
    else:
        amount = abs(amount)
        side = SIDE.SELL
        position_effect = POSITION_EFFECT.CLOSE

    round_lot = int(env.get_instrument(order_book_id).round_lot)
    try:
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
    except ValueError:
        amount = 0

    order = Order.__from_create__(order_book_id, amount, side, style, position_effect)

    if amount == 0:
        # 如果计算出来的下单量为0, 则不生成Order, 直接返回None
        # 因为很多策略会直接在handle_bar里面执行order_target_percent之类的函数,经常会出现下一个量为0的订单,如果这些订单都生成是没有意义的。
        order.mark_rejected(_(u"Order Creation Failed: 0 order quantity"))
        return order

    env.broker.submit_order(order)
    return order
コード例 #2
0
ファイル: api_base.py プロジェクト: gaoyunhua/rqalpha
def submit_order(id_or_ins, amount, side, price=None, position_effect=None):

    order_book_id = assure_order_book_id(id_or_ins)
    env = Environment.get_instance()
    if env.config.base.run_type != RUN_TYPE.BACKTEST:
        if "88" in order_book_id:
            raise RQInvalidArgument(_(u"Main Future contracts[88] are not supported in paper trading."))
        if "99" in order_book_id:
            raise RQInvalidArgument(_(u"Index Future contracts[99] are not supported in paper trading."))
    style = cal_style(price, None)
    market_price = env.get_last_price(order_book_id)
    if not is_valid_price(market_price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id)
        )
        return

    order = Order.__from_create__(
        order_book_id=order_book_id,
        quantity=amount,
        side=side,
        style=style,
        position_effect=position_effect
    )

    if order.type == ORDER_TYPE.MARKET:
        order.set_frozen_price(market_price)
    if env.can_submit_order(order):
        env.broker.submit_order(order)
    return order
コード例 #3
0
ファイル: api_stock.py プロジェクト: 8dspaces/rqalpha
def _sell_all_stock(order_book_id, amount, style):
    env = Environment.get_instance()
    order = Order.__from_create__(order_book_id, amount, SIDE.SELL, style, None)
    if amount == 0:
        order.mark_rejected(_(u"Order Creation Failed: 0 order quantity"))
        return order

    if env.can_submit_order(order):
        env.broker.submit_order(order)
    return order
コード例 #4
0
ファイル: api_stock.py プロジェクト: ricequant/rqalpha
def _sell_all_stock(order_book_id, amount, style):
    env = Environment.get_instance()
    order = Order.__from_create__(order_book_id, amount, SIDE.SELL, style, POSITION_EFFECT.CLOSE)
    if amount == 0:
        user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
        return

    if env.can_submit_order(order):
        env.broker.submit_order(order)
        return order
コード例 #5
0
    def set_state(self, state):
        self._open_orders = []
        self._delayed_orders = []

        value = jsonpickle.loads(state.decode('utf-8'))
        for v in value['open_orders']:
            o = Order()
            o.set_state(v)
            account = self._env.get_account(o.order_book_id)
            self._open_orders.append((account, o))
        for v in value['delayed_orders']:
            o = Order()
            o.set_state(v)
            account = self._env.get_account(o.order_book_id)
            self._delayed_orders.append((account, o))
コード例 #6
0
def make_order_from_vnpy_trade(vnpy_trade):
    order_book_id = make_order_book_id(vnpy_trade.symbol)
    quantity = vnpy_trade.volume
    side = SIDE_REVERSE[vnpy_trade.direction]
    style = LimitOrder(vnpy_trade.price)
    position_effect = make_position_effect(vnpy_trade.exchange,
                                           vnpy_trade.offset)
    order = Order.__from_create__(order_book_id, quantity, side, style,
                                  position_effect)
    order._filled_quantity = vnpy_trade.volume
    order._status = ORDER_STATUS.FILLED
    order._avg_price = vnpy_trade.price
    order._transaction_cost = 0
    return order
コード例 #7
0
def make_order(vnpy_order):
    order_book_id = make_order_book_id(vnpy_order.symbol)
    quantity = vnpy_order.totalVolume
    side = SIDE_REVERSE[vnpy_order.direction]
    style = LimitOrder(vnpy_order.price)
    position_effect = make_position_effect(vnpy_order.exchange,
                                           vnpy_order.offset)
    order_id = vnpy_order.orderID

    order = Order.__from_create__(order_book_id, quantity, side, style,
                                  position_effect)
    order._filled_quantity = vnpy_order.totalVolume
    order._order_id = order_id

    return order
コード例 #8
0
    def make_order_from_vnpy_trade(cls, vnpy_trade):
        calendar_dt = parse(vnpy_trade.tradeTime)
        trading_dt = cls.make_trading_dt(calendar_dt)
        order_book_id = cls.make_order_book_id(vnpy_trade.symbol)
        quantity = vnpy_trade.volume
        side = cls.SIDE_REVERSE[vnpy_trade.direction]
        style = LimitOrder(vnpy_trade.price)
        position_effect = cls.make_position_effect(vnpy_trade.exchange, vnpy_trade.offset)

        order = Order.__from_create__(calendar_dt, trading_dt, order_book_id, quantity, side, style, position_effect)
        order._filled_quantity = vnpy_trade.volume
        order._status = ORDER_STATUS.FILLED
        order._avg_price = vnpy_trade.price
        # FIXME: 用近似值代替
        order._transaction_cost = 0
        return order
コード例 #9
0
def _order_shares(order_book_id, amount, style, auto_switch_order_value):
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return

    if amount > 0:
        side = SIDE.BUY
        position_effect = POSITION_EFFECT.OPEN
    else:
        amount = abs(amount)
        side = SIDE.SELL
        position_effect = POSITION_EFFECT.CLOSE

    if side == SIDE.BUY:
        # 卖出不再限制 round_lot, order_shares 不再依赖 portfolio
        round_lot = int(env.get_instrument(order_book_id).round_lot)
        try:
            amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
        except ValueError:
            amount = 0

    r_order = Order.__from_create__(order_book_id, amount, side, style, position_effect)

    if amount == 0:
        # 如果计算出来的下单量为0, 则不生成Order, 直接返回None
        # 因为很多策略会直接在handle_bar里面执行order_target_percent之类的函数,经常会出现下一个量为0的订单,如果这些订单都生成是没有意义的。
        user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
        return
    if r_order.type == ORDER_TYPE.MARKET:
        r_order.set_frozen_price(price)

    reject_validator_type = env.validate_order_submission(r_order)
    if not reject_validator_type:
        env.broker.submit_order(r_order)
        return r_order
    else:
        if auto_switch_order_value and reject_validator_type == FRONT_VALIDATOR_TYPE.CASH:
            remaining_cash = env.portfolio.accounts[DEFAULT_ACCOUNT_TYPE.STOCK.name].cash
            user_system_log.warn(_(
                "Insufficient cash, use all remaining cash({}) to create order").format(remaining_cash)
            )
            return _order_value(order_book_id, remaining_cash, style)
コード例 #10
0
ファイル: simulation_broker.py プロジェクト: kknet/rqalpha
 def set_state(self, state):
     value = jsonpickle.loads(state.decode('utf-8'))
     for v in value['open_orders']:
         o = Order()
         o.set_state(v)
         account = self._env.get_account(o.order_book_id)
         self._open_orders.append((account, o))
     for v in value['delayed_orders']:
         o = Order()
         o.set_state(v)
         account = self._env.get_account(o.order_book_id)
         self._delayed_orders.append((account, o))
コード例 #11
0
def _order_value(account, position, ins, cash_amount, style):
    env = Environment.get_instance()
    if cash_amount > 0:
        cash_amount = min(cash_amount, account.cash)
    if isinstance(style, LimitOrder):
        price = style.get_limit_price()
    else:
        price = env.data_proxy.get_last_price(ins.order_book_id)
        if not is_valid_price(price):
            user_system_log.warn(
                _(u"Order Creation Failed: [{order_book_id}] No market data").
                format(order_book_id=ins.order_book_id))
            return

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

    min_round_lot = int(ins.round_lot)
    if cash_amount > 0:
        if _is_ksh(ins):
            amount = _get_ksh_amount(amount)
            min_round_lot = 1
        else:
            amount = int(
                Decimal(amount) / Decimal(min_round_lot)) * min_round_lot
        while amount > 0:
            expected_transaction_cost = env.get_order_transaction_cost(
                Order.__from_create__(ins.order_book_id, amount, SIDE.BUY,
                                      LimitOrder(price), POSITION_EFFECT.OPEN))
            if amount * price + expected_transaction_cost <= cash_amount:
                break
            amount -= min_round_lot
        else:
            user_system_log.warn(
                _(u"Order Creation Failed: 0 order quantity, order_book_id={order_book_id}"
                  ).format(order_book_id=ins.order_book_id))
            return

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

    return _order_shares(ins,
                         amount,
                         style,
                         position.quantity,
                         auto_switch_order_value=False)
コード例 #12
0
def _order_value(order_book_id, cash_amount, style):
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return

    account = env.portfolio.accounts[DEFAULT_ACCOUNT_TYPE.STOCK.name]

    if cash_amount > 0:
        cash_amount = min(cash_amount, account.cash)

    price = price if isinstance(style, MarketOrder) else style.get_limit_price()
    amount = int(Decimal(cash_amount) / Decimal(price))

    if cash_amount > 0:
        round_lot = int(env.get_instrument(order_book_id).round_lot)

        # FIXME: logic duplicate with order_shares
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot

        while amount > 0:
            dummy_order = Order.__from_create__(order_book_id, amount, SIDE.BUY, LimitOrder(price),
                                                POSITION_EFFECT.OPEN)
            expected_transaction_cost = env.get_order_transaction_cost(dummy_order)
            if amount * price + expected_transaction_cost <= cash_amount:
                break
            amount -= round_lot
        else:
            user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
            return

    # if the cash_amount is larger than you current security’s position,
    # then it will sell all shares of this security.

    position = account.get_position(order_book_id, POSITION_DIRECTION.LONG)
    amount = downsize_amount(amount, position)

    return _order_shares(order_book_id, amount, style, auto_switch_order_value=False)
コード例 #13
0
def _submit_order(ins, amount, side, position_effect, style, quantity,
                  auto_switch_order_value):
    env = Environment.get_instance()
    if isinstance(style, LimitOrder):
        if style.get_limit_price() <= 0:
            raise RQInvalidArgument(_(u"Limit order price should be positive"))
    price = env.data_proxy.get_last_price(ins.order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").
            format(order_book_id=ins.order_book_id))
        return
    round_lot = int(ins.round_lot)

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

    if amount == 0:
        user_system_log.warn(
            _(u"Order Creation Failed: 0 order quantity, order_book_id={order_book_id}"
              ).format(order_book_id=ins.order_book_id))
        return
    order = Order.__from_create__(ins.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, ins = _get_account_position_ins(ins)
        if not is_cash_enough(env, order, account):
            user_system_log.warn(
                _("insufficient cash, use all remaining cash({}) to create order"
                  ).format(account.cash))
            return _order_value(account, position, ins, account.cash, style)
    if env.can_submit_order(order):
        env.broker.submit_order(order)
        return order
コード例 #14
0
ファイル: api_base.py プロジェクト: susan9023/rqalpha
def exercise(id_or_ins, amount, right_type=RIGHT_TYPE.SELL_BACK):
    # type: (Union[str, Instrument], Union[int, float], Optional[RIGHT_TYPE]) -> Optional[Order]
    """
    行权。针对期权、可转债等含权合约,行使合约权利方被赋予的权利。

    :param id_or_ins: 行权合约,order_book_id 或 Instrument 对象
    :param amount: 参与行权的合约数量
    :param right_type: 权利类型,对于含有多种权利的合约(如可转债),选择行使何种权利

    :example:

    .. code-block:: python

        # 行使一张豆粕1905购2350的权力
        exercise("M1905C2350", 1)

    """

    amount = int(amount)
    if amount <= 0:
        user_system_log.warn(
            _(u"Order Creation Failed: Order amount should be positive."))
        return None
    if right_type != RIGHT_TYPE.SELL_BACK:
        raise NotImplementedError(_("exercise only supports sell back now"))
    env = Environment.get_instance()
    if isinstance(id_or_ins, Instrument):
        order_book_id = id_or_ins.order_book_id
    else:
        order_book_id = env.data_proxy.instruments(id_or_ins).order_book_id
    order = Order.__from_create__(order_book_id,
                                  amount,
                                  SIDE.SELL,
                                  None,
                                  POSITION_EFFECT.EXERCISE,
                                  right_type=right_type)
    if env.can_submit_order(order):
        env.broker.submit_order(order)
        return order
コード例 #15
0
ファイル: api_stock.py プロジェクト: ricequant/rqalpha
def order_value(id_or_ins, cash_amount, price=None, style=None):
    """
    使用想要花费的金钱买入/卖出股票,而不是买入/卖出想要的股数,正数代表买入,负数代表卖出。股票的股数总是会被调整成对应的100的倍数(在A中国A股市场1手是100股)。如果资金不足,该API将不会创建发送订单。

    需要注意:
    当您提交一个买单时,cash_amount 代表的含义是您希望买入股票消耗的金额(包含税费),最终买入的股数不仅和发单的价格有关,还和税费相关的参数设置有关。
    当您提交一个卖单时,cash_amount 代表的意义是您希望卖出股票的总价值。如果金额超出了您所持有股票的价值,那么您将卖出所有股票。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param float cash_amount: 需要花费现金购买/卖出证券的数目。正数代表买入,负数代表卖出。

    :param float price: 下单价格,默认为None,表示 :class:`~MarketOrder`, 此参数主要用于简化 `style` 参数。

    :param style: 下单类型, 默认是市价单。目前支持的订单类型有 :class:`~LimitOrder` 和 :class:`~MarketOrder`
    :type style: `OrderStyle` object

    :return: :class:`~Order` object | None

    :example:

    .. code-block:: python

        #花费最多¥10000买入平安银行股票,并以市价单发送。具体下单的数量与您策略税费相关的配置有关。
        order_value('000001.XSHE', 10000)
        #卖出价值¥10000的现在持有的平安银行:
        order_value('000001.XSHE', -10000)

    """

    style = cal_style(price, style)

    if isinstance(style, LimitOrder):
        if style.get_limit_price() <= 0:
            raise RQInvalidArgument(_(u"Limit order price should be positive"))

    order_book_id = assure_stock_order_book_id(id_or_ins)
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return

    account = env.portfolio.accounts[DEFAULT_ACCOUNT_TYPE.STOCK.name]

    if cash_amount > 0:
        cash_amount = min(cash_amount, account.cash)

    price = price if isinstance(style, MarketOrder) else style.get_limit_price()
    amount = int(Decimal(cash_amount) / Decimal(price))

    if cash_amount > 0:
        round_lot = int(env.get_instrument(order_book_id).round_lot)

        # FIXME: logic duplicate with order_shares
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot

        while amount > 0:
            dummy_order = Order.__from_create__(order_book_id, amount, SIDE.BUY, style, POSITION_EFFECT.OPEN)
            expected_transaction_cost = env.get_order_transaction_cost(DEFAULT_ACCOUNT_TYPE.STOCK, dummy_order)
            if amount * price + expected_transaction_cost <= cash_amount:
                break
            amount -= round_lot
        else:
            user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
            return

    # if the cash_amount is larger than you current security’s position,
    # then it will sell all shares of this security.

    position = account.positions[order_book_id]
    amount = downsize_amount(amount, position)

    return order_shares(order_book_id, amount, style=style)
コード例 #16
0
def order(id_or_ins, amount, side, position_effect, style):
    if not isinstance(style, OrderStyle):
        raise RuntimeError
    if amount < 0:
        raise RuntimeError
    if amount == 0:
        user_system_log.warn(_(u"Order Creation Failed: Order amount is 0."))
        return None
    if isinstance(style, LimitOrder) and style.get_limit_price() <= 0:
        raise RQInvalidArgument(_(u"Limit order price should be positive"))

    order_book_id = assure_future_order_book_id(id_or_ins)
    env = Environment.get_instance()
    if env.config.base.run_type != RUN_TYPE.BACKTEST:
        if "88" in order_book_id:
            raise RQInvalidArgument(
                _(u"Main Future contracts[88] are not supported in paper trading."
                  ))
        if "99" in order_book_id:
            raise RQInvalidArgument(
                _(u"Index Future contracts[99] are not supported in paper trading."
                  ))

    price = env.get_last_price(order_book_id)
    if np.isnan(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").
            format(order_book_id=order_book_id))
        return

    amount = int(amount)

    position = Environment.get_instance().portfolio.positions[order_book_id]

    orders = []
    if position_effect == POSITION_EFFECT.CLOSE:
        if side == SIDE.BUY:
            # 如果平仓量大于持仓量,则 Warning 并 取消订单创建
            if amount > position.sell_quantity:
                user_system_log.warn(
                    _(u"Order Creation Failed: close amount {amount} is larger than position "
                      u"quantity {quantity}").format(
                          amount=amount, quantity=position.sell_quantity))
                return []
            sell_old_quantity = position.sell_old_quantity
            if amount > sell_old_quantity:
                if sell_old_quantity != 0:
                    # 如果有昨仓,则创建一个 POSITION_EFFECT.CLOSE 的平仓单
                    orders.append(
                        Order.__from_create__(order_book_id, sell_old_quantity,
                                              side, style,
                                              POSITION_EFFECT.CLOSE))
                # 剩下还有仓位,则创建一个 POSITION_EFFECT.CLOSE_TODAY 的平今单
                orders.append(
                    Order.__from_create__(order_book_id,
                                          amount - sell_old_quantity, side,
                                          style, POSITION_EFFECT.CLOSE_TODAY))
            else:
                # 创建 POSITION_EFFECT.CLOSE 的平仓单
                orders.append(
                    Order.__from_create__(order_book_id, amount, side, style,
                                          POSITION_EFFECT.CLOSE))
        else:
            if amount > position.buy_quantity:
                user_system_log.warn(
                    _(u"Order Creation Failed: close amount {amount} is larger than position "
                      u"quantity {quantity}").format(
                          amount=amount, quantity=position.sell_quantity))
                return []
            buy_old_quantity = position.buy_old_quantity
            if amount > buy_old_quantity:
                if buy_old_quantity != 0:
                    orders.append(
                        Order.__from_create__(order_book_id, buy_old_quantity,
                                              side, style,
                                              POSITION_EFFECT.CLOSE))
                orders.append(
                    Order.__from_create__(order_book_id,
                                          amount - buy_old_quantity, side,
                                          style, POSITION_EFFECT.CLOSE_TODAY))
            else:
                orders.append(
                    Order.__from_create__(order_book_id, amount, side, style,
                                          POSITION_EFFECT.CLOSE))
    else:
        orders.append(
            Order.__from_create__(order_book_id, amount, side, style,
                                  position_effect))

    if np.isnan(price) or price == 0:
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").
            format(order_book_id=order_book_id))
        for o in orders:
            o.mark_rejected(
                _(u"Order Creation Failed: [{order_book_id}] No market data").
                format(order_book_id=order_book_id))
        return orders

    for o in orders:
        if o.type == ORDER_TYPE.MARKET:
            o.set_frozen_price(price)
        if env.can_submit_order(o):
            env.broker.submit_order(o)

    # 向前兼容,如果创建的order_list 只包含一个订单的话,直接返回对应的订单,否则返回列表
    if len(orders) == 1:
        return orders[0]
    else:
        return orders
コード例 #17
0
ファイル: api_base.py プロジェクト: ricequant/rqalpha
def submit_order(id_or_ins, amount, side, price=None, position_effect=None):
    """
    通用下单函数,策略可以通过该函数自由选择参数下单。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param float amount: 下单量,需为正数

    :param side: 多空方向,多(SIDE.BUY)或空(SIDE.SELL)
    :type side: :class:`~SIDE` enum

    :param float price: 下单价格,默认为None,表示市价单

    :param position_effect: 开平方向,开仓(POSITION_EFFECT.OPEN),平仓(POSITION.CLOSE)或平今(POSITION_EFFECT.CLOSE_TODAY),交易股票不需要该参数
    :type position_effect: :class:`~POSITION_EFFECT` enum

    :return: :class:`~Order` object | None

    :example:

    .. code-block:: python

        # 购买 2000 股的平安银行股票,并以市价单发送:
        submit_order('000001.XSHE', 2000, SIDE.BUY)
        # 平 10 份 RB1812 多方向的今仓,并以 4000 的价格发送限价单
        submit_order('RB1812', 10, SIDE.SELL, price=4000, position_effect=POSITION_EFFECT.CLOSE_TODAY)

    """
    order_book_id = assure_order_book_id(id_or_ins)
    env = Environment.get_instance()
    if (
        env.config.base.run_type != RUN_TYPE.BACKTEST
        and env.get_instrument(order_book_id).type == "Future"
    ):
        if "88" in order_book_id:
            raise RQInvalidArgument(
                _(u"Main Future contracts[88] are not supported in paper trading.")
            )
        if "99" in order_book_id:
            raise RQInvalidArgument(
                _(u"Index Future contracts[99] are not supported in paper trading.")
            )
    style = cal_style(price, None)
    market_price = env.get_last_price(order_book_id)
    if not is_valid_price(market_price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(
                order_book_id=order_book_id
            )
        )
        return

    amount = int(amount)

    order = Order.__from_create__(
        order_book_id=order_book_id,
        quantity=amount,
        side=side,
        style=style,
        position_effect=position_effect,
    )

    if order.type == ORDER_TYPE.MARKET:
        order.set_frozen_price(market_price)
    if env.can_submit_order(order):
        env.broker.submit_order(order)
        return order
コード例 #18
0
ファイル: api_future.py プロジェクト: SeavantUUz/rqalpha
def order(id_or_ins, amount, side, position_effect, style):
    if not isinstance(style, OrderStyle):
        raise RuntimeError
    if amount < 0:
        raise RuntimeError
    if amount == 0:
        user_system_log.warn(_(u"Order Creation Failed: Order amount is 0."))
        return None
    if isinstance(style, LimitOrder) and style.get_limit_price() <= 0:
        raise RQInvalidArgument(_(u"Limit order price should be positive"))

    order_book_id = assure_future_order_book_id(id_or_ins)
    env = Environment.get_instance()
    if env.config.base.run_type != RUN_TYPE.BACKTEST:
        if "88" in order_book_id:
            raise RQInvalidArgument(_(u"Main Future contracts[88] are not supported in paper trading."))
        if "99" in order_book_id:
            raise RQInvalidArgument(_(u"Index Future contracts[99] are not supported in paper trading."))

    price = env.get_last_price(order_book_id)
    if np.isnan(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id)
        )
        return

    amount = int(amount)

    position = Environment.get_instance().portfolio.positions[order_book_id]

    orders = []
    if position_effect == POSITION_EFFECT.CLOSE:
        if side == SIDE.BUY:
            # 如果平仓量大于持仓量,则 Warning 并 取消订单创建
            if amount > position.sell_quantity:
                user_system_log.warn(
                    _(u"Order Creation Failed: close amount {amount} is larger than position "
                      u"quantity {quantity}").format(amount=amount, quantity=position.sell_quantity)
                )
                return []
            sell_old_quantity = position.sell_old_quantity
            if amount > sell_old_quantity:
                if sell_old_quantity != 0:
                    # 如果有昨仓,则创建一个 POSITION_EFFECT.CLOSE 的平仓单
                    orders.append(Order.__from_create__(
                        order_book_id,
                        sell_old_quantity,
                        side,
                        style,
                        POSITION_EFFECT.CLOSE
                    ))
                # 剩下还有仓位,则创建一个 POSITION_EFFECT.CLOSE_TODAY 的平今单
                orders.append(Order.__from_create__(
                    order_book_id,
                    amount - sell_old_quantity,
                    side,
                    style,
                    POSITION_EFFECT.CLOSE_TODAY
                ))
            else:
                # 创建 POSITION_EFFECT.CLOSE 的平仓单
                orders.append(Order.__from_create__(
                    order_book_id,
                    amount,
                    side,
                    style,
                    POSITION_EFFECT.CLOSE
                ))
        else:
            if amount > position.buy_quantity:
                user_system_log.warn(
                    _(u"Order Creation Failed: close amount {amount} is larger than position "
                      u"quantity {quantity}").format(amount=amount, quantity=position.sell_quantity)
                )
                return []
            buy_old_quantity = position.buy_old_quantity
            if amount > buy_old_quantity:
                if buy_old_quantity != 0:
                    orders.append(Order.__from_create__(
                        order_book_id,
                        buy_old_quantity,
                        side,
                        style,
                        POSITION_EFFECT.CLOSE
                    ))
                orders.append(Order.__from_create__(
                    order_book_id,
                    amount - buy_old_quantity,
                    side,
                    style,
                    POSITION_EFFECT.CLOSE_TODAY
                ))
            else:
                orders.append(Order.__from_create__(
                    order_book_id,
                    amount,
                    side,
                    style,
                    POSITION_EFFECT.CLOSE
                ))
    else:
        orders.append(Order.__from_create__(
            order_book_id,
            amount,
            side,
            style,
            position_effect
        ))

    if np.isnan(price) or price == 0:
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        for o in orders:
            o.mark_rejected(
                _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return orders

    for o in orders:
        if o.type == ORDER_TYPE.MARKET:
            o.set_frozen_price(price)
        if env.can_submit_order(o):
            env.broker.submit_order(o)

    # 向前兼容,如果创建的order_list 只包含一个订单的话,直接返回对应的订单,否则返回列表
    if len(orders) == 1:
        return orders[0]
    else:
        return orders
コード例 #19
0
ファイル: api_future.py プロジェクト: ziyangye-sys/rqalpha
def _submit_order(id_or_ins, amount, side, position_effect, style):
    amount = int(amount)
    if amount == 0:
        user_system_log.warn(_(u"Order Creation Failed: Order amount is 0."))
        return None
    if isinstance(style, LimitOrder) and style.get_limit_price() <= 0:
        raise RQInvalidArgument(_(u"Limit order price should be positive"))

    instrument = assure_instrument(id_or_ins)
    order_book_id = instrument.order_book_id
    env = Environment.get_instance()
    if env.config.base.run_type != RUN_TYPE.BACKTEST and instrument.type == INSTRUMENT_TYPE.FUTURE:
        if "88" in order_book_id:
            raise RQInvalidArgument(
                _(u"Main Future contracts[88] are not supported in paper trading."
                  ))
        if "99" in order_book_id:
            raise RQInvalidArgument(
                _(u"Index Future contracts[99] are not supported in paper trading."
                  ))

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").
            format(order_book_id=order_book_id))
        return

    env = Environment.get_instance()

    orders = []
    if position_effect in (POSITION_EFFECT.CLOSE_TODAY, POSITION_EFFECT.CLOSE):
        direction = POSITION_DIRECTION.LONG if side == SIDE.SELL else POSITION_DIRECTION.SHORT
        position = env.portfolio.get_position(order_book_id,
                                              direction)  # type: Position
        if position_effect == POSITION_EFFECT.CLOSE_TODAY:
            if amount > position.today_closable:
                user_system_log.warning(
                    _("Order Creation Failed: "
                      "close today amount {amount} is larger than today closable quantity {quantity}"
                      ).format(amount=amount,
                               quantity=position.today_closable))
                return []
            orders.append(
                Order.__from_create__(order_book_id, amount, side, style,
                                      POSITION_EFFECT.CLOSE_TODAY))
        else:
            quantity, old_quantity = position.quantity, position.old_quantity
            if amount > quantity:
                user_system_log.warn(
                    _(u"Order Creation Failed: close amount {amount} is larger than position quantity {quantity}"
                      ).format(amount=amount, quantity=quantity))
                return []
            if amount > old_quantity:
                if old_quantity != 0:
                    # 如果有昨仓,则创建一个 POSITION_EFFECT.CLOSE 的平仓单
                    orders.append(
                        Order.__from_create__(order_book_id, old_quantity,
                                              side, style,
                                              POSITION_EFFECT.CLOSE))
                # 剩下还有仓位,则创建一个 POSITION_EFFECT.CLOSE_TODAY 的平今单
                orders.append(
                    Order.__from_create__(order_book_id, amount - old_quantity,
                                          side, style,
                                          POSITION_EFFECT.CLOSE_TODAY))
            else:
                # 创建 POSITION_EFFECT.CLOSE 的平仓单
                orders.append(
                    Order.__from_create__(order_book_id, amount, side, style,
                                          POSITION_EFFECT.CLOSE))
    elif position_effect == POSITION_EFFECT.OPEN:
        orders.append(
            Order.__from_create__(order_book_id, amount, side, style,
                                  position_effect))
    else:
        raise NotImplementedError()

    if len(orders) > 1:
        user_system_log.warn(
            _("Order was separated, original order: {original_order_repr}, new orders: [{new_orders_repr}]"
              ).
            format(
                original_order_repr=
                "Order(order_book_id={}, quantity={}, side={}, position_effect={})"
                .format(order_book_id, amount, side, position_effect),
                new_orders_repr=", ".join([
                    "Order({}, {}, {}, {})".format(o.order_book_id, o.quantity,
                                                   o.side, o.position_effect)
                    for o in orders
                ])))

    for o in orders:
        if o.type == ORDER_TYPE.MARKET:
            o.set_frozen_price(price)
        if env.can_submit_order(o):
            env.broker.submit_order(o)
        else:
            orders.remove(o)

    # 向前兼容,如果创建的order_list 只包含一个订单的话,直接返回对应的订单,否则返回列表
    if len(orders) == 1:
        return orders[0]
    else:
        return orders
コード例 #20
0
ファイル: api_stock.py プロジェクト: 8dspaces/rqalpha
def order_shares(id_or_ins, amount, price=None, style=None):
    """
    落指定股数的买/卖单,最常见的落单方式之一。如有需要落单类型当做一个参量传入,如果忽略掉落单类型,那么默认是市价单(market order)。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param int amount: 下单量, 正数代表买入,负数代表卖出。将会根据一手xx股来向下调整到一手的倍数,比如中国A股就是调整成100股的倍数。

    :param float price: 下单价格,默认为None,表示 :class:`~MarketOrder`, 此参数主要用于简化 `style` 参数。

    :param style: 下单类型, 默认是市价单。目前支持的订单类型有 :class:`~LimitOrder` 和 :class:`~MarketOrder`
    :type style: `OrderStyle` object

    :return: :class:`~Order` object

    :example:

    .. code-block:: python

        #购买Buy 2000 股的平安银行股票,并以市价单发送:
        order_shares('000001.XSHE', 2000)
        #卖出2000股的平安银行股票,并以市价单发送:
        order_shares('000001.XSHE', -2000)
        #购买1000股的平安银行股票,并以限价单发送,价格为¥10:
        order_shares('000001.XSHG', 1000, style=LimitOrder(10))
    """
    if amount == 0:
        # 如果下单量为0,则认为其并没有发单,则直接返回None
        return None
    style = cal_style(price, style)
    if isinstance(style, LimitOrder):
        if style.get_limit_price() <= 0:
            raise RQInvalidArgument(_(u"Limit order price should be positive"))
    order_book_id = assure_stock_order_book_id(id_or_ins)
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return

    if amount > 0:
        side = SIDE.BUY
    else:
        amount = abs(amount)
        side = SIDE.SELL

    round_lot = int(env.get_instrument(order_book_id).round_lot)

    try:
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
    except ValueError:
        amount = 0

    r_order = Order.__from_create__(order_book_id, amount, side, style, None)

    if price == 0:
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        r_order.mark_rejected(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return r_order

    if amount == 0:
        # 如果计算出来的下单量为0, 则不生成Order, 直接返回None
        # 因为很多策略会直接在handle_bar里面执行order_target_percent之类的函数,经常会出现下一个量为0的订单,如果这些订单都生成是没有意义的。
        r_order.mark_rejected(_(u"Order Creation Failed: 0 order quantity"))
        return r_order
    if r_order.type == ORDER_TYPE.MARKET:
        r_order.set_frozen_price(price)
    if env.can_submit_order(r_order):
        env.broker.submit_order(r_order)

    return r_order
コード例 #21
0
ファイル: api_booking.py プロジェクト: gaoyunhua/rqalpha
def send_order(order_book_id, amount, side, position_effect, style):
    env = Environment.get_instance()

    order = Order.__from_create__(order_book_id, amount, side, style, position_effect)
    env.broker.submit_order(order)
    return order
コード例 #22
0
ファイル: api_stock.py プロジェクト: CallingWisdom/rqalpha
def order_shares(id_or_ins, amount, price=None, style=None):
    """
    落指定股数的买/卖单,最常见的落单方式之一。如有需要落单类型当做一个参量传入,如果忽略掉落单类型,那么默认是市价单(market order)。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param int amount: 下单量, 正数代表买入,负数代表卖出。将会根据一手xx股来向下调整到一手的倍数,比如中国A股就是调整成100股的倍数。

    :param float price: 下单价格,默认为None,表示 :class:`~MarketOrder`, 此参数主要用于简化 `style` 参数。

    :param style: 下单类型, 默认是市价单。目前支持的订单类型有 :class:`~LimitOrder` 和 :class:`~MarketOrder`
    :type style: `OrderStyle` object

    :return: :class:`~Order` object

    :example:

    .. code-block:: python

        #购买Buy 2000 股的平安银行股票,并以市价单发送:
        order_shares('000001.XSHE', 2000)
        #卖出2000股的平安银行股票,并以市价单发送:
        order_shares('000001.XSHE', -2000)
        #购买1000股的平安银行股票,并以限价单发送,价格为¥10:
        order_shares('000001.XSHG', 1000, style=LimitOrder(10))
    """

    orig_amount = amount

    if amount == 0:
        # 如果下单量为0,则认为其并没有发单,则直接返回None
        return None
    style = cal_style(price, style)
    if isinstance(style, LimitOrder):
        if style.get_limit_price() <= 0:
            raise RQInvalidArgument(_(u"Limit order price should be positive"))
    order_book_id = assure_stock_order_book_id(id_or_ins)
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(
            price
    ):  # fixme if the security was not traded yesterday,it won't be traded ? --- this requires env.get_last_price() would not skip suspended price
        print('dt,last', env.price_board._bar_dict.dt,
              env.price_board._bar_dict[order_book_id])
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] last price {price}").
            format(order_book_id=order_book_id, price=price))
        return

    if amount > 0:
        side = SIDE.BUY
    else:
        amount = abs(amount)
        side = SIDE.SELL

    round_lot = int(env.get_instrument(order_book_id).round_lot)

    try:
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
    except ValueError:
        amount = 0

    r_order = Order.__from_create__(order_book_id, amount, side, style, None)

    if price == 0:
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] last price is 0").
            format(order_book_id=order_book_id))
        r_order.mark_rejected(
            _(u"Order Creation Failed: [{order_book_id}] last price is 0").
            format(order_book_id=order_book_id))
        return r_order

    if amount == 0:
        # 如果计算出来的下单量为0, 则不生成Order, 直接返回None
        # 因为很多策略会直接在handle_bar里面执行order_target_percent之类的函数,经常会出现下一个量为0的订单,如果这些订单都生成是没有意义的。
        r_order.mark_rejected(
            _(u"Order Creation Failed: [{order_book_id}] {orig_amount} order quantity. round_lot {round_lot}"
              ).format(order_book_id=order_book_id,
                       orig_amount=round(orig_amount, 5),
                       round_lot=round_lot))
        return r_order
    if r_order.type == ORDER_TYPE.MARKET:
        r_order.set_frozen_price(price)
    if env.can_submit_order(r_order):
        env.broker.submit_order(r_order)

    return r_order
コード例 #23
0
ファイル: api_stock.py プロジェクト: hudaoyou/rqalpha
def order_value(id_or_ins, cash_amount, price=None, style=None):
    """
    使用想要花费的金钱买入/卖出股票,而不是买入/卖出想要的股数,正数代表买入,负数代表卖出。股票的股数总是会被调整成对应的100的倍数(在A中国A股市场1手是100股)。如果资金不足,该API将不会创建发送订单。

    需要注意:
    当您提交一个买单时,cash_amount 代表的含义是您希望买入股票消耗的金额(包含税费),最终买入的股数不仅和发单的价格有关,还和税费相关的参数设置有关。
    当您提交一个卖单时,cash_amount 代表的意义是您希望卖出股票的总价值。如果金额超出了您所持有股票的价值,那么您将卖出所有股票。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param float cash_amount: 需要花费现金购买/卖出证券的数目。正数代表买入,负数代表卖出。

    :param float price: 下单价格,默认为None,表示 :class:`~MarketOrder`, 此参数主要用于简化 `style` 参数。

    :param style: 下单类型, 默认是市价单。目前支持的订单类型有 :class:`~LimitOrder` 和 :class:`~MarketOrder`
    :type style: `OrderStyle` object

    :return: :class:`~Order` object | None

    :example:

    .. code-block:: python

        #花费最多¥10000买入平安银行股票,并以市价单发送。具体下单的数量与您策略税费相关的配置有关。
        order_value('000001.XSHE', 10000)
        #卖出价值¥10000的现在持有的平安银行:
        order_value('000001.XSHE', -10000)

    """

    style = cal_style(price, style)

    if isinstance(style, LimitOrder):
        if style.get_limit_price() <= 0:
            raise RQInvalidArgument(_(u"Limit order price should be positive"))

    order_book_id = assure_stock_order_book_id(id_or_ins)
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id))
        return

    account = env.portfolio.accounts[DEFAULT_ACCOUNT_TYPE.STOCK.name]

    if cash_amount > 0:
        cash_amount = min(cash_amount, account.cash)

    price = price if isinstance(style, MarketOrder) else style.get_limit_price()
    amount = int(Decimal(cash_amount) / Decimal(price))

    if cash_amount > 0:
        round_lot = int(env.get_instrument(order_book_id).round_lot)

        # FIXME: logic duplicate with order_shares
        amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot

        while amount > 0:
            dummy_order = Order.__from_create__(order_book_id, amount, SIDE.BUY, LimitOrder(price), POSITION_EFFECT.OPEN)
            expected_transaction_cost = env.get_order_transaction_cost(DEFAULT_ACCOUNT_TYPE.STOCK, dummy_order)
            if amount * price + expected_transaction_cost <= cash_amount:
                break
            amount -= round_lot
        else:
            user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
            return

    # if the cash_amount is larger than you current security’s position,
    # then it will sell all shares of this security.

    position = account.positions[order_book_id]
    amount = downsize_amount(amount, position)

    return order_shares(order_book_id, amount, style=style)
コード例 #24
0
def order_target_portfolio(target_portfolio):
    # type: (Dict[Union[str, Instrument]: float]) -> List[Order]
    """
    买入/卖出证券以批量调整证券的仓位,以期使其持仓市值占账户总权益的比重达到指定值。

    :param target_portfolio: 下单标的物及其目标市值占比的字典

    :example:

    .. code-block:: python

        # 调整仓位,以使平安银行和万科 A 的持仓占比分别达到 10% 和 15%
        order_target_portfolio({
            '000001.XSHE': 0.1
            '000002.XSHE': 0.15
        })
    """

    if isinstance(target_portfolio, pd.Series):
        # FIXME: kind of dirty
        total_percent = sum(target_portfolio)
    else:
        total_percent = sum(six.itervalues(target_portfolio))
    if total_percent > 1:
        raise RQInvalidArgument(_(u"total percent should be lower than 1, current: {}").format(total_percent))

    env = Environment.get_instance()
    account = env.portfolio.accounts[DEFAULT_ACCOUNT_TYPE.STOCK]
    account_value = account.total_value
    target_quantities = {}
    for id_or_ins, target_percent in six.iteritems(target_portfolio):
        order_book_id = assure_stock_order_book_id(id_or_ins)
        if target_percent < 0:
            raise RQInvalidArgument(_(u"target percent of {} should between 0 and 1, current: {}").format(
                order_book_id, target_percent
            ))
        price = env.data_proxy.get_last_price(order_book_id)
        if not is_valid_price(price):
            user_system_log.warn(
                _(u"Order Creation Failed: [{order_book_id}] No market data").format(order_book_id=order_book_id)
            )
            continue
        target_quantities[order_book_id] = account_value * target_percent / price

    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 six.iteritems(current_quantities):
        if order_book_id not in target_portfolio:
            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 six.iteritems(target_quantities):
        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
            ))

    submit_orders = []
    for order in chain(close_orders, open_orders):
        if env.can_submit_order(order):
            submit_orders.append(order)
            env.broker.submit_order(order)
    return submit_orders
コード例 #25
0
 def _account_order_from_state(order_state):
     o = Order()
     o.set_state(order_state)
     account = self._env.get_account(o.order_book_id)
     return account, o
コード例 #26
0
ファイル: api_base.py プロジェクト: zwcdp/rqalpha
def submit_order(id_or_ins, amount, side, price=None, position_effect=None):
    """
    通用下单函数,策略可以通过该函数自由选择参数下单。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param float amount: 下单量,需为正数

    :param side: 多空方向,多(SIDE.BUY)或空(SIDE.SELL)
    :type side: :class:`~SIDE` enum

    :param float price: 下单价格,默认为None,表示市价单

    :param position_effect: 开平方向,开仓(POSITION_EFFECT.OPEN),平仓(POSITION.CLOSE)或平今(POSITION_EFFECT.CLOSE_TODAY),交易股票不需要该参数
    :type position_effect: :class:`~POSITION_EFFECT` enum

    :return: :class:`~Order` object | None

    :example:

    .. code-block:: python

        # 购买 2000 股的平安银行股票,并以市价单发送:
        submit_order('000001.XSHE', 2000, SIDE.BUY)
        # 平 10 份 RB1812 多方向的今仓,并以 4000 的价格发送限价单
        submit_order('RB1812', 10, SIDE.SELL, price=4000, position_effect=POSITION_EFFECT.CLOSE_TODAY)

    """
    order_book_id = assure_order_book_id(id_or_ins)
    env = Environment.get_instance()
    if (env.config.base.run_type != RUN_TYPE.BACKTEST
            and env.get_instrument(order_book_id).type == "Future"):
        if "88" in order_book_id:
            raise RQInvalidArgument(
                _(u"Main Future contracts[88] are not supported in paper trading."
                  ))
        if "99" in order_book_id:
            raise RQInvalidArgument(
                _(u"Index Future contracts[99] are not supported in paper trading."
                  ))
    style = cal_style(price, None)
    market_price = env.get_last_price(order_book_id)
    if not is_valid_price(market_price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").
            format(order_book_id=order_book_id))
        return

    amount = int(amount)

    order = Order.__from_create__(
        order_book_id=order_book_id,
        quantity=amount,
        side=side,
        style=style,
        position_effect=position_effect,
    )

    if order.type == ORDER_TYPE.MARKET:
        order.set_frozen_price(market_price)
    if env.can_submit_order(order):
        env.broker.submit_order(order)
        return order
コード例 #27
0
def order_shares(id_or_ins, amount, price=None, style=None):
    """
    落指定股数的买/卖单,最常见的落单方式之一。如有需要落单类型当做一个参量传入,如果忽略掉落单类型,那么默认是市价单(market order)。

    :param id_or_ins: 下单标的物
    :type id_or_ins: :class:`~Instrument` object | `str`

    :param int amount: 下单量, 正数代表买入,负数代表卖出。将会根据一手xx股来向下调整到一手的倍数,比如中国A股就是调整成100股的倍数。

    :param float price: 下单价格,默认为None,表示 :class:`~MarketOrder`, 此参数主要用于简化 `style` 参数。

    :param style: 下单类型, 默认是市价单。目前支持的订单类型有 :class:`~LimitOrder` 和 :class:`~MarketOrder`
    :type style: `OrderStyle` object

    :return: :class:`~Order` object

    :example:

    .. code-block:: python

        #购买Buy 2000 股的平安银行股票,并以市价单发送:
        order_shares('000001.XSHE', 2000)
        #卖出2000股的平安银行股票,并以市价单发送:
        order_shares('000001.XSHE', -2000)
        #购买1000股的平安银行股票,并以限价单发送,价格为¥10:
        order_shares('000001.XSHG', 1000, style=LimitOrder(10))
    """
    if amount == 0:
        # 如果下单量为0,则认为其并没有发单,则直接返回None
        user_system_log.warn(_(u"Order Creation Failed: Order amount is 0."))
        return None
    style = cal_style(price, style)
    if isinstance(style, LimitOrder):
        if style.get_limit_price() <= 0:
            raise RQInvalidArgument(_(u"Limit order price should be positive"))
    order_book_id = assure_stock_order_book_id(id_or_ins)
    env = Environment.get_instance()

    price = env.get_last_price(order_book_id)
    if not is_valid_price(price):
        user_system_log.warn(
            _(u"Order Creation Failed: [{order_book_id}] No market data").
            format(order_book_id=order_book_id))
        return

    if amount > 0:
        side = SIDE.BUY
        position_effect = POSITION_EFFECT.OPEN
    else:
        amount = abs(amount)
        side = SIDE.SELL
        position_effect = POSITION_EFFECT.CLOSE

    round_lot = int(env.get_instrument(order_book_id).round_lot)

    if side == SIDE.BUY or amount != env.portfolio.accounts[
            DEFAULT_ACCOUNT_TYPE.STOCK.name].positions[order_book_id].sellable:
        # 一次性申报卖出时可以卖散股
        try:
            amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
        except ValueError:
            amount = 0

    r_order = Order.__from_create__(order_book_id, amount, side, style,
                                    position_effect)

    if amount == 0:
        # 如果计算出来的下单量为0, 则不生成Order, 直接返回None
        # 因为很多策略会直接在handle_bar里面执行order_target_percent之类的函数,经常会出现下一个量为0的订单,如果这些订单都生成是没有意义的。
        user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
        return
    if r_order.type == ORDER_TYPE.MARKET:
        r_order.set_frozen_price(price)
    if env.can_submit_order(r_order):
        env.broker.submit_order(r_order)
        return r_order
コード例 #28
0
ファイル: api_stock.py プロジェクト: zfy1989lee/rqalpha
def _sell_all_stock(order_book_id, amount, style):
    env = Environment.get_instance()
    order = Order.__from_create__(order_book_id, amount, SIDE.SELL, style, None)
    if env.can_submit_order(order):
        env.broker.submit_order(order)
    return order