def onOrderReport(self, head: dict, data: dict) -> None: """""" sysid = data["clOrdId"] orderid = data["origClOrdId"] self.sys_local_ids[sysid] = orderid self.local_sys_ids[orderid] = sysid timestamp = f"{data['ordDate']} {data['ordCnfmTime']}" dt = datetime.strptime(timestamp, "%Y%m%d %H%M%S%f") status = STATUS_OES2VT[data["ordStatus"]] order = self.orders.get(orderid, None) if not order: symbol = data["securityId"] direction = DIRECTION_OES2VT.get(data["bsType"], None) offset = Offset.NONE if len(symbol) > 6: (direction, offset) = OPTION_DIRECTION_OES2VT[data["bsType"]] order = OrderData(orderid=orderid, symbol=symbol, exchange=EXCHANGE_OES2VT[data["mktId"]], type=ORDERTYPE_OES2VT[data["ordType"]], direction=direction, offset=offset, price=data["ordPrice"] / 10000, volume=data["ordQty"], status=status, datetime=dt, gateway_name=self.gateway_name) self.gateway.on_order(order) else: order.status = status order.datetime = dt self.gateway.on_order(order)
def send_limit_order(self, direction: Direction, offset: Offset, price: float, volume: float, extra: dict = None): """""" self.limit_order_count += 1 order = OrderData(symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=direction, offset=offset, price=price, volume=volume, status=Status.SUBMITTING, gateway_name=self.gateway_name, extra=extra) order.datetime = self.datetime self.active_limit_orders[order.vt_orderid] = order self.limit_orders[order.vt_orderid] = order return order.vt_orderid
def send_order(self, strategy: StrategyTemplate, vt_symbol: str, direction: Direction, offset: Offset, price: float, volume: float, lock: bool) -> List[str]: """""" price = round_to(price, self.priceticks[vt_symbol]) symbol, exchange = extract_vt_symbol(vt_symbol) self.limit_order_count += 1 order = OrderData( symbol=symbol, exchange=exchange, orderid=str(self.limit_order_count), direction=direction, offset=offset, price=price, volume=volume, status=Status.SUBMITTING, gateway_name=self.gateway_name, ) order.datetime = self.datetime self.active_limit_orders[order.vt_orderid] = order self.limit_orders[order.vt_orderid] = order return [order.vt_orderid]
def send_limit_order( self, direction: Direction, offset: Offset, price: float, volume: float ): """""" self.limit_order_count += 1 order = OrderData( symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=direction, offset=offset, price=price, volume=volume, status=Status.SUBMITTING, gateway_name=self.gateway_name, ) # volume是在buy里面的fixed_size order.datetime = self.datetime # 这个很可能是添加order的属性 self.active_limit_orders[order.vt_orderid] = order self.limit_orders[order.vt_orderid] = order return order.vt_orderid
def onOrderEvent(self, data: dict, error: dict, session: int) -> None: """""" if error["error_id"]: self.gateway.write_error("交易委托失败", error) symbol = data["ticker"] if len(symbol) == 8: direction = DIRECTION_OPTION_XTP2VT[data["side"]] offset = OFFSET_XTP2VT[data["position_effect"]] order_type = OPTION_ORDERTYPE_XTP2VT.get(data["price_type"], OrderType.MARKET) else: direction, offset = DIRECTION_STOCK_XTP2VT[data["side"]] if symbol.startswith("688"): type_map = STAR_ORDERTYPE_XTP2VT else: type_map = EQUITY_ORDERTYPE_XTP2VT order_type = type_map.get(data["price_type"], OrderType.MARKET) orderid = str(data["order_xtp_id"]) if orderid not in self.orders: order = OrderData(symbol=symbol, exchange=MARKET_XTP2VT[data["market"]], orderid=orderid, type=order_type, direction=direction, offset=offset, price=data["price"], volume=data["quantity"], traded=data["qty_traded"], status=STATUS_XTP2VT[data["order_status"]], gateway_name=self.gateway_name) self.orders[orderid] = order else: order = self.orders[orderid] order.traded = data["qty_traded"] order.status = STATUS_XTP2VT[data["order_status"]] if not order.datetime: timestamp = str(data["insert_time"]) dt = datetime.strptime(timestamp, "%Y%m%d%H%M%S%f") dt = CHINA_TZ.localize(dt) order.datetime = dt self.gateway.on_order(copy(order))
def onOrderStatus(self, data) -> None: """""" exchange, symbol = data["symbol"].split(".") orderid = data["cl_order_id"] sysid = data["order_id"] if not orderid: orderid = sysid timestamp = f"{data['order_date']} {data['order_time']}" dt = datetime.strptime(timestamp, "%Y%m%d %H%M%S%f") dt = CHINA_TZ.localize(dt) order = self.orders.get(orderid, None) if not order: order = OrderData( orderid=orderid, gateway_name=self.gateway_name, symbol=symbol, exchange=EXCHANGE_GTJA2VT[exchange], direction=DIRECTION_GTJA2VT[data["side"]], type=ORDERTYPE_GTJA2VT.get(data["order_type"], OrderType.MARKET), price=data["price"] / 10000, volume=data["volume"], traded=data["filled_volume"], status=ORDERSTATUS_GTJA2VT[data["order_status"]], datetime=dt, ) self.orders[orderid] = order elif not order.datetime: order.datetime = dt order.traded = data["filled_volume"] order.status = ORDERSTATUS_GTJA2VT[data["order_status"]] self.gateway.on_order(order)
def cross_stop_order(self): """ Cross stop order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.high_price short_cross_price = self.bar.low_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.last_price short_cross_price = self.tick.last_price long_best_price = long_cross_price short_best_price = short_cross_price for stop_order in list(self.active_stop_orders.values()): # Check whether stop order can be triggered. long_cross = (stop_order.direction == Direction.LONG and stop_order.price <= long_cross_price) short_cross = (stop_order.direction == Direction.SHORT and stop_order.price >= short_cross_price) if not long_cross and not short_cross: continue # Create order data. self.limit_order_count += 1 order = OrderData( symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=stop_order.direction, offset=stop_order.offset, price=stop_order.price, volume=stop_order.volume, status=Status.ALLTRADED, gateway_name=self.gateway_name, ) order.datetime = self.datetime self.limit_orders[order.vt_orderid] = order # Create trade data. if long_cross: trade_price = max(stop_order.price, long_best_price) pos_change = order.volume else: trade_price = min(stop_order.price, short_best_price) pos_change = -order.volume self.trade_count += 1 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime self.trades[trade.vt_tradeid] = trade # Update stop order. stop_order.vt_orderid = order.vt_orderid stop_order.status = StopOrderStatus.TRIGGERED self.active_stop_orders.pop(stop_order.stop_orderid) # Push update to strategy. self.strategy.on_stop_order(stop_order) self.strategy.on_order(order) self.strategy.pos += pos_change self.strategy.on_trade(trade)
def on_order_info(self, packet: dict) -> None: """""" data = packet["data"] if not data["order"]: return trans_type = data["trans_type"] # Map sys and local orderid if trans_type == TRADE_TRANSACTION_ORDER_ADD: sys_id = str(data["order"]) local_id = data["order_comment"] if not local_id: local_id = sys_id self.local_sys_map[local_id] = sys_id self.sys_local_map[sys_id] = local_id order = self.orders.get(local_id, None) if local_id and order: order.datetime = generate_datetime(data["order_time_setup"]) # Update order data elif trans_type in {TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_ORDER_DELETE}: sysid = str(data["order"]) local_id = self.sys_local_map[sysid] order = self.orders.get(local_id, None) if not order: direction, order_type = ORDERTYPE_MT2VT[data["order_type"]] order = OrderData( symbol=data["symbol"].replace('.', '-'), exchange=Exchange.OTC, orderid=local_id, type=order_type, direction=direction, price=data["order_price"], volume=data["order_volume_initial"], gateway_name=self.gateway_name ) self.orders[local_id] = order if data["order_time_setup"]: order.datetime = generate_datetime(data["order_time_setup"]) if data["trans_state"] in STATUS_MT2VT: order.status = STATUS_MT2VT[data["trans_state"]] self.on_order(order) # Update trade data elif trans_type == TRADE_TRANSACTION_HISTORY_ADD: sysid = str(data["order"]) local_id = self.sys_local_map[sysid] order = self.orders.get(local_id, None) if order: if data["order_time_setup"]: order.datetime = generate_datetime(data["order_time_setup"]) trade = TradeData( symbol=order.symbol.replace('.', '-'), exchange=order.exchange, direction=order.direction, orderid=order.orderid, tradeid=data["deal"], price=data["trans_price"], volume=data["trans_volume"], datetime=LOCAL_TZ.localize(datetime.now()), gateway_name=self.gateway_name ) order.traded = trade.volume self.on_order(order) self.on_trade(trade)
def on_order_info(self, packet: dict) -> None: """""" data = packet["data"] if not data["order"]: if data["trans_type"] == TRADE_TRANSACTION_REQUEST: local_id = data["request_comment"] order = self.orders.get(local_id, None) if local_id and order: order_id = str(data["result_order"]) if data["result_order"] and self.sys_local_map[ order_id] == order_id: order.orderid = local_id order.traded = data["result_volume"] if order.traded == order.volume: order.status = Status.ALLTRADED else: order.status = Status.PARTTRADED self.on_order(order) trade = TradeData(symbol=order.symbol, exchange=order.exchange, direction=order.direction, orderid=data["request_comment"], tradeid=data["result_deal"], price=data["result_price"], volume=data["result_volume"], datetime=LOCAL_TZ.localize( datetime.now()), gateway_name=self.gateway_name) self.on_trade(trade) elif data["result_retcode"] == TRADE_RETCODE_MARKET_CLOSED: order.status = Status.REJECTED self.write_log(f"委托{local_id}拒单,原因market_closed") self.on_order(order) return trans_type = data["trans_type"] # Map sys and local orderid if trans_type == TRADE_TRANSACTION_ORDER_ADD: sys_id = str(data["order"]) local_id = data["order_comment"] if not local_id: local_id = sys_id self.local_sys_map[local_id] = sys_id self.sys_local_map[sys_id] = local_id order = self.orders.get(local_id, None) if local_id and order: order.datetime = generate_datetime(data["order_time_setup"]) # Update order data elif trans_type in { TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_ORDER_DELETE }: sysid = str(data["order"]) local_id = self.sys_local_map[sysid] order = self.orders.get(local_id, None) if not order: direction, order_type = ORDERTYPE_MT2VT[data["order_type"]] order = OrderData(symbol=data["symbol"].replace('.', '-'), exchange=Exchange.OTC, orderid=local_id, type=order_type, direction=direction, price=data["order_price"], volume=data["order_volume_initial"], gateway_name=self.gateway_name) self.orders[local_id] = order if data["order_time_setup"]: order.datetime = generate_datetime(data["order_time_setup"]) if data["trans_state"] in STATUS_MT2VT: order.status = STATUS_MT2VT[data["trans_state"]] self.on_order(order) # Update trade data elif trans_type == TRADE_TRANSACTION_HISTORY_ADD: sysid = str(data["order"]) local_id = self.sys_local_map[sysid] order = self.orders.get(local_id, None) if order: if data["order_time_setup"]: order.datetime = generate_datetime( data["order_time_setup"]) trade = TradeData(symbol=order.symbol.replace('.', '-'), exchange=order.exchange, direction=order.direction, orderid=order.orderid, tradeid=data["deal"], price=data["trans_price"], volume=data["trans_volume"], datetime=LOCAL_TZ.localize(datetime.now()), gateway_name=self.gateway_name) order.traded = trade.volume self.on_order(order) self.on_trade(trade)
def on_order_info(self, packet: dict) -> None: """""" data = packet["data"] if not data["order"]: return trans_type = data["trans_type"] # Map sys and local orderid if trans_type == 0: sys_id = str(data["order"]) local_id = data["order_comment"] if not local_id: local_id = sys_id self.local_sys_map[local_id] = sys_id self.sys_local_map[sys_id] = local_id # Update order data elif trans_type in {1, 2}: sysid = str(data["order"]) local_id = self.sys_local_map[sysid] order = self.orders.get(local_id, None) if not order: direction, order_type = ORDERTYPE_MT2VT[data["order_type"]] order = OrderData(symbol=data["symbol"], exchange=Exchange.OTC, orderid=local_id, type=order_type, direction=direction, price=data["order_price"], volume=data["order_volume_initial"], gateway_name=self.gateway_name) self.orders[local_id] = order order.traded = data["order_volume_initial"] - data[ "order_volume_current"] if data["order_time_setup"]: order.datetime = generate_datetime(data["order_time_setup"]) if data["trans_state"] in STATUS_MT2VT: order.status = STATUS_MT2VT[data["trans_state"]] self.on_order(order) # Update trade data elif trans_type == 6: sysid = str(data["order"]) local_id = self.sys_local_map[sysid] order = self.orders.get(local_id, None) if order: if data["order_time_setup"]: order.datetime = generate_datetime( data["order_time_setup"]) trade = TradeData( symbol=order.symbol, exchange=order.exchange, direction=order.direction, orderid=order.orderid, tradeid=data["deal"], price=data["trans_price"], volume=data["trans_volume"], datetime=datetime.now().replace(tzinfo=LOCAL_TZ), gateway_name=self.gateway_name) self.on_trade(trade)
def cross_stop_order(self): """ Cross stop order with last bar/tick data. T时刻内,价格上下波动,形成T日K线; T时刻走完,基于T日以及之前数据计算通道上下轨 T+1时刻开盘,基于上一步的通道上下轨挂出对应的停止单 T+1时刻内,价格突破通道是触发停止单,立即发出市价单成交 """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.high_price short_cross_price = self.bar.low_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.last_price short_cross_price = self.tick.last_price long_best_price = long_cross_price short_best_price = short_cross_price for stop_order in list(self.active_stop_orders.values()): # Check whether stop order can be triggered. # self.active_stop_orders.values里面的数据结构是一个类,这里面使用类来保存数据。 long_cross = (stop_order.direction == Direction.LONG and stop_order.price <= long_cross_price) short_cross = (stop_order.direction == Direction.SHORT and stop_order.price >= short_cross_price) if not long_cross and not short_cross: continue # Create order data. # 停止单最后还是要转化为限价单 self.limit_order_count += 1 order = OrderData(symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=stop_order.direction, offset=stop_order.offset, price=stop_order.price, volume=stop_order.volume, status=Status.ALLTRADED, gateway_name=self.gateway_name, time=self.datetime.strftime("%H:%M:%S")) """ symbol表示交易品种,如IF88,在最开始传入 exchange表示交易所,在set_parameters中传入的 self.limit_order_count表示限价单的数量 stop_order表示在发送停止单时的一些信息 stop_order.direction的方向在上面 offset表示开或平 status: Status = Status.SUBMITTING这个是默认值, getway_name是在BacktestingEngine中确定的 """ order.datetime = self.datetime # 这个地方和可能是直接给这个类添加属性,这个有什么用呢,为什么不直接放进OrderData里面去,self.datetime= bar.datetime self.limit_orders[order.vt_orderid] = order # 没有把这笔交易推给策略,没有搞懂为什么,这个不是active,因为一旦发出即成交了,两种情况,一种是t时刻就已经把单子挂在交易所那边,另一种是挂在自己的系统上面只要满足条件就提交订单,并不一定需要t+1的K线形成才可以 # Create trade data. if long_cross: trade_price = max(stop_order.price, long_best_price) pos_change = order.volume else: trade_price = min(stop_order.price, short_best_price) pos_change = -order.volume self.trade_count += 1 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime # direction表示方向,offset表示经常模式,一手多两手空,会平掉多仓空仓,然后开 # 一个空仓 # 这个time是一个字符串 self.trades[trade.vt_tradeid] = trade # Update stop order. stop_order.vt_orderids.append(order.vt_orderid) stop_order.status = StopOrderStatus.TRIGGERED if stop_order.stop_orderid in self.active_stop_orders: self.active_stop_orders.pop(stop_order.stop_orderid) # Push update to strategy. self.strategy.on_stop_order(stop_order) self.strategy.on_order(order) # 这个地方把停止单推给了策略 self.strategy.pos += pos_change self.strategy.on_trade(trade)