def on_trade(self, d): """""" # Filter trade update with no trade volume and side (funding) if not d["lastQty"] or not d["side"]: return tradeid = d["execID"] if tradeid in self.trades: return self.trades.add(tradeid) if d["clOrdID"]: orderid = d["clOrdID"] else: orderid = d["orderID"] trade = TradeData( symbol=d["symbol"], exchange=Exchange.BITMEX, orderid=orderid, tradeid=tradeid, direction=DIRECTION_BITMEX2VT[d["side"]], price=d["lastPx"], volume=d["lastQty"], time=d["timestamp"][11:19], gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def onRtnTrade(self, data: dict): """ Callback of trade status update. """ symbol = data["InstrumentID"] exchange = symbol_exchange_map.get(symbol, "") if not exchange: self.trade_data.append(data) return orderid = self.sysid_orderid_map[data["OrderSysID"]] trade = TradeData( symbol=symbol, exchange=exchange, orderid=orderid, tradeid=data["TradeID"], direction=DIRECTION_CTP2VT[data["Direction"]], offset=OFFSET_CTP2VT[data["OffsetFlag"]], price=data["Price"], volume=data["Volume"], time=data["TradeTime"], gateway_name=self.gateway_name ) self.gateway.on_trade(trade)
def on_order(self, d): """""" 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, ) 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"{self.connect_time}{self.trade_count}" 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, data: dict): """""" sys_orderid = str(data["order-id"]) order = self.order_manager.get_order_with_sys_orderid(sys_orderid) if not order: self.order_manager.add_push_data(sys_orderid, data) return traded_volume = float(data["filled-amount"]) # Push order event order.traded += traded_volume order.status = STATUS_HUOBI2VT.get(data["order-state"], None) self.order_manager.on_order(order) # Push trade event if not traded_volume: return trade = TradeData( symbol=order.symbol, exchange=Exchange.HUOBI, orderid=order.orderid, tradeid=str(data["seq-id"]), direction=order.direction, price=float(data["price"]), volume=float(data["filled-amount"]), time=datetime.now().strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def OnTradeEvent(self, trade_info: XTPTradeReport, session_id: int) -> Any: """""" trade = TradeData(symbol=trade_info.ticker, exchange=MARKET_XTP2VT[trade_info.market], orderid=str(trade_info.order_xtp_id), tradeid=str(trade_info.exec_id), direction=DIRECTION_XTP2VT[trade_info.side], price=trade_info.price, volume=trade_info.quantity, time=trade_info.trade_time, 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 execDetails(self, reqId: int, contract: Contract, execution: Execution): # pylint: disable=invalid-name """ Callback of trade data update. """ super(IbApi, self).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, 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), time=self.generate_date_time(data[2]), gateway_name=self.gateway_name, ) self.gateway.on_trade(trade)
def on_order(self, d): """""" offset, direction = TYPE_OKEXF2VT[d["type"]] order = OrderData( symbol=d["instrument_id"], exchange=Exchange.OKEX, 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("%H:%M:%S"), status=STATUS_OKEXF2VT[d["status"]], 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"{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(trade)
def process_deal(self, data): """ Process trade data for both query and update. """ for ix, row in data.iterrows(): tradeid = str(row["deal_id"]) if tradeid in self.trades: continue self.trades.add(tradeid) symbol, exchange = convert_symbol_futu2vt(row["code"]) trade = TradeData( symbol=symbol, exchange=exchange, direction=DIRECTION_FUTU2VT[row["trd_side"]], tradeid=tradeid, orderid=row["order_id"], price=float(row["price"]), volume=row["qty"], time=row["create_time"].split(" ")[-1], gateway_name=self.gateway_name, ) self.on_trade(trade)
def on_query_trade(self, data, request): """""" if self.check_error(data, "查询成交"): return for d in data["data"]["trades"]: dt = datetime.fromtimestamp(d["create_date"] / 1000) time = dt.strftime("%H:%M:%S") trade = TradeData( tradeid=d["match_id"], orderid=d["order_id"], symbol=d["contract_code"], exchange=Exchange.HUOBI, price=d["trade_price"], volume=d["trade_volume"], direction=DIRECTION_HBDM2VT[d["direction"]], offset=OFFSET_HBDM2VT[d["offset"]], time=time, gateway_name=self.gateway_name, ) self.gateway.on_trade(trade) self.gateway.write_log(f"{request.extra}成交信息查询成功")
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)
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