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)
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
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
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
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
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)
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
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
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
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)
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)
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)
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