订单簿数据获取:交易所API对接、WebSocket实时流、数据清洗与存储
做量化交易,尤其是做市商策略,数据就是你的血液。没有干净、实时的订单簿数据,再牛的模型也是空中楼阁。今天我们就来聊聊,怎么把这口「活水」引进来。
我个人习惯把数据获取分成三个层次:接口对接、实时流处理、清洗存储。每一层都有坑,踩过才知道疼。
一、交易所API对接:选对协议,少走弯路
大部分交易所都提供REST API和WebSocket两种接口。REST适合拉取历史快照,WebSocket适合订阅实时增量。
REST API 要点
- 限频控制:每个交易所的限频规则不同。币安是每分钟1200次权重,OKX是每秒60次。我建议你在代码里做一个本地计数器,超过阈值就sleep一下。
- 签名认证:私钥千万别硬编码在代码里。我用环境变量加载,或者用密钥管理服务。
- 错误重试:网络抖动是常态。我一般用指数退避策略,第一次等1秒,第二次等2秒,最多重试3次。
避坑指南:我曾经在对接某二线交易所时,发现它的REST接口返回的订单簿深度只有20档。后来仔细看文档,才发现需要传参limit=100。嗯,文档还是要读的。
WebSocket 要点
- 心跳维持:大部分交易所要求客户端每隔30秒发送ping帧。我习惯用一个定时器,每25秒发一次。
- 断线重连:WebSocket连接说断就断。我写了一个自动重连模块,检测到close事件后,等待5秒再重新订阅。
- 数据去重:有时候交易所会重复推送同一条消息。我根据
sequenceId或timestamp做去重,避免重复更新订单簿。
二、WebSocket实时流:增量更新才是王道
全量拉取订单簿太慢了,而且浪费带宽。真正做市商用的都是增量更新——只推送变化的部分。
举个例子,币安的深度流格式是这样的:
{
"e": "depthUpdate", // 事件类型
"E": 123456789, // 事件时间
"s": "BTCUSDT", // 交易对
"U": 157, // 第一更新ID
"u": 160, // 最后更新ID
"b": [ // 买单变化
["10000.00", "1.500"]
],
"a": [ // 卖单变化
["10001.00", "2.000"]
]
}
收到增量后,怎么合并到本地订单簿?我一般维护两个字典:bids和asks。key是价格,value是数量。如果数量为0,就删除这个档位。
小技巧:增量更新时,记得检查U和u的连续性。如果发现跳号,说明丢包了,需要重新拉一次全量快照。
为什么会丢包?说白了,网络拥堵或者交易所负载高。我遇到过几次,后来加了一个定时器,每5分钟强制拉一次全量快照做校准。
三、数据清洗:脏数据会要了你的命
你以为交易所推送的数据都是干净的?太天真了。我见过的情况包括:
- 价格异常:突然出现一个0.0001的价格,明显是撮合错误。
- 时间戳乱跳:某条消息的时间戳比上一条早了10秒。
- 重复推送:同一个更新ID出现两次。
我的清洗流程是这样的:
- 格式校验:检查字段类型是否正确,价格和数量是否为正数。
- 逻辑校验:买单价格必须小于卖单价格?不一定,但至少不能为负。
- 时间戳排序:按事件时间排序,丢弃明显乱序的数据。
- 去重:用
(交易对, 更新ID)作为唯一键。
注意:清洗后的数据一定要打上received_at时间戳,记录你本地收到的时间。这个字段在回测时非常有用,能帮你判断数据延迟。
四、数据存储:选对工具,事半功倍
订单簿数据量很大。一个热门交易对,每秒可能推送几十次更新。一天下来就是几百万条记录。
存储方案对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| CSV文件 | 小规模回测 | 简单、易读 | 查询慢、占用空间大 |
| SQLite | 单机分析 | 轻量、支持SQL | 并发写入差 |
| InfluxDB | 时序数据 | 写入快、压缩率高 | 学习成本高 |
| Parquet | 大规模分析 | 列式存储、查询快 | 不适合实时写入 |
我个人习惯用InfluxDB存实时数据,每天凌晨跑一个任务,把昨天的数据转成Parquet格式归档。这样既保证了实时查询的速度,又节省了存储成本。
五、整体架构图
下面这张图展示了从数据获取到存储的完整流程。你想想看,每一步都环环相扣,任何一个环节出问题,下游的策略都会受影响。
六、实战中的几个坑
最后分享几个我踩过的坑,希望能帮你省点时间。
- 时间戳陷阱:有些交易所返回的是毫秒级时间戳,有些是微秒级。我建议统一转成纳秒级存储,避免精度丢失。
- 内存泄漏:WebSocket客户端如果长时间运行,回调函数里如果持有大对象的引用,内存会慢慢涨。我习惯用弱引用或者手动清理。
- 磁盘写满:数据量大的时候,一天能写几十GB。我写了一个监控脚本,磁盘使用率超过80%就自动清理最早的数据。
核心总结:数据获取不是简单的「调个接口就完事」。从对接、清洗到存储,每一步都需要精心设计。尤其是做市商策略,对数据的实时性和准确性要求极高。记住一句话:垃圾数据进,垃圾策略出。