Exemplo n.º 1
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)
    amount = int(Decimal(cash_amount) / Decimal(price))

    if cash_amount > 0:
        round_lot = int(ins.round_lot)
        amount = int(Decimal(amount) / Decimal(round_lot)) * 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 -= round_lot
        else:
            user_system_log.warn(_(u"Order Creation Failed: 0 order quantity"))
            return

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

    return _order_shares(ins, amount, style, auto_switch_order_value=False)
Exemplo n.º 2
0
    def update_data(self, data):
        self.order_id = int(data.OrderRef)
        self.trade_id = data.TradeID
        self.order_book_id = make_order_book_id(data.InstrumentID)

        self.side = SIDE_REVERSE.get(data.Direction, SIDE.BUY)

        self.exchange_id = data.ExchangeID

        if self.exchange_id == 'SHFE':
            if data.OffsetFlag == ApiStruct.OF_Open:
                self.position_effect = POSITION_EFFECT.OPEN
            elif data.OffsetFlag == ApiStruct.OF_CloseToday:
                self.position_effect = POSITION_EFFECT.CLOSE_TODAY
            else:
                self.position_effect = POSITION_EFFECT.CLOSE
        else:
            if data.OffsetFlag == ApiStruct.OF_Open:
                self.position_effect = POSITION_EFFECT.OPEN
            else:
                self.position_effect = POSITION_EFFECT.CLOSE

        self.quantity = data.Volume
        self.price = data.Price
        self.style = LimitOrder(self.price)

        self.is_valid = True
Exemplo n.º 3
0
    def update_data(self, data):
        self.order_id = int(data['OrderRef'])
        self.trade_id = data['TradeID']
        self.order_book_id = make_order_book_id(data['InstrumentID'])

        self.side = SIDE_REVERSE.get(data['Direction'], SIDE.BUY)

        self.exchange_id = data['ExchangeID']

        if self.exchange_id == 'SHFE':
            if data['OffsetFlag'] == defineDict['THOST_FTDC_OF_Open']:
                self.position_effect = POSITION_EFFECT.OPEN
            elif data['OffsetFlag'] == defineDict['THOST_FTDC_OF_CloseToday']:
                self.position_effect = POSITION_EFFECT.CLOSE_TODAY
            else:
                self.position_effect = POSITION_EFFECT.CLOSE
        else:
            if data['OffsetFlag'] == defineDict['THOST_FTDC_OF_Open']:
                self.position_effect = POSITION_EFFECT.OPEN
            else:
                self.position_effect = POSITION_EFFECT.CLOSE

        self.amount = data['Volume']
        self.price = data['Price']
        self.style = LimitOrder(self.price)

        self.is_valid = True
Exemplo n.º 4
0
    def update_data(self, data, rejected=False):
        if not data['InstrumentID']:
            return
        try:
            self.order_id = int(data['OrderRef'])
        except ValueError:
            self.order_id = np.nan

        self.order_book_id = make_order_book_id(data['InstrumentID'])

        if 'FrontID' in data:
            self.front_id = data['FrontID']
            self.session_id = data['SessionID']

        self.quantity = data['VolumeTotalOriginal']

        if 'VolumeTraded' in data:
            self.filled_quantity = data['VolumeTraded']
            self.unfilled_quantity = self.quantity - self.filled_quantity

        self.side = SIDE_REVERSE.get(data['Direction'], SIDE.BUY)
        self.price = data['LimitPrice']
        self.exchange_id = data['ExchangeID']

        if self.exchange_id == 'SHFE':
            if data['CombOffsetFlag'] == defineDict['THOST_FTDC_OF_Open']:
                self.position_effect = POSITION_EFFECT.OPEN
            elif data['CombOffsetFlag'] == defineDict[
                    'THOST_FTDC_OF_CloseToday']:
                self.position_effect = POSITION_EFFECT.CLOSE_TODAY
            else:
                self.position_effect = POSITION_EFFECT.CLOSE
        else:
            if data['CombOffsetFlag'] == defineDict['THOST_FTDC_OF_Open']:
                self.position_effect = POSITION_EFFECT.OPEN
            else:
                self.position_effect = POSITION_EFFECT.CLOSE

        if rejected:
            self.status = ORDER_STATUS.REJECTED
        else:
            if 'OrderStatus' in data:
                if data['OrderStatus'] in [
                        defineDict["THOST_FTDC_OST_PartTradedQueueing"],
                        defineDict["THOST_FTDC_OST_NoTradeQueueing"]
                ]:
                    self.status = ORDER_STATUS.ACTIVE
                elif data['OrderStatus'] == defineDict[
                        "THOST_FTDC_OST_AllTraded"]:
                    self.status = ORDER_STATUS.FILLED
                elif data['OrderStatus'] == defineDict[
                        "THOST_FTDC_OST_Canceled"]:
                    self.status = ORDER_STATUS.CANCELLED
                else:
                    return

        self.style = LimitOrder(self.price)

        self.is_valid = True
Exemplo n.º 5
0
    def make_order(cls, vnpy_order):
        calendar_dt = parse(vnpy_order.orderTime)
        trading_dt = cls.make_trading_dt(calendar_dt)
        order_book_id = cls.make_order_book_id(vnpy_order.symbol)
        quantity = vnpy_order.totalVolume
        side = cls.SIDE_REVERSE[vnpy_order.direction]
        style = LimitOrder(vnpy_order.price)
        position_effect = cls.make_position_effect(vnpy_order.exchange, vnpy_order.offset)

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

        return order
Exemplo n.º 6
0
def cal_style(price, style):
    if price is None and style is None:
        return MarketOrder()

    if style is not None:
        if not isinstance(style, OrderStyle):
            raise RuntimeError
        return style

    if isinstance(price, OrderStyle):
        # 为了 order_xxx('RB1710', 10, MarketOrder()) 这种写法
        return price

    return LimitOrder(price)
Exemplo n.º 7
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
Exemplo n.º 8
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
Exemplo n.º 9
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
Exemplo n.º 10
0
def cal_style(price, style):
    if price is None and style is None:
        return MarketOrder()

    if style is not None:
        if not isinstance(style, OrderStyle):
            raise RuntimeError
        return style

    if isinstance(price, OrderStyle):
        # 为了 order_xxx('RB1710', 10, MarketOrder()) 这种写法
        if isinstance(price, LimitOrder):
            if np.isnan(price.get_limit_price()):
                raise RQInvalidArgument(_(u"Limit order price should not be nan."))
        return price

    if np.isnan(price):
        raise RQInvalidArgument(_(u"Limit order price should not be nan."))

    return LimitOrder(price)
Exemplo n.º 11
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)
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
    def update_data(self, data, rejected=False):
        if not data.InstrumentID:
            return
        try:
            self.order_id = int(data.OrderRef)
        except ValueError:
            self.order_id = np.nan

        self.order_book_id = make_order_book_id(data.InstrumentID)

        try:
            self.front_id = data.FrontID
            self.session_id = data.SessionID
        except AttributeError:
            pass

        self.quantity = data.VolumeTotalOriginal

        try:
            self.filled_quantity = data.VolumeTraded
            self.unfilled_quantity = self.quantity - self.filled_quantity
        except AttributeError:
            pass

        self.side = SIDE_REVERSE.get(data.Direction, SIDE.BUY)
        self.price = data.LimitPrice
        try:
            self.exchange_id = data.ExchangeID
        except AttributeError:
            pass

        if self.exchange_id == 'SHFE':
            if data.CombOffsetFlag == ApiStruct.OF_Open:
                self.position_effect = POSITION_EFFECT.OPEN
            elif data.CombOffsetFlag == ApiStruct.OF_CloseToday:
                self.position_effect = POSITION_EFFECT.CLOSE_TODAY
            else:
                self.position_effect = POSITION_EFFECT.CLOSE
        else:
            if data.CombOffsetFlag == ApiStruct.OF_Open:
                self.position_effect = POSITION_EFFECT.OPEN
            else:
                self.position_effect = POSITION_EFFECT.CLOSE

        if rejected:
            self.status = ORDER_STATUS.REJECTED
        else:
            try:
                if data.OrderStatus in [ApiStruct.OST_PartTradedQueueing, ApiStruct.OST_NoTradeQueueing]:
                    self.status = ORDER_STATUS.ACTIVE
                elif data.OrderStatus == ApiStruct.OST_AllTraded:
                    self.status = ORDER_STATUS.FILLED
                elif data.OrderStatus == ApiStruct.OST_Canceled:
                    self.status = ORDER_STATUS.CANCELLED
                else:
                    return
            except AttributeError:
                pass

        self.style = LimitOrder(self.price)

        self.is_valid = True