🚀 AI 一键生成 qmt 策略代码
立即体验
👉 AI 生成代码 👈

QMT 平台 L2 数据丢包无法正确构建订单簿怎么办?

qmt | 发布时间: 2026/6/2
以下内容由 EasyQuant 生成。

问题描述

L2数据丢包无法正确构建订单簿咋办

版主好:

构建订单簿时,如果出现逐笔委托和逐笔成交丢数据的现象就无法正确还原订单簿。以今天 600686 为例:正确的十档如下:

解决方案

在量化交易中,利用 Level2 (L2) 数据(逐笔委托和逐笔成交)构建高精度的订单簿是许多高频和微观结构策略的基础。然而,由于网络延迟、系统负载或数据源本身的问题,L2 数据丢包是一个常见且棘手的问题。当发生丢包时,基于增量更新的订单簿就会出现偏差,导致策略做出错误的交易决策。

针对 QMT 平台上 L2 数据丢包导致订单簿构建失败的问题,可以采取以下几种策略来应对和修复:

1. 定期使用快照数据进行校准 (Snapshot Calibration)

这是最常用且最有效的解决方案。虽然逐笔数据(Tick-by-Tick)用于实时更新订单簿,但交易所也会定期发送行情快照(Snapshot,例如每 3 秒一次的十档行情)。

  • 机制:在接收逐笔数据的同时,订阅并接收快照数据。
  • 校准逻辑:每当收到一个新的快照时,将其与当前通过逐笔数据构建的内部订单簿进行比对。如果发现不一致(例如价格档位缺失、数量不匹配),则以快照数据为准,强制覆盖和重置内部订单簿。
  • QMT 实现:在 QMT 中,你可以同时订阅 tick(分笔数据,包含快照信息)和 L2 的逐笔数据。利用 ContextInfo.get_full_tick() 或订阅回调中的快照信息来定期修正你的订单簿状态。

2. 序列号检测与断线重连 (Sequence Number Tracking)

高质量的 L2 数据流通常会为每条逐笔委托和逐笔成交分配一个连续的序列号(Sequence Number)。

  • 机制:在处理每条逐笔数据时,检查其序列号是否与上一条连续。
  • 处理丢包:如果发现序列号跳跃(例如收到了 100,下一条是 105),则明确知道发生了丢包。
  • 应对措施
    • 短时间容忍:如果丢包数量很少,且策略对极短期精度要求不高,可以等待下一个快照到来进行自动修复。
    • 主动重置:一旦检测到丢包,立即将内部订单簿标记为“不可信”状态,暂停基于订单簿的交易信号生成,直到下一个完整的快照数据到来并完成重置。
    • 请求重传:某些高级数据接口支持根据序列号请求重传丢失的数据包(QMT 平台具体是否支持需参考其底层数据接口文档,通常普通 API 不提供此功能)。

3. 订单簿合理性校验 (Sanity Checks)

即使没有序列号,也可以通过一些逻辑规则来判断订单簿是否出现了严重错误。

  • 价格交叉:买一价(Bid 1)大于或等于卖一价(Ask 1)。在正常的连续竞价阶段,这是不可能发生的(除非是特殊的撮合机制)。如果出现,说明订单簿已损坏。
  • 负数量:某个价格档位的委托数量变为负数。这通常是因为丢失了该档位的初始委托单,但收到了后续的撤单或成交单。
  • 极端价格偏离:订单簿中出现了偏离当前市场价格极大的异常委托,且长时间未被清理。
  • 应对:一旦触发这些合理性校验失败,立即清空当前订单簿,并等待下一个快照数据进行重建。

4. 优化网络和系统环境

减少丢包的根本方法是优化接收端的基础设施。

  • 网络连接:确保运行 QMT 的服务器或本地机器拥有稳定、低延迟的网络连接。尽量使用有线网络而非无线网络。
  • 系统负载:L2 数据量巨大,处理逐笔数据需要消耗大量的 CPU 和内存资源。确保你的 Python 策略代码足够高效(例如使用 NumpyCython 优化核心计算逻辑),避免因处理不过来导致接收缓冲区溢出而丢包。
  • 独立进程:如果可能,将数据接收和订单簿构建逻辑放在一个独立的线程或进程中,与策略计算和下单逻辑分离,以提高数据处理的实时性。

总结建议

在 QMT 平台中,最务实的做法是结合逐笔数据和快照数据。以逐笔数据驱动订单簿的实时微小变动,以快照数据作为“锚点”进行定期强制校准。当检测到订单簿异常(如价格交叉或负数量)时,立即停止交易并等待快照重置。这样可以在保证一定实时性的同时,最大程度地降低丢包带来的风险。