def on_order(self, order: OrderData) -> None: # 更新活跃报单 active_orders = [] for order in self.app.recorder.get_all_active_orders( order.local_symbol): active_orders.append(order._to_dict()) data = {"type": "active_order", "data": active_orders} self.io.emit("active_order", data) orders = [] for order in self.app.recorder.get_all_orders(): orders.append(order._to_dict()) data = {"type": "order", "data": orders} self.io.emit("order", data)
def onRtnOrder(self, data: dict): """ Callback of order status update. """ symbol = data["InstrumentID"] exchange = symbol_exchange_map.get(symbol, "") if not exchange: self.order_data.append(data) return frontid = data["FrontID"] sessionid = data["SessionID"] order_ref = data["OrderRef"] order_id = f"{frontid}_{sessionid}_{order_ref}" order = OrderData(symbol=symbol, exchange=exchange, order_id=order_id, type=ORDERTYPE_CTP2VT[data["OrderPriceType"]], direction=DIRECTION_CTP2VT[data["Direction"]], offset=OFFSET_CTP2VT[data["CombOffsetFlag"]], price=data["LimitPrice"], volume=data["VolumeTotalOriginal"], traded=data["VolumeTraded"], status=STATUS_CTP2VT[data["OrderStatus"]], time=data["InsertTime"], gateway_name=self.gateway_name) self.on_event(type=EVENT_ORDER, data=order) self.sysid_orderid_map[data["OrderSysID"]] = order_id
def update_order(self, order: OrderData): """""" if order.is_active(): self.active_orders[order.local_order_id] = order else: if order.local_order_id in self.active_orders: self.active_orders.pop(order.local_order_id) self.calculate_frozen()
def _push_order_callback(self, order: OrderData, is_traded: bool): """ 推送order回策略层, 如果已经成交, 那么找到成交单数据并推送回去, 如果没有成交 ,那么将order的状态推荐为正在提交中 :param order_data: 报单 :param is_traded: 是否成交 :return: """ if is_traded: """ 如果成交了那么同时推送""" trade = self.traded_order_mapping[order.order_id] order.status = Status.ALLTRADED self._push_order() self._push_trade(trade) else: order.status = Status.SUBMITTING self.order_id_pending_mapping[order.order_id] = order self._push_order(order) self.pending.appendleft(order)
def _auth_order_price(self, order: OrderData): """ 检查报单价格是否超过涨跌停 :param order: 报单 :return: """ if order.price > self.current_tick.limit_up or order.price < self.current_tick.limit_down: self.log("价格超过涨跌停, 拒单") order.status = Status.REJECTED self._push_order(order) return False return True
def onRspOrderInsert(self, data: dict, error: dict, reqid: int, last: bool): """""" order_ref = data["OrderRef"] order_id = f"{self.frontid}_{self.sessionid}_{order_ref}" symbol = data["InstrumentID"] exchange = symbol_exchange_map[symbol] order = OrderData(symbol=symbol, exchange=exchange, order_id=order_id, direction=DIRECTION_CTP2VT[data["Direction"]], offset=OFFSET_CTP2VT[data["CombOffsetFlag"]], price=data["LimitPrice"], volume=data["VolumeTotalOriginal"], status=Status.REJECTED, gateway_name=self.gateway_name) self.on_event(type=EVENT_ORDER, data=order) error['detail'] = "交易委托失败" self.on_event(type=EVENT_ERROR, data=error)
def match_deal(self, data: OrderData) -> int or TradeData: """ 撮合成交 维护一个返回状态 -1: 超出下单限制 -2: 超出涨跌价格 -3: 未成交 -4: 资金不足 p : 成交回报 todo: 处理冻结 ?? """ if self.params.get("deal_pattern") == "match": """ 撮合成交 """ # todo: 是否可以模拟一定量的市场冲击响应? 以靠近更加逼真的回测效果 ???? elif self.params.get("deal_pattern") == "price": """ 见价成交 """ # 先判断价格和手数是否满足限制条件 if data.volume > self.params.get( "single_order_limit" ) or self.today_volume > self.params.get("single_day_limit"): """ 超出限制 直接返回不允许成交 """ return -1 if data.price < self.drop_price or data.price > self.upper_price: """ 超出涨跌价格 """ return -2 # 发单立即冻结 self.account.update_frozen(data) # 进行成交判断 long_c = self.price.low_price if self.price.low_price is not None else self.price.ask_price_1 short_c = self.price.high_price if self.price.low_price is not None else self.price.bid_price_1 long_b = self.price.open_price if self.price.low_price is not None else long_c short_b = self.price.open_price if self.price.low_price is not None else short_c long_cross = data.direction == Direction.LONG and data.price >= long_c > 0 short_cross = data.direction == Direction.SHORT and data.price <= short_c and short_c > 0 # 处理未成交的单子 for order in self.pending: index = self.pending.index(order) long_cross = data.direction == Direction.LONG and order.price >= long_c > 0 short_cross = data.direction == Direction.SHORT and order.price <= short_c and short_c > 0 if not long_cross and not short_cross: """ 不成交 """ continue if long_cross: order.price = min(order.price, long_b) else: order.price = max(order.price, short_b) trade = self._generate_trade_data_from_order(order) order.status = Status.ALLTRADED [ api(deepcopy(order)) for api in self.strategy_mapping.values() ] [api(trade) for api in self.strategy_mapping.values()] self.pending.remove(order) # 成交,移除冻结 self.account.update_frozen(order=order, reverse=True) self.update_account_margin(trade) if not long_cross and not short_cross: # 未成交单, 提交到pending里面去 self.pending.append(data) return -3 if long_cross: data.price = min(data.price, long_b) else: data.price = max(data.price, short_b) """ 判断账户资金是否足以支撑成交 """ if self.account.is_traded(data): """ 调用API生成成交单 """ # 同时这里需要处理是否要进行 p = self._generate_trade_data_from_order(data) self.account.update_trade(p) """ 调用strategy的on_trade """ [api(p) for api in self.strategy_mapping.values()] self.today_volume += data.volume # 已经成交,同时移除冻结 self.account.update_frozen(p, reverse=True) self.update_account_margin(p) return p else: """ 当前账户不足以支撑成交 """ return -4 else: raise TypeError("未支持的成交机制")
def on_order(self, order: OrderData) -> None: data = { "type": "order", "data": order._to_dict() } self.io.emit("order", data)