2、盘口数据获取:WebSocket实时订阅、REST API快照拉取、数据清洗与对齐
做市策略跑起来,第一件事就是搞定数据。数据拿不到,或者拿不准,后面全是白搭。我个人习惯把盘口数据获取拆成三个环节:实时流、快照、清洗对齐。咱们一个一个说。
2.1 WebSocket 实时订阅:别让行情溜走
做市嘛,拼的就是速度。REST API 轮询?太慢了。你想想看,一秒拉一次,中间几十笔成交你都看不见。所以必须上 WebSocket。
WebSocket 建立连接后,交易所会持续推送订单簿的增量更新。比如币安的 depth 频道,每次推送只告诉你「价格 100.05 的买单数量变了,从 10 变成 12」。你本地维护一个订单簿,收到增量就往上叠。
我在项目中遇到过一个问题:某次网络抖动,增量丢了几条,结果本地订单簿跟交易所对不上了。后来怎么解决的?每隔 5 分钟强制拉一次快照做校验,发现偏差超过阈值就重置。
// 伪代码示例:WebSocket 订阅 + 本地维护
ws.on('message', (data) => {
if (data.type === 'snapshot') {
localOrderBook = buildFromSnapshot(data);
} else if (data.type === 'delta') {
applyDelta(localOrderBook, data);
// 校验:检查 best bid/ask 是否合理
if (!validate(localOrderBook)) {
requestSnapshot(); // 出错了,重新拉快照
}
}
});
2.2 REST API 快照拉取:打地基
WebSocket 增量是「装修」,REST API 快照就是「地基」。每次启动策略,或者发现数据不一致时,都得先拉一次全量快照。
快照拉取有几个坑,我踩过,你注意一下:
- 频率限制: 交易所对 REST API 有调用限制。比如币安每分钟 1200 次权重。你如果每 5 秒拉一次,很快就封了。
- 数据延迟: REST API 返回的快照可能比实时行情慢几百毫秒。所以拉完快照后,要跟 WebSocket 的最新时间戳对齐。
- 深度级别: 有些交易所的快照只返回前 100 档。做市策略通常需要全量深度,你得确认清楚。
我曾经因为没注意频率限制,被交易所 ban 了 IP 整整 5 分钟。那 5 分钟里策略完全瞎了,亏了不少。后来我加了个限流器,每次拉取前检查一下配额。
2.3 数据清洗与对齐:脏数据是魔鬼
数据拿到手了,你以为就能直接用?太天真了。交易所推送的数据经常有脏数据。我总结了几类常见问题:
| 问题类型 | 表现 | 处理方式 |
|---|---|---|
| 重复推送 | 同一笔增量发了两遍 | 用 sequence ID 去重 |
| 乱序到达 | 后发的增量先到 | 缓存排序,按 sequence 顺序应用 |
| 价格异常 | 出现 0 或负数价格 | 直接丢弃,触发快照校验 |
| 数量溢出 | 挂单数量超过合理范围 | 设定上下限,超限则报警 |
数据对齐这块,说白了就是让「本地订单簿」和「交易所订单簿」保持一致。我常用的方法是:
- 每次收到增量,先检查 sequence ID 是否连续。不连续?说明丢了数据,立刻拉快照。
- 每 30 秒主动拉一次快照做全量校验。偏差超过 0.1% 就重置。
- 记录每次对齐的时间戳和偏差值,方便事后复盘。
2.4 整体流程:一张图说清楚
嗯,这里我画了一张流程图,把上面说的串起来。你看一眼就明白了。
你看这个流程,WebSocket 和 REST API 两条线并行,最终汇聚到数据清洗模块。清洗完的数据才能喂给做市策略。反馈回路也很重要——一旦发现数据对不上,立刻触发重新拉取。
好了,盘口数据获取这块就聊到这儿。记住一句话:数据质量决定策略上限。你花再多时间在数据清洗上都不为过。