1. 课程导入与订单簿重建问题定义
在真实交易系统中,行情数据通常以两种形态出现:一种是交易所定时推送的快照(Snapshot),另一种是逐笔发生的事件流(Tick-by-Tick / Incremental Feed)。快照给出某一时刻盘口的完整切片,而逐笔事件只告诉你"发生了什么变化"——某价位新增了一笔委托、某笔委托被撤销、某笔成交吃掉了多少量。订单簿重建(Order Book Reconstruction)要解决的问题就是:从一串增量事件出发,在本地维护一份与交易所一致的、任意时刻可查询的限价订单簿。
本课程的学习目标可以概括为三个层次。第一层是理解语义:能准确区分新增、修改、撤销、成交四类事件对买卖盘的影响,理解价格优先、时间优先的撮合原则如何体现在事件序列中。第二层是实现重建:能用合适的数据结构(价格档位映射 + 档内订单队列)把事件流还原成盘口,并正确处理数量增减、档位删除、订单部分成交等边界情况。第三层是保证正确性:能设计校验机制,用快照对齐、序列号连续性检查、盘口交叉检测等手段发现并修复重建偏差。这三层目标贯穿全部 30 节,本节先把问题边界和整体路线讲清楚。
逐笔事件驱动重建的核心挑战
为什么不能简单地"收到一条事件就改一下数字"?因为真实事件流里藏着大量容易出错的细节。下面这张图把一次典型的重建过程拆成"事件输入—状态变更—一致性校验"三条并行关注点,标出了最容易出问题的环节:
图中左侧四类事件是重建的原料,中间是目标状态,右侧是保证状态可信的校验手段。实际工程中,最棘手的问题集中在三处。其一是事件乱序与重复:网络抖动或行情网关重连会导致事件到达顺序与交易所产生顺序不一致,必须依赖每条事件携带的序列号(Sequence Number)做排序与去重,一旦发现序号缺口,就要暂停应用并请求快照重同步,而不是"先凑合着用"。其二是成交事件的归属:一笔成交同时影响买卖双方,但逐笔行情往往只推送主动方或只推送被动方,需要根据成交价与当时盘口判断它消耗的是哪一侧的档位,否则会把数量减错方向。其三是档位生命周期:某价位数量减到零时必须从盘口中删除该档,否则会出现"幽灵档位",导致后续价差计算和盘口交叉检测全部失真。
整体实战路线图
本课程按"先建骨架、再补血肉、最后上强度"的顺序推进。第一阶段聚焦数据结构与基础事件处理:定义订单对象、价格档位、买卖盘容器,实现新增与撤销两类最基础的事件,并用构造的小样本事件流验证盘口形态。第二阶段进入成交与修改事件:处理部分成交、完全成交、减量修改与改价重排,重点讲清楚"改价等于撤销加新增"这一语义在队列中的体现。第三阶段是工程化与正确性:引入序列号管理、快照对齐、增量与全量的切换策略,并搭建一套可复现的校验流程。第四阶段做性能与实战演练:在较大规模事件流下考察重建吞吐与内存占用,分析热点路径,最后用一个完整的端到端案例把前面所有环节串起来。
为了让"重建是否正确"有可操作的判断依据,课程会反复使用一个简单的对照方法:给定一段事件流和一份该时段结束时的官方快照,重建完成后逐档比较价格与数量。下面是一个教学用的示例片段,展示事件流与期望盘口的对应关系(数据为构造的示例,非真实行情):
事件流(示例):
seq=1 Add Bid 10.00 x 600
seq=2 Add Bid 10.00 x 400
seq=3 Add Ask 10.01 x 800
seq=4 Trade 10.00 x 300 # 成交消耗买盘 10.00 档
seq=5 Cancel Bid 10.00 x 200 # 撤销该档中较早订单的剩余部分
重建后买盘 10.00 档应为:600 + 400 - 300 - 200 = 500
若结果不等于 500,说明成交归属或撤销量处理有误。
这个例子虽小,却覆盖了本节强调的全部要点:同价位多笔订单要累加、成交要扣减正确的一侧、撤销要扣减指定订单的剩余量。把这类小样本跑通,再逐步放大到真实事件流,是整门课推荐的推进节奏。接下来各节将围绕这条路线,逐层展开实现细节与验证方法。