2. 交易所数据协议:WebSocket vs REST、行情数据格式(L2/L3)、快照与增量

做量化交易,第一关就是怎么把数据拿回来。我见过不少新手,一上来就写个循环去轮询REST接口,结果行情还没拿到,先被交易所封了IP。今天咱们就把这块彻底聊透。

2.1 WebSocket vs REST:选哪个?

说白了,REST就是你去问交易所要数据,WebSocket是交易所主动推给你。你想想看,做高频交易时,每毫秒都可能是钱,谁有空一遍遍去问?

特性 REST WebSocket
连接方式 短连接,每次请求独立 长连接,持续推送
延迟 较高(50-200ms) 极低(1-10ms)
数据获取 拉模式(Polling) 推模式(Push)
适用场景 历史数据、账户查询 实时行情、订单簿
带宽消耗 低(按需请求) 高(持续推送)

我个人习惯是:REST拿历史数据,WebSocket接实时流。比如启动时先用REST拉一次快照,然后切到WebSocket收增量更新。这样既快又稳。

⚠️ 注意: 我曾经见过有人用REST做高频轮询,结果被交易所判定为DDoS攻击。记住,REST接口通常有频率限制,比如每秒最多5次。WebSocket则没有这个烦恼。

2.2 行情数据格式:L2 vs L3

这里有个常见的坑——很多人分不清L2和L3。我简单解释一下:

  • L2(Level 2):聚合后的订单簿。比如买一价1.0000有100个,买二价0.9999有200个。交易所把相同价格的订单合并了。
  • L3(Level 3):原始订单簿。每个订单都是独立的,能看到每个订单的ID、数量、时间戳。说白了就是「裸数据」。

举个例子,你在币安上看到的深度图就是L2。而如果你做做市商策略,需要精确控制每个订单的成交情况,那就得用L3。

💡 我的经验: 做普通策略用L2就够了。L3数据量太大,处理不好反而拖慢系统。我有个朋友非要上L3,结果服务器内存直接爆了。

2.3 快照与增量:重建订单簿的核心

订单簿重建,说白了就是「先拍一张照片,然后不断更新变化」。这个逻辑其实很简单:

  1. 快照(Snapshot):某一时刻订单簿的完整状态。比如「当前买一价1.0000,数量100;卖一价1.0001,数量200」。
  2. 增量(Incremental Update):后续的变化。比如「买一价1.0000的订单被吃掉了50个」或者「新增了一个卖单在1.0002」。

你想想看,如果每次都传完整快照,带宽根本扛不住。所以交易所都是「快照+增量」的模式。我一般这样处理:

# 伪代码:订单簿重建逻辑
class OrderBook:
    def __init__(self):
        self.bids = {}  # 买盘
        self.asks = {}  # 卖盘
    
    def apply_snapshot(self, snapshot):
        # 清空旧数据,加载新快照
        self.bids = {item['price']: item['size'] for item in snapshot['bids']}
        self.asks = {item['price']: item['size'] for item in snapshot['asks']}
    
    def apply_update(self, update):
        # 处理增量更新
        for side in ['bids', 'asks']:
            for item in update[side]:
                price = item['price']
                size = item['size']
                if size == 0:
                    # 数量为0表示删除该价位
                    self.bids.pop(price, None) if side == 'bids' else self.asks.pop(price, None)
                else:
                    # 更新或新增
                    if side == 'bids':
                        self.bids[price] = size
                    else:
                        self.asks[price] = size
🔧 避坑指南: 我曾经遇到过增量更新序号错乱的问题。交易所的每条增量都有一个序列号,一定要检查序列号是否连续。如果发现跳号,必须重新拉取快照,否则订单簿会越偏越远。

2.4 知识体系总览

下面这张图把整个数据获取流程串起来了。我建议你保存下来,做系统设计时对照着看:

订单簿数据获取流程 交易所 REST WebSocket REST 接口 历史数据 / 快照 WebSocket 接口 实时增量更新 订单簿重建引擎 1. 加载快照 2. 应用增量 3. 校验序列号 实时订单簿 L2:聚合订单簿(按价格合并) L3:原始订单簿(每个订单独立) 快照:完整状态 | 增量:变化部分

嗯,这张图把整个流程讲清楚了。从交易所出发,REST拿快照,WebSocket收增量,然后在订单簿重建引擎里合并。最后输出一个实时更新的订单簿。

📌 核心要点:
  • REST适合拿快照和查询,WebSocket适合收实时增量
  • L2是聚合数据,L3是原始数据,选哪个看你的策略需求
  • 快照+增量是标准模式,一定要校验序列号防止数据错乱

好了,这一章就到这里。数据协议这块是基本功,搞懂了后面做策略才不慌。下一章咱们聊聊订单簿的深度计算和流动性分析,到时候会用到今天讲的知识。


公众号:蓝海资料掘金营,微信deep3321