2. 逐笔事件类型解析

逐笔重建订单簿的第一步,不是写代码,而是把交易所推送的每一条事件“翻译”成对订单簿状态的确定性影响。同一条消息,字段读错一个,重建出的盘口就可能整体偏移。本节围绕新增订单、撤单、成交、订单修改四类核心事件,逐项拆解字段含义,并重点说明那些“看起来相似、语义却完全不同”的差异点。

一、四类事件的语义定位

可以把订单簿看作一个由订单ID索引的状态机,每类事件都是对状态机的一次操作:新增订单是插入一条新记录并占用对应价位的流动性;撤单是删除记录并释放流动性;成交是减少记录中的剩余数量,可能部分成交也可能全部成交;订单修改则是对已有记录的数量或价格做变更,往往等价于“先撤后增”。理解这四种操作的差异,是保证重建结果与交易所快照一致的前提。

需要特别强调的是:事件类型不能只看消息名称,而要看字段组合。例如某些行情源把“成交”和“撤单”合并为同一条“订单删除”消息,此时必须结合“是否有成交量字段”“剩余数量是否归零”来判断真实语义。

逐笔事件 → 订单簿状态变更映射 订单簿状态 order_id → {价格, 剩余量, 方向} 价位聚合 → 深度档位 (以订单ID为主键的映射表) 新增订单 Add order_id / 方向 / 价格 数量 / 时间戳 → 插入记录,占用流动性 撤单 Cancel order_id / 撤单数量 (部分撤单需保留剩余) → 删除记录,释放流动性 成交 Trade maker_order_id / 成交量 成交价 / 方向 → 扣减剩余量,可能归零 订单修改 Modify order_id / 新价格 新数量 / 优先级变化 → 等价“先撤后增” 关键差异:成交与撤单都减少数量,但成交有对手方与成交价,撤单没有 修改若改变价格,原订单优先级失效,须按新单重新排队

二、新增订单:字段与陷阱

新增订单事件通常携带 order_id、side(买/卖)、price、quantity、timestamp。重建时要做三件事:以 order_id 为键写入映射表;按 side 和 price 定位到对应价位;把 quantity 累加到该价位的总量上。这里最常见的错误是把“订单数量”当成“增量”——新增订单的数量是该订单的初始总量,不是相对上一状态的差值。

另一个陷阱是价格精度与方向约定。若交易所用整数表示价格(如以 0.01 元为单位),重建时必须统一换算,否则同一价位会被拆成多个档位。方向字段也要确认:有的源用 1/2 表示买卖,有的用 B/S,混用会导致买卖盘颠倒。

三、撤单:部分撤单与全量撤单

撤单事件至少包含 order_id 和撤单数量。若撤单数量等于该订单当前剩余量,则删除记录;若小于剩余量,则是部分撤单,必须保留记录并扣减数量。很多实现只处理“全撤”,遇到部分撤单直接删除订单,结果盘口深度偏薄。判断依据应写成:剩余量 -= 撤单量;若剩余量 == 0 则删除。

还要注意“撤单”与“成交导致的删除”在消息层面的区别:撤单没有成交价和对手方,成交则有。若行情源把两者合并为“订单删除”,就必须依赖成交量字段是否大于零来区分。

四、成交:扣减剩余量而非删除

成交事件的关键字段是 maker_order_id(被动方订单)、trade_price、trade_quantity。重建时只应扣减被动方订单的剩余量,主动方订单通常已通过新增/撤单事件体现,重复处理会导致数量被扣两次。若 trade_quantity 等于剩余量,订单归零并删除;否则保留并更新数量。

成交价与订单原价可能不同(价格改善),但订单簿中该订单仍挂在原价位,直到数量归零。这一点常被误解为“成交后订单立即移到成交价”,实际并非如此。

五、订单修改:最容易被低估的事件

订单修改事件携带 order_id 及新价格或新数量。语义上它等价于“撤销原订单 + 以新参数新增订单”。若只改数量而不改价格,订单在原价位保留但优先级可能重置;若改了价格,则必须从原价位移除、在新价位插入。实现上建议统一走“先按撤单处理,再按新增处理”的路径,避免遗漏价位聚合的更新。

若把“修改数量”简单当作“成交扣减”,会把主动调整误判为成交,导致成交量统计与盘口深度同时出错。修改事件必须与成交事件分开处理。

六、字段语义对照速查

事件核心字段对订单簿的操作常见误判
新增order_id、side、price、quantity插入记录,价位总量增加把 quantity 当增量
撤单order_id、cancel_qty扣减剩余量,归零则删除忽略部分撤单
成交maker_order_id、trade_qty、trade_price扣减被动方剩余量重复扣减主动方
修改order_id、new_price、new_qty先撤后增,更新价位当作成交处理

把上述四类事件的字段含义与操作语义固化为重建逻辑的分支判断,后续再叠加时间戳排序与快照校验,才能保证逐笔重建的订单簿在任意时刻都与交易所一致。