2、数据源接入:REST API vs WebSocket,如何选择?
做量化交易,第一步就是搞定数据源。说白了,你得先有数据,才能谈策略、谈回测、谈实盘。
我个人习惯,在搭建行情系统时,最先纠结的就是:到底用 REST API 还是 WebSocket?
这个问题,我当年刚入行时也踩过坑。有一次,我图省事,全用 REST 去拉深度数据,结果策略跑起来,滑点大得吓人。后来换成 WebSocket,才把问题解决。嗯,这里面的门道,咱们今天好好聊聊。
2.1 两种协议的本质区别
先看一张图,帮你快速建立直观印象:
REST API 就像打电话——你拨一次号,问一句,对方答一句,然后挂断。下次想问,再拨一次。
WebSocket 呢?更像对讲机。你接通频道后,对方可以随时跟你说话,你也能随时回复。通道一直开着。
你想想看,做高频交易或者盯盘,哪种方式更合适?答案很明显。
2.2 什么时候用 REST API?
REST 虽然「老」,但绝不是没用。我在项目中遇到过不少场景,REST 反而是最佳选择。
| 场景 | 说明 |
|---|---|
| 历史数据拉取 | 比如你要下载过去一年的 K 线数据做回测。一次请求,拿到全部数据,完事。 |
| 低频查询 | 每隔几分钟查一次账户余额、持仓情况。没必要保持长连接。 |
| 下单操作 | 下单、撤单这种操作,用 REST 更安全。一次请求一次确认,不容易出错。 |
| 系统初始化 | 程序启动时,先通过 REST 拉一次全量数据,再切到 WebSocket 做增量更新。 |
💡 我的小技巧: 我习惯在系统启动时,先用 REST 拉一次全量深度数据,然后立刻建立 WebSocket 连接。这样既拿到了完整快照,又能实时更新。两全其美。
2.3 什么时候必须用 WebSocket?
说白了,只要你对「实时性」有要求,WebSocket 就是唯一选择。
为什么会这样?我给你算笔账:
- 延迟对比: REST 每次请求都要经历 TCP 握手、HTTP 头部传输、服务端处理、响应返回。一轮下来,少说几十毫秒。而 WebSocket 建立连接后,数据推送延迟通常在 1-5 毫秒。
- 带宽浪费: REST 每次请求都带着几百字节的 HTTP 头部。如果你每秒请求一次,光头部就浪费大量带宽。WebSocket 的帧头部只有 2-14 字节。
- 服务器压力: 高频轮询 REST 接口,交易所那边很容易把你 IP 封了。我见过有人每秒请求 10 次,结果被交易所拉黑三天。
⚠️ 核心结论: 如果你做的是 tick 级行情、深度快照、实时成交推送,必须用 WebSocket。用 REST 做实时行情,基本等于自废武功。
2.4 实战中的混合方案
在实际项目中,我很少只用一种协议。大多数时候,是 REST + WebSocket 混合使用。
给你看一个我常用的架构:
// 伪代码:混合方案示例
class MarketDataEngine {
constructor() {
this.restClient = new RestClient();
this.wsClient = new WebSocketClient();
this.orderBook = {}; // 本地维护的深度数据
}
async init() {
// 第一步:REST 拉取全量快照
const snapshot = await this.restClient.getOrderBook('BTCUSDT');
this.orderBook = snapshot;
console.log('全量快照加载完成');
// 第二步:WebSocket 订阅增量更新
this.wsClient.subscribe('depthUpdate', (data) => {
this.applyUpdate(data); // 增量更新本地深度
});
console.log('WebSocket 增量订阅已启动');
}
applyUpdate(data) {
// 用增量数据更新本地 orderBook
// 这里处理 bids 和 asks 的增删改
}
}
这个方案的好处很明显:
- 启动时用 REST 拿到完整数据,避免 WebSocket 重连后数据不一致
- 运行中用 WebSocket 做增量更新,延迟极低
- 即使 WebSocket 断线重连,也只需要重新拉一次快照,不会丢数据
🚨 避坑指南: 我曾经犯过一个错误——只依赖 WebSocket 的增量更新,没有定期用 REST 做全量校验。结果有一次 WebSocket 推送丢了一条数据,导致我的深度数据一直错位,策略亏了不少钱。后来我加了一个定时任务,每 5 分钟用 REST 拉一次全量快照做校验。嗯,这个坑你们别踩。
2.5 选型决策表
最后,给你一张决策表。遇到具体场景时,直接对照着选就行:
| 需求场景 | 推荐协议 | 理由 |
|---|---|---|
| 拉取历史 K 线 | REST | 一次性请求,数据量大,不需要实时 |
| 实时 tick 行情 | WebSocket | 延迟要求毫秒级,必须推送 |
| 深度快照(全量) | REST | 启动时拉取,保证数据完整 |
| 深度增量更新 | WebSocket | 实时性要求高,增量数据小 |
| 下单/撤单 | REST | 一次一确认,安全可靠 |
| 成交推送 | WebSocket | 需要第一时间知道成交结果 |
| 账户余额查询 | REST | 低频操作,没必要长连接 |
总结一下我的经验:REST 管「全量」和「低频」,WebSocket 管「增量」和「实时」。两者配合,才是做行情系统的最佳姿势。
下一节,咱们聊聊具体怎么搭建 WebSocket 连接,以及如何处理断线重连。嗯,那又是一个值得细说的坑。