4. 盘口快照与逐笔成交的时间对齐方法

盘口快照(Level-1/Level-2 行情切片)与逐笔成交是两类采样机制完全不同的数据:快照按固定频率(如每 3 秒、每 500 毫秒)推送一次市场状态,逐笔成交则在每笔撮合发生时异步推送。做盘口策略时,我们往往需要回答“这笔成交发生时,盘口长什么样”,或者“这个盘口状态下,接下来几秒成交如何分布”。要回答这类问题,就必须把两条时间轴对齐到同一参照系上。本节讨论三种常用对齐策略——最近邻、线性插值、前向填充——以及各自的适用边界与典型陷阱。

先统一时间参照系

对齐前必须先明确时间戳的语义。交易所行情通常带两类时间:交易所撮合时间(exchange timestamp)与本地接收时间(local receive timestamp)。前者是事件真实发生时刻,后者包含网络与排队延迟。做防泄漏对齐时,应统一使用交易所时间作为对齐基准,本地时间只用于监控延迟和判断数据完整性。若快照与逐笔来自不同通道、时间戳精度不同(如一个到毫秒、一个到秒),需先统一精度,通常向下取整到较粗粒度,并记录取整带来的最大误差。

另一个约定是“对齐方向”。本节统一采用:以逐笔成交事件为查询点,在快照序列中寻找其对应的盘口状态。这意味着对每笔成交 t,我们要从快照集合中选出一个代表该时刻的盘口。三种策略的差别,就在于“选哪个”以及“是否合成”。

三种对齐策略在快照间隔内的取值方式 t 时间 → 快照 S1 快照 S2 快照 S3 成交 T 最近邻 |T−S1|=150 |T−S2|=150 等距时须定规则(如取前向) 线性插值 按 (T−S1)/(S2−S1)=0.5 加权合成盘口 前向填充 T 取 S1 的盘口(不引入未来信息)

最近邻:简单但有方向性风险

最近邻的做法是:对成交时刻 t,在快照序列中找时间距离最近的一个快照,直接使用其盘口。实现上可用二分查找定位前后两个快照,再比较距离。它的优点是实现简单、不引入合成值,盘口字段(买卖价、量、档位)保持真实。但有两个边界必须注意。

第一是等距歧义。当 t 恰好位于两个快照中点时,前后距离相等,必须显式规定取前还是取后。若默认取后(未来快照),就引入了未来信息,属于典型泄漏。建议规则固定为“等距取前向”,并在代码中写死。第二是方向性偏差。若快照间隔为 3 秒,最近邻可能取到 t 之后最多 1.5 秒的快照,这段“未来盘口”在回测中会高估策略反应速度。因此最近邻更适合快照频率高(如 500 毫秒以内)、且策略对盘口变化不敏感的场景。

线性插值:平滑但可能造出“不存在的盘口”

线性插值对前后两个快照的数值字段按时间比例加权。设 t 位于 S1、S2 之间,权重 w=(t−t1)/(t2−t1),则插值价 = P1 + w·(P2−P1),量同理。它给出连续、平滑的盘口估计,适合研究价格与盘口深度的连续关系。

但插值有两个陷阱。其一,盘口是离散且有序的:买卖价、档位量插值后可能得到“买一价 10.005”这类现实中不存在的价位,甚至出现买价高于卖价的交叉。若策略依赖价差或档位判断,插值结果会失真。其二,插值使用了未来快照 S2,在 t 时刻实际不可得,严格回测中属于前视偏差。若必须用插值,应改为“仅用 S1 与历史趋势外推”,或明确接受这一近似并在报告中标注。插值更适合离线研究、特征平滑,不适合对时序严格性要求高的实盘回测。

前向填充:防泄漏的首选

前向填充(forward fill)对成交 t 取“时间戳不大于 t 的最近一个快照”,即只用过去信息。它天然无前视偏差,盘口字段保持真实,是盘口策略回测中最稳妥的默认策略。实现时用 merge_asof(direction='backward') 一类操作即可完成。

它的边界在于陈旧度。若某快照缺失或停推,前向填充会把旧盘口一直沿用,导致成交对应到几秒甚至几十秒前的状态。因此必须设置最大容忍间隔(如不超过 2 个快照周期),超限则标记为无效样本而非强行填充。此外,开盘集合竞价、午间休市前后快照稀疏,前向填充的误差会明显放大,应单独处理。

策略选择与陷阱清单

策略是否用未来信息盘口真实性适用边界
最近邻可能(取后向时)真实高频快照、低敏感策略
线性插值是(用 S2)可能失真离线研究、特征平滑
前向填充否真实回测默认、防泄漏优先
常见陷阱:① 用本地接收时间对齐,把网络延迟当成市场变化;② 等距时默认取后向快照,引入前视;③ 前向填充不设陈旧上限,把停推数据当有效样本;④ 插值后未检查买卖价交叉;⑤ 快照与逐笔时间精度不一致却直接比较。

实践中推荐组合使用:以前向填充为主保证无泄漏,同时记录每笔成交对应的“快照年龄”(t 与所用快照的时间差),把年龄超过阈值的样本剔除或降权。这样既守住防泄漏底线,又能通过年龄分布观察数据质量,为后续特征工程和回测可信度提供依据。