2、数据源接入:REST API vs WebSocket,如何选择?

做量化交易,第一步就是搞定数据源。说白了,你得先有数据,才能谈策略、谈回测、谈实盘。

我个人习惯,在搭建行情系统时,最先纠结的就是:到底用 REST API 还是 WebSocket?

这个问题,我当年刚入行时也踩过坑。有一次,我图省事,全用 REST 去拉深度数据,结果策略跑起来,滑点大得吓人。后来换成 WebSocket,才把问题解决。嗯,这里面的门道,咱们今天好好聊聊。

2.1 两种协议的本质区别

先看一张图,帮你快速建立直观印象:

REST API 客户端 请求 服务器 响应 特点: • 一问一答模式 • 短连接,用完即断 • 适合低频查询 WebSocket 客户端 握手连接 服务器 持续推送 持续推送 持续推送 特点: • 长连接,全双工 • 服务端主动推送 • 适合实时行情

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 连接,以及如何处理断线重连。嗯,那又是一个值得细说的坑。


专注资料整理