def _on_post_bar(self, event): if self._open_orders: data = self._query_filled_orders() if data is not None: for item in data: trade_no = item[u'成交编号'] if trade_no in self._trade_no: continue entrust_no = item[u'合同编号'] order_id = self._order_id_map.get(entrust_no, None) if order_id: order = self._open_orders.get(order_id, None) if order: trade = Trade.__from_create__( order_id=order.order_id, price=float(item[u'成交均价']), amount=int(item[u'成交数量']), side=order.side, position_effect=order.position_effect, order_book_id=order.order_book_id, frozen_price=order.frozen_price, ) account = self._env.get_account(order.order_book_id) trade._commission = self._env.get_trade_commission(account_type_str2enum(account.type), trade) trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade) order.fill(trade) self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=order)) self._trade_no.add(trade_no) if order.is_final(): str_order_id = str(order.order_id) del self._open_orders[str_order_id] del self._order_id_map[entrust_no] del self._order_id_map[str_order_id]
def match(self, open_orders): price_board = self._env.price_board for account, order in open_orders: order_book_id = order.order_book_id instrument = self._env.get_instrument(order_book_id) deal_price = self._deal_price_decider(order_book_id, order.side) if not is_valid_price(deal_price): listed_date = instrument.listed_date.date() if listed_date == self._trading_dt.date(): reason = _( u"Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]" ).format( order_book_id=order.order_book_id, listed_date=listed_date, ) else: reason = _( u"Order Cancelled: current bar [{order_book_id}] miss market data." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if order.type == ORDER_TYPE.LIMIT: if order.side == SIDE.BUY and order.price < deal_price: continue if order.side == SIDE.SELL and order.price > deal_price: continue # 是否限制涨跌停不成交 if self._price_limit: if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up( order_book_id): continue if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down( order_book_id): continue if self._liquidity_limit: if order.side == SIDE.BUY and price_board.get_a1( order_book_id) == 0: continue if order.side == SIDE.SELL and price_board.get_b1( order_book_id) == 0: continue else: if self._price_limit: if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up( order_book_id): reason = _( "Order Cancelled: current bar [{order_book_id}] reach the limit_up price." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down( order_book_id): reason = _( "Order Cancelled: current bar [{order_book_id}] reach the limit_down price." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if self._liquidity_limit: if order.side == SIDE.BUY and price_board.get_a1( order_book_id) == 0: reason = _( "Order Cancelled: [{order_book_id}] has no liquidity." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if order.side == SIDE.SELL and price_board.get_b1( order_book_id) == 0: reason = _( "Order Cancelled: [{order_book_id}] has no liquidity." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if self._volume_limit: bar = self._env.bar_dict[order_book_id] volume_limit = round( bar.volume * self._volume_percent) - self._turnover[order.order_book_id] round_lot = instrument.round_lot volume_limit = (volume_limit // round_lot) * round_lot if volume_limit <= 0: if order.type == ORDER_TYPE.MARKET: reason = _( u"Order Cancelled: market order {order_book_id} volume {order_volume}" u" due to volume limit").format( order_book_id=order.order_book_id, order_volume=order.quantity) order.mark_cancelled(reason) continue unfilled = order.unfilled_quantity fill = min(unfilled, volume_limit) else: fill = order.unfilled_quantity ct_amount = account.positions.get_or_create( order.order_book_id).cal_close_today_amount(fill, order.side) price = self._slippage_decider.get_trade_price(order, deal_price) trade = Trade.__from_create__( order_id=order.order_id, price=price, amount=fill, side=order.side, position_effect=order.position_effect, order_book_id=order.order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount) trade._commission = self._env.get_trade_commission( account_type_str2enum(account.type), trade) trade._tax = self._env.get_trade_tax( account_type_str2enum(account.type), trade) order.fill(trade) self._turnover[order.order_book_id] += fill self._env.event_bus.publish_event( Event(EVENT.TRADE, account=account, trade=trade, order=order)) if order.type == ORDER_TYPE.MARKET and order.unfilled_quantity != 0: reason = _( u"Order Cancelled: market order {order_book_id} volume {order_volume} is" u" larger than {volume_percent_limit} percent of current bar volume, fill {filled_volume} actually" ).format(order_book_id=order.order_book_id, order_volume=order.quantity, filled_volume=order.filled_quantity, volume_percent_limit=self._volume_percent * 100.0) order.mark_cancelled(reason)
def match(self, open_orders): price_board = self._env.price_board for account, order in open_orders: order_book_id = order.order_book_id instrument = self._env.get_instrument(order_book_id) deal_price = self._deal_price_decider(order_book_id, order.side) if not is_valid_price(deal_price): listed_date = instrument.listed_date.date() if listed_date == self._trading_dt.date(): reason = _( u"Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]").format( order_book_id=order.order_book_id, listed_date=listed_date, ) else: reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format( order_book_id=order.order_book_id) order.mark_rejected(reason) continue if order.type == ORDER_TYPE.LIMIT: if order.side == SIDE.BUY and order.price < deal_price: continue if order.side == SIDE.SELL and order.price > deal_price: continue # 是否限制涨跌停不成交 if self._price_limit: if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id): continue if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id): continue if self._liquidity_limit: if order.side == SIDE.BUY and price_board.get_a1(order_book_id) == 0: continue if order.side == SIDE.SELL and price_board.get_b1(order_book_id) == 0: continue else: if self._price_limit: if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id): reason = _( "Order Cancelled: current bar [{order_book_id}] reach the limit_up price." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id): reason = _( "Order Cancelled: current bar [{order_book_id}] reach the limit_down price." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if self._liquidity_limit: if order.side == SIDE.BUY and price_board.get_a1(order_book_id) == 0: reason = _( "Order Cancelled: [{order_book_id}] has no liquidity." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if order.side == SIDE.SELL and price_board.get_b1(order_book_id) == 0: reason = _( "Order Cancelled: [{order_book_id}] has no liquidity." ).format(order_book_id=order.order_book_id) order.mark_rejected(reason) continue if self._volume_limit: bar = self._env.bar_dict[order_book_id] volume_limit = round(bar.volume * self._volume_percent) - self._turnover[order.order_book_id] round_lot = instrument.round_lot volume_limit = (volume_limit // round_lot) * round_lot if volume_limit <= 0: if order.type == ORDER_TYPE.MARKET: reason = _(u"Order Cancelled: market order {order_book_id} volume {order_volume}" u" due to volume limit").format( order_book_id=order.order_book_id, order_volume=order.quantity ) order.mark_cancelled(reason) continue unfilled = order.unfilled_quantity fill = min(unfilled, volume_limit) else: fill = order.unfilled_quantity ct_amount = account.positions.get_or_create(order.order_book_id).cal_close_today_amount(fill, order.side) price = self._slippage_decider.get_trade_price(order, deal_price) trade = Trade.__from_create__( order_id=order.order_id, price=price, amount=fill, side=order.side, position_effect=order.position_effect, order_book_id=order.order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount ) trade._commission = self._env.get_trade_commission(account_type_str2enum(account.type), trade) trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade) order.fill(trade) self._turnover[order.order_book_id] += fill self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=order)) if order.type == ORDER_TYPE.MARKET and order.unfilled_quantity != 0: reason = _( u"Order Cancelled: market order {order_book_id} volume {order_volume} is" u" larger than {volume_percent_limit} percent of current bar volume, fill {filled_volume} actually" ).format( order_book_id=order.order_book_id, order_volume=order.quantity, filled_volume=order.filled_quantity, volume_percent_limit=self._volume_percent * 100.0 ) order.mark_cancelled(reason)
def _match(self, account, order): order_book_id = order.order_book_id price_board = self._env.price_board last_price = price_board.get_last_price(order_book_id) if not is_valid_price(last_price): instrument = self._env.get_instrument(order_book_id) listed_date = instrument.listed_date.date() if listed_date == self._env.trading_dt.date(): reason = _( "Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]").format( order_book_id=order_book_id, listed_date=listed_date, ) else: reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format( order_book_id=order_book_id) order.mark_rejected(reason) self._env.event_bus.publish_event(Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=copy(order))) return if order.type == ORDER_TYPE.LIMIT: deal_price = order.frozen_price else: deal_price = last_price if self._price_limit: """ 在 Signal 模式下,不再阻止涨跌停是否买进,price_limit 参数表示是否给出警告提示。 """ if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_UP )) if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_DOWN )) ct_amount = account.positions.get_or_create(order_book_id).cal_close_today_amount(order.quantity, order.side) trade_price = self._slippage_decider.get_trade_price(order, deal_price) trade = Trade.__from_create__( order_id=order.order_id, price=trade_price, amount=order.quantity, side=order.side, position_effect=order.position_effect, order_book_id=order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount ) trade._commission = self._env.get_trade_commission(account_type_str2enum(account.type), trade) trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade) order.fill(trade) self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=copy(order)))
def _match(self, account, order): order_book_id = order.order_book_id price_board = self._env.price_board last_price = price_board.get_last_price(order_book_id) if not is_valid_price(last_price): instrument = self._env.get_instrument(order_book_id) listed_date = instrument.listed_date.date() if listed_date == self._env.trading_dt.date(): reason = _( "Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]").format( order_book_id=order_book_id, listed_date=listed_date, ) else: reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format( order_book_id=order_book_id) order.mark_rejected(reason) self._env.event_bus.publish_event(Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=copy(order))) return if order.type == ORDER_TYPE.LIMIT: deal_price = order.frozen_price else: deal_price = last_price if self._price_limit: """ 在 Signal 模式下,不再阻止涨跌停是否买进,price_limit 参数表示是否给出警告提示。 """ if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_UP )) return if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_DOWN )) return ct_amount = account.positions.get_or_create(order_book_id).cal_close_today_amount(order.quantity, order.side) trade_price = self._slippage_decider.get_trade_price(order, deal_price) trade = Trade.__from_create__( order_id=order.order_id, price=trade_price, amount=order.quantity, side=order.side, position_effect=order.position_effect, order_book_id=order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount ) trade._commission = self._env.get_trade_commission(account_type_str2enum(account.type), trade) trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade) order.fill(trade) self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=copy(order)))