2. 限价订单簿数据解析

要检测“大额挂单快速撤回”,第一步不是写策略,而是把交易所推送的原始数据读懂、对齐、洗干净。限价订单簿(Limit Order Book,LOB)数据通常以两种形态出现:订单簿快照(snapshot)和逐笔委托/逐笔更新(tick-by-tick order / delta)。快照告诉你某一时刻盘口的“静态切片”,逐笔流告诉你两次快照之间“发生了什么”。大额挂单的挂出与撤回,往往只体现在逐笔流里,而快照只能看到结果,因此二者必须配合使用。

一、订单簿快照的数据结构

快照一般按“价格档位”组织,每档包含价格与数量,买卖两侧分开。以常见的 L2 快照为例,一条记录可抽象为如下字段:

{
  "symbol": "600000",
  "ts_exchange": 1717036800123,   // 交易所时间戳,毫秒
  "ts_local":    1717036800158,   // 本地接收时间戳
  "seq": 88213,                   // 快照序号
  "bids": [[10.01, 5200], [10.00, 18300], [9.99, 7600]],
  "asks": [[10.02, 4100], [10.03, 22500], [10.04, 9800]]
}

其中 bids 按价格从高到低排列,asks 从低到高排列,数组元素为 [价格, 数量]。数量单位需确认是“股”还是“手”,价格需确认是否已含最小变动价位(tick size)缩放。快照的关键字段含义:seq 用于判断快照是否连续、有无丢包;ts_exchange 是撮合系统打的时间,ts_local 是本地网卡收到的时间,两者之差即链路延迟,是后续判断“撤回是否异常快”的重要基准。

二、逐笔委托的数据结构

逐笔流按事件记录,每条对应一次委托进入、一次成交或一次撤单。典型字段如下:

{
  "symbol": "600000",
  "ts_exchange": 1717036800205,
  "seq": 88214,
  "order_id": "A7731",
  "side": "B",            // B 买 / S 卖
  "price": 10.01,
  "qty": 5000,
  "event": "NEW",         // NEW / TRADE / CANCEL
  "trade_id": null
}

这里 order_id 是贯穿委托生命周期的唯一标识:NEW 表示挂单进入,CANCEL 表示撤单,TRADE 表示成交。大额挂单快速撤回的核心识别逻辑,就是在逐笔流中寻找同一 order_id 的 NEW 与 CANCEL 事件,并计算二者时间差与挂单量。注意:部分交易所的撤单事件只带 order_id 而不重复价格数量,需回查该订单的 NEW 记录补全;也有交易所用“减量更新”而非独立撤单事件,解析时必须按数据源文档区分。

三、时间戳对齐

快照与逐笔流来自不同通道,时间基准可能不一致。对齐原则是:以交易所时间戳为主轴,本地时间戳仅用于延迟分析。若逐笔流带 seq,应先用序号连续性校验,再按 ts_exchange 将逐笔事件归入相邻两个快照之间。实践中常见问题是快照时间戳为“生成时刻”而逐笔为“撮合时刻”,二者存在毫秒级偏移,直接按时间戳排序可能把撤单排到挂单之前。稳妥做法是:先按 seq 排序重建事件序列,再用时间戳做辅助校验,发现 CANCEL 时间早于对应 NEW 时标记为异常记录而非直接丢弃。

快照与逐笔流的时间轴对齐与事件重建 t 快照 S1 快照 S2 快照 S3 NEW 5000 CANCEL NEW 3000 TRADE Δt = 撤单时刻 − 挂单时刻 解析要点 ① 以 seq 重建事件顺序,时间戳仅作辅助校验; ② 同一 order_id 的 NEW 与 CANCEL 配对,计算挂单量与存活时长; ③ 快照 S1→S2 之间若出现大额 NEW 后迅速 CANCEL,且 S2 盘口未体现该量,即为疑似快速撤回; ④ 时间戳倒挂(CANCEL 早于 NEW)标记异常,不直接丢弃。

四、数据质量检查方法

解析完成后必须做质量检查,否则后续统计会被脏数据污染。建议按以下顺序执行:

  • 序号连续性:检查 seq 是否跳号。跳号意味着丢包,需标记该区间并评估是否影响目标订单的配对。
  • 字段合法性:价格应为 tick size 的整数倍,数量应为正数且不超过单笔申报上限;side 只能是 B/S,event 只能是约定枚举值。
  • 订单生命周期完整性:每个 NEW 最终应有 TRADE、CANCEL 或仍存续三种归宿之一;出现“孤儿 CANCEL”(无对应 NEW)需回查是否跨文件、跨交易日。
  • 时间戳单调性:同一 order_id 的事件时间应非递减;全局时间戳出现大幅回退应检查是否混入了不同交易日或不同时钟源的数据。
  • 快照与逐笔一致性:用逐笔流重放构建订单簿,与官方快照逐档比对,若某档数量偏差超过阈值,说明解析或对齐有误。
教学示例:假设某订单 NEW 于 ts_exchange=1717036800205 挂出 5000 股,CANCEL 于 1717036800388 撤回,则存活时长约 183 毫秒。若设定“大额”阈值为 3000 股、“快速”阈值为 500 毫秒,则该订单同时满足两个条件,进入疑似事件池。上述数值为示例假设,实际阈值需结合标的流动性与交易所撮合节奏标定。
常见陷阱:部分数据源的撤单事件不携带价格与数量,若直接按撤单记录统计“撤回量”会得到零;正确做法是通过 order_id 关联回 NEW 记录取原始挂单量。另外,快照中的“档位数量”是聚合值,不能直接与单笔委托量比较,必须借助逐笔流还原单笔订单。

把上述结构、对齐与质检流程固化为解析管线后,才能稳定输出“订单号—挂单量—挂单时刻—撤单时刻—存活时长”的事件表,这正是后续大额挂单快速撤回检测的输入基础。