3. 订单簿重建与盘口状态表示

逐笔消息(逐笔委托、逐笔成交)本身是离散的事件流,而盘口是这些事件累积后的“状态”。要在关键转折时刻做自动标注,第一步不是找信号,而是把事件流稳定地还原成一份可复用的盘口快照。本节围绕三件事展开:如何从逐笔消息重建限价订单簿、如何计算价差/深度不平衡/中间价等状态量、以及如何把这些状态量组织成特征快照供后续模型或规则使用。

一、重建的对象与基本约定

限价订单簿(LOB)本质是“价格 → 该价位挂单量”的有序映射,买侧按价格从高到低、卖侧按价格从低到高排列。重建的核心是维护两个有序结构(买簿、卖簿)以及一个按订单编号索引的订单表。订单表记录每笔挂单的订单号、方向、价格、剩余数量、所属档位,它是处理撤单和部分成交的关键——因为逐笔成交消息往往只带订单号,不带价格。

需要先明确几个约定,全文与图示保持一致:买一价为买簿最高价,卖一价为卖簿最低价;价差定义为卖一价减买一价,恒为非负;中间价为(买一价+卖一价)/2;深度不平衡以买侧前 N 档总量减卖侧前 N 档总量,再除以两侧总量之和,取值落在 [-1, 1],正值表示买方深度占优。N 通常取 5 或 10,需在快照中固定并记录,否则不同快照之间不可比。

二、逐笔消息的处理规则

重建过程对三类消息分别处理。新订单(限价委托)到达时,若为买方向,插入买簿对应价位并累加数量,同时在订单表登记;若价格穿越对手价(即可立即成交),真实撮合中会先成交剩余部分再挂单,重建时需按“先成交、后挂余量”的顺序处理,否则会出现短暂的交叉盘口。成交消息到达时,按订单号查订单表,扣减对应订单剩余量与该价位总量,剩余量为零则从订单表移除;若该价位总量归零,则删除该档。撤单消息到达时,同样按订单号定位,扣减数量并做归零清理。

这里最容易出错的是“价位总量”和“订单剩余量”两套计数必须同步维护。只更新价位总量而不更新订单表,撤单时就无法定位;只更新订单表而不清理空档,盘口会出现数量为零的“幽灵档位”,导致买一价、卖一价计算错误。建议在每次消息处理末尾做一次轻量校验:买一价必须小于卖一价(无交叉),且买一、卖一档位数量均大于零。

工程上常用“价格整数化”避免浮点误差:把价格乘以最小变动单位(如 0.01 元对应乘 100)后以整数作为有序结构的键,展示时再除回。这样价差、中间价的计算都是整数运算,结果稳定可复现。

三、状态量的计算与快照组织

每处理完一批消息(或按固定时间切片,如每 500 毫秒、每 100 笔消息),就生成一份快照。快照至少包含:时间戳、买一/卖一价与量、中间价、价差、前 N 档买卖总量、深度不平衡、以及最近窗口内的成交笔数与成交量。若用于转折标注,还应附带价差的滚动均值与当前价差相对均值的偏离,因为价差突然收窄或走阔往往先于价格转折出现。

下面给出一个可参考的快照字段与示例值(示例数据为教学假设,非实测):

字段含义示例值
ts快照时间戳(毫秒)093015500
bid1 / ask1买一价 / 卖一价10.02 / 10.03
spread价差(卖一减买一)0.01
mid中间价10.025
depth_bid5 / depth_ask5前 5 档买卖总量8200 / 5400
imb5深度不平衡(N=5)0.206
trade_cnt_win窗口内成交笔数37

以表中数据为例,imb5 = (8200 − 5400) / (8200 + 5400) ≈ 0.206,说明买方前五档深度明显占优;配合价差仅 0.01(一个最小变动单位),可判断为“买方承接较强、盘口偏紧”的状态。这类组合状态正是后续转折标注要捕捉的输入。

逐笔消息 → 订单簿重建 → 状态量 → 特征快照 逐笔消息流 新订单 成交 撤单 订单表 订单号 → 方向/价/量 撤单与部分成交定位 限价订单簿 买簿:价高→低 卖簿:价低→高 价位总量同步维护 状态量计算 价差 / 中间价 前 N 档深度 深度不平衡 imb 盘口特征快照(示例值,教学假设) bid1=10.02 ask1=10.03 spread=0.01 mid=10.025 depth_bid5=8200 depth_ask5=5400 imb5=(8200−5400)/(8200+5400)≈0.206 trade_cnt_win=37 → 状态判读:买方深度占优、价差偏紧 快照按固定时间切片或固定消息数生成,N 与窗口长度随快照记录,保证可比 订单表支撑撤单/成交定位

四、实现要点与常见坑

第一,消息顺序与去重。交易所逐笔消息通常带序号,重建前应按序号排序并检测缺口;出现缺口时该段快照应标记为“不完整”,不能直接用于标注,否则会把数据缺失误判为盘口突变。第二,时间切片的选择。切片过密会放大噪声,过疏会漏掉转折;对活跃标的可用固定消息数(如每 100 笔)切片,对清淡标的改用固定时间切片,并在快照中记录切片方式。第三,N 档深度的边界。当某一侧不足 N 档时,应按实际档数求和并在快照中标注实际档数,避免把“档位不足”误算成“深度很小”。

第四,快照的可复现性。同一段逐笔数据重放两次,快照序列必须完全一致。为此要固定:价格整数化方式、N 的取值、切片规则、窗口长度、以及浮点输出的精度(如统一保留 4 位小数)。把这些参数写入快照元数据,后续做转折标注时才能回溯“这个信号是在什么盘口状态下触发的”。

不要把“盘口快照”和“K 线”混用。K 线是区间聚合,盘口快照是某一时刻的挂单状态;转折标注需要的是后者提供的即时深度与价差信息,用 K 线收盘价替代会丢失买卖压力结构。

完成上述重建后,得到的就是一条按时间排列、字段固定、参数可追溯的快照序列。它既是盘口状态的表示,也是后续识别“关键转折时刻”的输入底座——价差骤变、深度不平衡翻转、中间价短时位移等特征,都可以直接在这条序列上计算与比对。