2. 数据源接入:交易所API、第三方数据商与WebSocket
好,咱们进入第二章。数据源接入,说白了就是解决一个问题——Tick数据从哪来。
我个人习惯把数据源分成三类:交易所直连、第三方数据商、WebSocket流式推送。这三条路我都走过,各有各的坑。今天我把它们掰开揉碎了讲清楚。
2.1 交易所API:最原始,也最折腾
先聊交易所直连。这是最正统的方式,也是我最早接触的方式。
交易所API通常提供两种接口:REST和WebSocket。REST用来拉历史数据,WebSocket用来收实时行情。
举个例子,币安的REST接口长这样:
GET /api/v3/klines?symbol=BTCUSDT&interval=1m&limit=1000
返回的是K线数据。但你要Tick数据?抱歉,大部分交易所不直接给。你得自己从深度快照里算。
所以,接入交易所API时,我建议你做好三件事:
- 限流器:用令牌桶算法控制请求频率
- 重试机制:网络抖动是常态,指数退避重试是标配
- 数据校验:交易所返回的数据偶尔会丢字段,校验不能省
2.2 第三方数据商:花钱买省心
如果你不想跟交易所的API死磕,第三方数据商是个好选择。
市面上主流的几家:
| 数据商 | 覆盖市场 | 数据精度 | 价格 |
|---|---|---|---|
| 彭博 | 全球股票、期货、外汇 | Tick级 | 贵到离谱 |
| 路透 | 全球股票、期货、外汇 | Tick级 | 也很贵 |
| 聚宽 | A股、期货 | 分钟级 | 中等 |
| CoinGecko | 加密货币 | 分钟级 | 免费/付费 |
第三方数据商的好处是数据干净、格式统一。你想想看,交易所的字段命名五花八门,有的叫lastPrice,有的叫close,有的叫tradePrice。第三方帮你做了标准化。
但坏处也很明显——延迟。数据从交易所到数据商,再到你手里,中间至少多了一跳。做高频交易的话,这几十毫秒的延迟可能让你亏掉裤子。
2.3 WebSocket:实时推送的王者
WebSocket是目前实时数据推送的主流方案。为什么?因为它解决了HTTP轮询的低效问题。
HTTP轮询是客户端每隔几秒问一次「有新数据吗?」,WebSocket是服务端主动说「有新数据了,给你」。
一个典型的WebSocket连接代码:
import websocket
def on_message(ws, message):
# 收到Tick数据
tick = parse_tick(message)
save_to_buffer(tick)
def on_error(ws, error):
# 断线重连
reconnect()
ws = websocket.WebSocketApp(
"wss://stream.binance.com:9443/ws/btcusdt@trade",
on_message=on_message,
on_error=on_error
)
ws.run_forever()
这段代码看起来简单,但实际生产环境里,坑多着呢。
我曾经遇到过一个问题:WebSocket连接在凌晨3点准时断开,查了三天才发现是云服务商的NAT超时设置。嗯,这种问题你光看代码是看不出来的。
2.4 数据源接入的核心架构
说了这么多,咱们画张图把整体逻辑串起来。
这张图里,数据从左边三个源头进来,经过接入层处理,进入内存缓冲,最后落地到持久化存储。每个环节都有讲究。
2.5 接入层的三个关键点
接入层是数据源和存储之间的桥梁。我总结三个关键点:
- 协议适配:不同数据源协议不同,REST、WebSocket、FIX协议...你得写适配器把它们统一成内部格式。
- 断线重连:WebSocket断线是家常便饭。我建议用指数退避策略,第一次等1秒,第二次等2秒,第三次等4秒...最大间隔别超过5分钟。
- 数据去重:同一个Tick可能从多个数据源收到,或者因为重连重复推送。你得用时间戳+交易ID做唯一键去重。
核心原则: 接入层要做到「不丢数据、不重复数据、不乱序数据」。这三点做到,后面的存储和计算就轻松了。
2.6 实战中的避坑指南
最后,分享几个我踩过的坑:
- 时间戳问题:交易所返回的时间戳是UTC还是本地时间?我见过有人直接用本地时间存,结果回测时数据对不上。统一用UTC+0存储。
- 数据缺失:交易所偶尔会丢Tick。我建议用心跳包检测,如果超过5秒没收到数据,主动发一个ping。
- 内存泄漏:WebSocket的on_message回调里如果处理太慢,消息会堆积在内存里。用异步处理或者背压机制解决。
我曾经在接入火币的WebSocket时,发现连接会在每天下午4点准时断开。查了日志才发现是火币的服务器端主动断开,原因是我的订阅频道数超过了限制。嗯,这种问题不看文档是永远猜不到的。
好了,数据源接入这块就聊到这。记住一句话:数据源是量化系统的命门,接入层是数据源的第一道防线。把这道防线守住了,后面的工作才能顺利展开。