撮合成交
载入CTA策略以及相关历史数据后,策略会根据最新的数据来计算相关指标。若符合条件会生成交易信号,发出具体委托(buy/sell/short/cover),并且在下一根K线成交。
根据委托类型的不同,回测引擎提供2种撮合成交机制来尽量模仿真实交易环节:
限价单撮合成交:(以买入方向为例)先确定是否发生成交,成交标准为委托价>= 下一根K线的最低价;然后确定成交价格,成交价格为委托价与下一根K线开盘价的最小值。
停止单撮合成交:(以买入方向为例)先确定是否发生成交,成交标准为委托价<= 下一根K线的最高价;然后确定成交价格,成交价格为委托价与下一根K线开盘价的最大值。
下面展示在引擎中限价单撮合成交的流程:
确定会撮合成交的价格;
遍历限价单字典中的所有限价单,推送委托进入未成交队列的更新状态;
判断成交状态,若出现成交,推送成交数据和委托数据;
从字典中删除已成交的限价单。
- 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