2. 订单簿数据结构与市场微结构基础

要重建订单簿历史并做一致性回测,第一步不是写撮合引擎,而是把“订单簿到底是什么、由哪些数据构成、按什么规则变化”这件事定义清楚。订单簿重建的所有误差,最终都会追溯到数据模型与撮合规则的理解偏差:把撤单当成成交、把市价单当成限价单、忽略价格时间优先,都会让重建出的盘口与真实市场系统性偏离。本节围绕限价订单簿的层次结构、订单类型、撮合规则与价格时间优先原则展开,目标是建立一套后续重建与回测共用的统一数据模型。

一、限价订单簿的层次结构

限价订单簿(Limit Order Book,LOB)本质上是按价格分档、档内按时间排序的双边队列集合。买侧(Bid)与卖侧(Ask)各自维护一组价格档位,每个档位挂着一个订单队列。对任一侧而言,价格越优的档位越靠近盘口:买侧价格越高越优,卖侧价格越低越优。最优买价(Best Bid)与最优卖价(Best Ask)之间的差额即买卖价差(Spread),两者构成盘口(Top of Book)。

从数据建模角度,一个档位至少需要两类信息:聚合层(该价位的总量、订单数)与明细层(该价位上每一笔订单的编号、数量、到达时间)。行情快照通常只给聚合层,逐笔委托(如 Add/Modify/Cancel/Trade 消息)才能还原明细层。重建订单簿时,明细层是“真相”,聚合层是“投影”;只有明细层正确,聚合层才可能一致。因此统一数据模型应以订单为最小实体,档位与盘口均由订单集合派生,而不是反过来。

限价订单簿:价格分档 + 档内时间优先 卖侧 Ask(价格由高到低) Ask3 10.06 × 300 Ask2 10.04 × 200 Ask1 10.02 × 150 价差 0.02 买侧 Bid(价格由高到低) Bid1 10.00 × 180 Bid2 9.98 × 260 Bid3 9.96 × 400 Bid1 档内队列(时间优先) #A01 10.00×80 #A02 10.00×60 #A03 10.00×40 ← 先到先撮合 新到卖单 S1:10.00 × 100(可成交) 先吃 #A01 的 80,再吃 #A02 的 20 撮合后状态 #A01 全部成交并移除 #A02 剩余 40,仍居队首 Bid1 总量 180 → 80

二、订单类型与生命周期

重建订单簿时最常遇到的订单类型包括:限价单(指定价格与数量,可立即成交部分、剩余挂单)、市价单(只指定数量,按对手方最优价逐档吃单,不进入订单簿)、IOC(立即成交剩余撤销)、FOK(全部立即成交否则整单撤销)、Post-Only(只做挂单,若会立即成交则拒单)。不同交易所对同一名称的语义可能有细微差异,重建前必须核对交易所规则文档,不能凭经验假设。

每笔订单在模型中应具备明确的生命周期状态:新建 → 部分成交 → 全部成交,或 新建 → 撤销,或 新建 → 部分成交 → 撤销。状态迁移必须由逐笔消息驱动,且每次迁移都要记录触发消息的序号与时间戳。这是后续“一致性”校验的锚点:任何时刻,订单簿中所有活动订单的数量之和,应等于对应档位聚合量;任何一笔成交,都应能对应到买卖双方订单数量的同步减少。

三、撮合规则与价格时间优先

连续竞价的核心规则是价格优先、时间优先:新到订单先与对手方最优价格档撮合;同一价格档内,先到达的订单先成交。以图中示例说明:买一档 10.00 有 #A01(80)、#A02(60)、#A03(40) 三笔订单,按到达顺序排队。此时新到卖单 S1 价格 10.00、数量 100,因卖价 10.00 ≤ 买一价 10.00,可立即成交。撮合按队列顺序进行:#A01 的 80 全部成交并移出队列,#A02 成交 20、剩余 40 仍居队首,买一档总量由 180 降为 80。若 S1 数量为 200,则 #A01、#A02 全部成交,#A03 成交 60 剩 0,买一价档位被清空,最优买价下移至 9.98。

这里有两个容易出错的细节。其一,成交价取被动方价格:S1 以 10.00 成交,是因为它吃的是挂在 10.00 的买单,而非以自身报价成交。其二,部分成交不改变时间优先级:剩余 40 的 #A02 仍排在 #A03 之前,重建时若把部分成交订单重新入队到队尾,就会破坏时间优先,导致后续回测的成交概率失真。

四、统一数据模型的关键字段

为了让重建与回测共用一套结构,建议以订单事件流为核心,定义如下最小字段集(示例为合理假设的字段设计,非某交易所实测格式):

字段含义示例
seq交易所消息序号,单调递增100237
ts事件时间戳(纳秒或毫秒,全文统一)1710000000123
type事件类型:ADD / CANCEL / TRADE / MODIFYADD
order_id订单唯一标识A02
side买卖方向BID
price限价(市价单为空)10.00
qty本次事件数量60
remaining事件后剩余量40

其中 seq 是重建顺序的唯一权威依据,ts 仅用于回测中的时间对齐与延迟建模。二者不可混用:同一毫秒内可能有多条消息,只有 seq 能确定真实先后。重建时应严格按 seq 回放,遇到序号缺口立即标记为数据不完整,而不是用时间戳猜测补全。

建模自检:任取一个快照时刻,验证“活动订单数量之和 = 各档位聚合量”“买一价 < 卖一价”“同档订单按到达时间单调排列”三条不变式。三条同时成立,才说明订单簿结构与撮合规则被正确实现。