def cross_order(self, order: OrderData, tick: TickData): """""" contract = self.main_engine.get_contract(order.vt_symbol) trade_price = 0 # Cross market order immediately after received if order.type == OrderType.MARKET: if order.direction == Direction.LONG: trade_price = tick.ask_price_1 + self.trade_slippage * contract.pricetick else: trade_price = tick.bid_price_1 - self.trade_slippage * contract.pricetick # Cross limit order only if price touched elif order.type == OrderType.LIMIT: if order.direction == Direction.LONG: if order.price >= tick.ask_price_1: trade_price = tick.ask_price_1 else: if order.price <= tick.bid_price_1: trade_price = tick.bid_price_1 # Cross limit order only if price broken elif order.type == OrderType.STOP: if order.direction == Direction.LONG: if tick.ask_price_1 >= order.price: trade_price = tick.ask_price_1 + self.trade_slippage * contract.pricetick else: if tick.bid_price_1 <= order.price: trade_price = tick.bid_price_1 - self.trade_slippage * contract.pricetick if trade_price: order.status = Status.ALLTRADED order.traded = order.volume self.put_event(EVENT_ORDER, order) trade = TradeData(symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=order.orderid, direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, datetime=datetime.now(LOCAL_TZ), gateway_name=order.gateway_name) self.put_event(EVENT_TRADE, trade) self.update_position(trade, contract)
def update_trade(self, data: dict): """""" timestamp = f"{data['FilledDate']} {data['FilledTime']}" dt = datetime.strptime(timestamp, "%Y%m%d %H:%M:%S") dt = dt.replace(tzinfo=CHINA_TZ) trade = TradeData(symbol=data["TreatyCode"], exchange=EXCHANGE_DA2VT[data["ExchangeCode"]], orderid=data["LocalNo"], tradeid=data["FilledNo"], direction=DIRECTION_DA2VT[data["BuySale"]], offset=OFFSET_DA2VT[data["AddReduce"]], price=float(data["FilledPrice"]), volume=int(data["FilledNumber"]), datetime=dt, gateway_name=self.gateway_name) self.gateway.on_trade(trade)
def on_order(self, packet: dict) -> None: """""" ord_data = packet["o"] key = (ord_data["o"], ord_data["f"]) order_type = ORDERTYPE_BINANCES2VT.get(key, None) if not order_type: return dt = generate_datetime(packet["E"]) order = OrderData(symbol=ord_data["s"], exchange=Exchange.BINANCE, orderid=str(ord_data["c"]), type=order_type, direction=DIRECTION_BINANCES2VT[ord_data["S"]], price=float(ord_data["p"]), volume=float(ord_data["q"]), traded=float(ord_data["z"]), status=STATUS_BINANCES2VT[ord_data["X"]], datetime=dt, gateway_name=self.gateway_name, offset=OFFSET_BINANCES2VT[ord_data['R']], time=dt.time()) if "n" in ord_data.keys(): order.fee = float(ord_data['n']) order.netpnl = float(ord_data['rp']) self.gateway.on_order(order) # Push trade event trade_volume = float(ord_data["l"]) if not trade_volume: return trade = TradeData(symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=ord_data["t"], direction=order.direction, price=float(ord_data["L"]), volume=trade_volume, datetime=generate_datetime(ord_data["T"]), gateway_name=self.gateway_name, offset=order.offset) self.gateway.on_trade(trade)
def to_trade(self): """ Generate ContractData object from DbContractData. """ trade = TradeData(accountid=self.accountid, symbol=self.symbol, exchange=Exchange(self.exchange), orderid=self.orderid, tradeid=self.tradeid, direction=Direction(self.direction), offset=Offset(self.offset), price=self.price, volume=self.volume, datetime=self.datetime, gateway_name="DB") return trade
def update_trade(self, data: dict) -> None: """ Convert TAP fill data structure into TradeData event and push it. """ orderid = self.sys_local_map[data["OrderNo"]] trade = TradeData(symbol=data["CommodityNo"] + data["ContractNo"], exchange=EXCHANGE_TAP2VT.get(data["ExchangeNo"], None), orderid=orderid, tradeid=data["MatchNo"], direction=DIRECTION_TAP2VT[data["MatchSide"]], price=data["MatchPrice"], volume=data["MatchQty"], datetime=generate_datetime(data["MatchDateTime"]), gateway_name=self.gateway_name) self.gateway.on_trade(trade)
def on_order(self, data: dict): """""" dt = datetime.fromtimestamp(data["created_at"] / 1000) time = dt.strftime("%H:%M:%S") if data["client_order_id"]: orderid = data["client_order_id"] else: orderid = data["order_id"] order = OrderData(symbol=data["contract_code"], exchange=Exchange.HUOBI, orderid=orderid, type=ORDERTYPE_HBDM2VT[data["order_price_type"]], direction=DIRECTION_HBDM2VT[data["direction"]], offset=OFFSET_HBDM2VT[data["offset"]], price=data["price"], volume=data["volume"], traded=data["trade_volume"], status=STATUS_HBDM2VT[data["status"]], time=time, gateway_name=self.gateway_name) self.gateway.on_order(order) # Push trade event trades = data["trade"] if not trades: return for d in trades: dt = datetime.fromtimestamp(d["created_at"] / 1000) time = dt.strftime("%H:%M:%S") trade = TradeData( symbol=order.symbol, exchange=Exchange.HUOBI, orderid=order.orderid, tradeid=str(d["trade_id"]), direction=order.direction, offset=order.offset, price=d["trade_price"], volume=d["trade_volume"], time=time, gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def parse_trade(data: dict) -> TradeData: """ Convert json received from API to TradeData object. """ trade = TradeData( symbol=f"{data['symbol']}_{data['settle_type']}", exchange=enum_decode(data["exchange"]), orderid=data["orderid"], tradeid=data["tradeid"], direction=enum_decode(data["direction"]), offset=enum_decode(data["offset"]), price=float(data["price"]), volume=float(data["volume"]), time=data["time"], gateway_name=data["gateway_name"] ) return trade
def on_order(self, packet: dict): """""" dt = datetime.fromtimestamp(packet["O"] / 1000) time = dt.strftime("%Y-%m-%d %H:%M:%S") if packet["C"] == "null": orderid = packet["c"] else: orderid = packet["C"] order = OrderData( symbol=packet["s"], exchange=Exchange.BINANCE, orderid=orderid, type=ORDERTYPE_BINANCE2VT[packet["o"]], direction=DIRECTION_BINANCE2VT[packet["S"]], price=float(packet["p"]), volume=float(packet["q"]), traded=float(packet["z"]), status=STATUS_BINANCE2VT[packet["X"]], time=time, gateway_name=self.gateway_name ) self.gateway.on_order(order) # Push trade event trade_volume = float(packet["l"]) if not trade_volume: return trade_dt = datetime.fromtimestamp(packet["T"] / 1000) trade_time = trade_dt.strftime("%Y-%m-%d %H:%M:%S") trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=packet["t"], direction=order.direction, price=float(packet["L"]), volume=trade_volume, time=trade_time, gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_order(self, packet: dict) -> None: """""" ord_data = packet["o"] key = (ord_data["o"], ord_data["f"]) order_type = ORDERTYPE_BINANCES2VT.get(key, None) if not order_type: return order = OrderData(symbol=ord_data["s"], exchange=Exchange.BINANCE, orderid=str(ord_data["c"]), type=order_type, direction=DIRECTION_BINANCES2VT[ord_data["S"]], price=float(ord_data["p"]), volume=float(ord_data["q"]), traded=float(ord_data["z"]), status=STATUS_BINANCES2VT[ord_data["X"]], datetime=generate_datetime(packet["E"]), gateway_name=self.gateway_name) self.gateway.on_order(order) # Round trade volume to minimum trading volume trade_volume = float(ord_data["l"]) contract = symbol_contract_map.get(order.symbol, None) if contract: trade_volume = round_to(trade_volume, contract.min_volume) if not trade_volume: return # Push trade event trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=ord_data["t"], direction=order.direction, price=float(ord_data["L"]), volume=trade_volume, datetime=generate_datetime(ord_data["T"]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_order(self, data): """""" # Update order d = data["order"] sys_orderid = d["id"] local_orderid = d["client_order_id"] LOCAL_SYS_MAP[local_orderid] = sys_orderid direction = DIRECTION_ALPACA2VT[d["side"]] order_type = ORDERTYPE_ALPACA2VT[d["type"]] order = OrderData( orderid=local_orderid, symbol=d["symbol"], exchange=Exchange.SMART, price=float(d["limit_price"]), volume=float(d["qty"]), type=order_type, direction=direction, traded=float(d["filled_qty"]), status=STATUS_ALPACA2VT.get(d["status"], Status.SUBMITTING), datetime=generate_datetime(d["created_at"]), gateway_name=self.gateway_name, ) self.gateway.on_order(order) # Update Trade event = data.get("event", "") if event != "fill": return self.trade_count += 1 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, price=float(data["price"]), volume=int(data["qty"]), datetime=generate_datetime(data["timestamp"]), gateway_name=self.gateway_name ) self.gateway.on_trade(trade)
def OnRtnTrade(self, info: CTORATstpTradeField) -> None: """""" try: trade_data = TradeData( gateway_name=self.gateway.gateway_name, symbol=info.SecurityID, exchange=EXCHANGE_TORA2VT[info.ExchangeID], orderid=info.OrderRef, tradeid=info.TradeID, direction=DIRECTION_TORA2VT[info.Direction], offset=Offset.OPEN, price=info.Price, volume=info.Volume, time=info.TradeTime, ) self.gateway.on_trade(trade_data) except KeyError: return
def on_trade(self, data: dict) -> None: """成交更新推送""" sys_id: str = data["order_id"] local_id: str = self.sys_local_map[sys_id] trade: TradeData = TradeData( symbol=data["instrument_name"], exchange=Exchange.DERIBIT, orderid=local_id, tradeid=data["trade_id"], direction=DIRECTION_DERIBIT2VT[data["direction"]], price=data["price"], volume=data["amount"], datetime=generate_datetime(data["timestamp"]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_trade(self, data: list, orderid): """""" sys_id = data["order_id"] local_id = self.sys_local_map[sys_id] trade = TradeData( symbol=data["instrument_name"], exchange=Exchange.DERIBIT, orderid=local_id, tradeid=data["trade_id"], direction=DIRECTION_DERIBIT2VT[data["direction"]], price=float(data["price"]), volume=float(data["amount"]), time=str(datetime.fromtimestamp(data["timestamp"] / 1000)), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_market_trade(self, packet): """""" channel = packet["channel"] data = packet["data"] tick = self.ticks[channel] tick.last_price = data["price"] tick.last_volume = data["amount"] dt = datetime.fromtimestamp(int(data["timestamp"])) tick.datetime = dt.replace(tzinfo=UTC_TZ) self.gateway.on_tick(copy(tick)) # Order status check buy_orderid = str(data["buy_order_id"]) sell_orderid = str(data["sell_order_id"]) for sys_orderid in [buy_orderid, sell_orderid]: order = self.order_manager.get_order_with_sys_orderid( sys_orderid) if order: order.traded += data["amount"] if order.traded < order.volume: order.status = Status.PARTTRADED else: order.status = Status.ALLTRADED self.order_manager.on_order(copy(order)) trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=data["id"], direction=order.direction, price=data["price"], volume=data["amount"], datetime=tick.datetime, gateway_name=self.gateway_name ) self.gateway.on_trade(trade)
def on_order_match(self, packet: dict): """""" if packet["maker_order_id"] in sys_order_map: order = sys_order_map[packet["maker_order_id"]] else: order = sys_order_map[packet["taker_order_id"]] trade = TradeData( symbol=packet["product_id"], exchange=Exchange.COINBASE, orderid=order.orderid, tradeid=packet["trade_id"], direction=DIRECTION_COINBASE2VT[packet["side"]], price=float(packet["price"]), volume=float(packet["size"]), datetime=generate_datetime(packet["time"]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_order_match(self, packet: dict): """""" if packet['maker_order_id'] in sys_order_map: order = sys_order_map[packet['maker_order_id']] else: order = sys_order_map[packet['taker_order_id']] trade = TradeData( symbol=packet['product_id'], exchange=Exchange.COINBASE, orderid=order.orderid, tradeid=packet['trade_id'], direction=DIRECTION_COINBASE2VT[packet['side']], price=float(packet['price']), volume=float(packet['size']), time=packet['time'], gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_order_change(self, tiger_account: str, data: list): """""" data = dict(data) symbol, exchange = convert_symbol_tiger2vt(data["origin_symbol"]) status = STATUS_TIGER2VT[data["status"]] dt = datetime.fromtimestamp(data["order_time"] / 1000) dt = dt.replace(tzinfo=CHINA_TZ) order = OrderData( symbol=symbol, exchange=exchange, orderid=self.ID_TIGER2VT.get(str(data["order_id"]), self.get_new_local_id()), direction=Direction.NET, price=data.get("limit_price", 0), volume=data["quantity"], traded=data["filled"], status=status, datetime=dt, gateway_name=self.gateway_name, ) self.ID_TIGER2VT[str(data["order_id"])] = order.orderid self.on_order(order) if status == Status.ALLTRADED: dt = datetime.fromtimestamp(data["trade_time"] / 1000) dt = dt.replace(tzinfo=CHINA_TZ) self.tradeid += 1 trade = TradeData( symbol=symbol, exchange=exchange, direction=Direction.NET, tradeid=self.tradeid, orderid=self.ID_TIGER2VT[str(data["order_id"])], price=data["avg_fill_price"], volume=data["filled"], datetime=dt, gateway_name=self.gateway_name, ) self.on_trade(trade)
def on_order_filled(self, data: dict, request: "Request"): order_id = data.get('clientOrderID', None) if order_id is None: order_id = data['orderID'] order: OrderData = self.gateway.orders[order_id] # # new API: # price = 0.0 # if 'tradeOpened' in data: # price += float(data['tradeOpened']['price']) # if 'tradeReduced' in data: # price += float(data['tradeReduced']['price']) # if 'tradeClosed' in data: # price += sum([float(i['price']) for i in data['tradeClosed']]) # note: 'price' record is Deprecated # but since this is faster and easier, we use this record. price = float(data['price']) # for Oanda, one order fill is a single trade. trade = TradeData( gateway_name=self.gateway_name, symbol=order.symbol, exchange=Exchange.OANDA, orderid=order_id, tradeid=order_id, direction=order.direction, offset=Offset.NONE, price=price, volume=order.volume, time=parse_time(data['time']), ) self.gateway.on_trade(trade) # this message indicate that this order is full filled. # ps: oanda's order has only two state: NOTTRADED, ALLTRADED. It it my settings error? order.traded = order.volume order.status = Status.ALLTRADED # order.time = trade.time order.time = parse_time(data['time']) self.gateway.on_order(order)
def on_trade(self, packet: dict): """""" for d in packet["data"]: order_id = d["order_link_id"] if not order_id: order_id = d["order_id"] trade = TradeData( symbol=d["symbol"], exchange=Exchange.BYBIT, orderid=order_id, tradeid=d["exec_id"], direction=DIRECTION_BYBIT2VT[d["side"]], price=float(d["price"]), volume=d["exec_qty"], time=d["trade_time"], gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def update_trade(self, data: dict) -> None: """""" symbol = data["InstrumentID"] exchange = EXCHANGE_UFT2VT[data["ExchangeID"]] sessionid = data["SessionID"] order_ref = data["OrderRef"] orderid = f"{sessionid}_{order_ref}" trade = TradeData(symbol=symbol, exchange=exchange, orderid=orderid, tradeid=data["TradeID"], direction=DIRECTION_UFT2VT[data["Direction"]], offset=OFFSET_UFT2VT[data["OffsetFlag"]], price=data["TradePrice"], volume=data["TradeVolume"], time=generate_time(data["TradeTime"]), gateway_name=self.gateway_name) self.gateway.on_trade(trade) print("on_trade", trade.orderid, trade.volume)
def on_trade(self, data: dict) -> None: """""" sys_orderid = str(data["orderID"]) order = self.order_manager.get_order_with_sys_orderid(sys_orderid) order.status = STATUS_KAISA2VT[data["orderStatus"]] order.traded = int(data["execQty"]) self.gateway.on_order(order) self.gateway.rest_api.trader_count += 1 trade = TradeData(tradeid=str(self.gateway.rest_api.trader_count), symbol=data["productCode"], exchange=Exchange.HKSE, orderid=order.orderid, direction=order.direction, price=float(data["execPrice"]), volume=int(data["execQty"]), datetime=generate_datetime(data["tradeTime"]), gateway_name=self.gateway_name) self.gateway.on_trade(trade)
def on_trade(self, data): """""" self.trade_id += 1 if data[4] > 0: direction = Direction.LONG else: direction = Direction.SHORT trade = TradeData( symbol=str(data[1].replace("t", "")), exchange=Exchange.BITFINEX, orderid=data[-1], direction=direction, volume=abs(data[4]), price=data[5], tradeid=str(self.trade_id), datetime=generate_datetime(data[2]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def execDetails(self, reqId: int, contract: Contract, execution: Execution): # pylint: disable=invalid-name """ Callback of trade data update. """ super().execDetails(reqId, contract, execution) # today_date = datetime.now().strftime("%Y%m%d") trade = TradeData( symbol=contract.conId, exchange=EXCHANGE_IB2VT.get(contract.exchange, contract.exchange), orderid=str(execution.orderId), tradeid=str(execution.execId), direction=DIRECTION_IB2VT[execution.side], price=execution.price, volume=execution.shares, time=datetime.strptime(execution.time, "%Y%m%d %H:%M:%S"), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_trade(self, l: List, t: int): """""" d = l[0] sys_orderid = d["order_id"] order = self.order_manager.get_order_with_sys_orderid(sys_orderid) if not order: return trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=d["id"], direction=order.direction, price=float(d["price"]), volume=abs(d["size"]), datetime=generate_datetime(d["create_time"]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def onTradeEvent(self, data: dict, session: int) -> None: """""" symbol = data["ticker"] if len(symbol) == 8: direction = DIRECTION_OPTION_XTP2VT[data["side"]] offset = OFFSET_XTP2VT[data["position_effect"]] else: direction, offset = DIRECTION_STOCK_XTP2VT[data["side"]] trade = TradeData(symbol=symbol, exchange=MARKET_XTP2VT[data["market"]], orderid=str(data["order_xtp_id"]), tradeid=str(data["exec_id"]), direction=direction, offset=offset, price=data["price"], volume=data["quantity"], time=data["trade_time"], gateway_name=self.gateway_name) self.gateway.on_trade(trade)
def on_order(self, packet: dict): """""" if packet["C"] == "": orderid = packet["c"] else: orderid = packet["C"] order = OrderData( symbol=packet["s"].lower(), exchange=Exchange.BINANCE, orderid=orderid, type=ORDERTYPE_BINANCE2VT[packet["o"]], direction=DIRECTION_BINANCE2VT[packet["S"]], price=float(packet["p"]), volume=float(packet["q"]), traded=float(packet["z"]), status=STATUS_BINANCE2VT[packet["X"]], datetime=generate_datetime(packet["O"]), gateway_name=self.gateway_name ) self.gateway.on_order(order) # Push trade event trade_volume = float(packet["l"]) if not trade_volume: return trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=packet["t"], direction=order.direction, price=float(packet["L"]), volume=trade_volume, datetime=generate_datetime(packet["T"]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def onTradeEvent(self, data: dict, session: int) -> None: """""" symbol = data["ticker"] if len(symbol) == 8: direction = DIRECTION_OPTION_XTP2VT[data["side"]] offset = OFFSET_XTP2VT[data["position_effect"]] else: direction, offset = DIRECTION_STOCK_XTP2VT[data["side"]] timestamp = str(data["trade_time"]) dt = datetime.strptime(timestamp, "%Y%m%d%H%M%S%f") dt = CHINA_TZ.localize(dt) trade = TradeData( symbol=symbol, exchange=MARKET_XTP2VT[data["market"]], orderid=str(data["order_xtp_id"]), tradeid=str(data["exec_id"]), direction=direction, offset=offset, price=data["price"], volume=data["quantity"], datetime=dt, gateway_name=self.gateway_name ) if trade.orderid in self.orders: order = self.orders[trade.orderid] order.traded += trade.volume if order.traded < order.volume: order.status = Status.PARTTRADED else: order.status = Status.ALLTRADED self.gateway.on_order(order) else: self.gateway.write_log(f"成交找不到对应委托{trade.orderid}") self.gateway.on_trade(trade)
def on_order(self, d): """order的回调函数""" order = OrderData( symbol=d["instrument_id"], exchange=Exchange.OKEX, type=ORDERTYPE_OKEX2VT[d["type"]], orderid=d["client_oid"], direction=DIRECTION_OKEX2VT[d["side"]], price=float(d["price"]), volume=float(d["size"]), traded=float(d["filled_size"]), time=d["timestamp"][11:19], status=STATUS_OKEX2VT[d["status"]], gateway_name=self.gateway_name, ) # 向gateway里面推送order self.gateway.on_order(copy(order)) # 这个字段的意思就是最新成交数量 trade_volume = d.get("last_fill_qty", 0) if not trade_volume or float(trade_volume) == 0: return # 如果有成交,数量不为0,则进行以下操作,推送成交 self.trade_count += 1 tradeid = f"spot{self.connect_time}{self.trade_count}" # last_fill_px 最近成交价格,last_fill_time 最新成交时间 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=tradeid, direction=order.direction, price=float(d["last_fill_px"]), volume=float(trade_volume), time=d["last_fill_time"][11:19], gateway_name=self.gateway_name ) self.gateway.on_trade(trade)
def on_order(self, d): """这里是将收到的order转换成本地OrderData""" offset, direction = TYPE_OKEXF2VT[d["type"]] order = OrderData( symbol=d["instrument_id"], exchange=Exchange.OKEXF, type=ORDERTYPE_OKEXF2VT[d["order_type"]], orderid=d["client_oid"], offset=offset, direction=direction, price=float(d["price"]), volume=float(d["size"]), traded=float(d["filled_qty"]), time=utc_to_local( d["timestamp"]).strftime("%Y-%m-%d %H:%M:%S.%fZ"), status=STATUS_OKEXF2VT[d["state"]], gateway_name=self.gateway_name, ) self.gateway.on_order(copy(order)) trade_volume = d.get("last_fill_qty", 0) if not trade_volume or float(trade_volume) == 0: return self.trade_count += 1 tradeid = f"futures{self.connect_time}{self.trade_count}" trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=tradeid, direction=order.direction, offset=order.offset, price=float(d["last_fill_px"]), volume=float(trade_volume), time=order.time, gateway_name=self.gateway_name, ) self.gateway.on_trade(copy(trade))
def on_order(self, data: dict) -> None: """""" direction = SIDE_OKEXO2VT[data["side"]] order = OrderData( symbol=data["instrument_id"], exchange=Exchange.OKEX, type=ORDERTYPE_OKEXO2VT[data["order_type"]], orderid=data["client_oid"], direction=direction, price=float(data["price"]), volume=float(data["size"]), traded=float(data["filled_qty"]), time=utc_to_local(data["timestamp"]).strftime("%H:%M:%S"), status=STATE_OKEXO2VT[data["state"]], gateway_name=self.gateway_name, ) self.gateway.on_order(copy(order)) trade_volume = data.get("last_fill_qty", 0) if not trade_volume or float(trade_volume) == 0: return self.trade_count += 1 tradeid = f"{self.connect_time}{self.trade_count}" trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=tradeid, direction=order.direction, offset=order.offset, price=float(data["last_fill_px"]), volume=float(trade_volume), time=order.time, gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def cross_limit_order(self): """ Cross limit order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.low_price short_cross_price = self.bar.high_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.ask_price_1 short_cross_price = self.tick.bid_price_1 long_best_price = long_cross_price short_best_price = short_cross_price for order in list(self.active_limit_orders.values()): # Push order update with status "not traded" (pending). if order.status == Status.SUBMITTING: order.status = Status.NOTTRADED self.strategy.on_order(order) # Check whether limit orders can be filled. long_cross = ( order.direction == Direction.LONG and order.price >= long_cross_price and long_cross_price > 0 ) short_cross = ( order.direction == Direction.SHORT and order.price <= short_cross_price and short_cross_price > 0 ) if not long_cross and not short_cross: continue # Push order udpate with status "all traded" (filled). order.traded = order.volume order.status = Status.ALLTRADED self.strategy.on_order(order) self.active_limit_orders.pop(order.vt_orderid) # Push trade update self.trade_count += 1 if long_cross: trade_price = min(order.price, long_best_price) pos_change = order.volume else: trade_price = max(order.price, short_best_price) pos_change = -order.volume 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.strategy.pos += pos_change self.strategy.on_trade(trade) self.trades[trade.vt_tradeid] = trade
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, ) 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)