3. Tick数据源与接入:常见交易所Tick数据源、FIX协议接入、WebSocket接入

在量化交易系统中,Tick数据是市场微观结构的原子级记录。本章聚焦于如何获取、接入并解析这些高频数据流。我们将从主流交易所的数据源特性出发,深入对比FIX协议与WebSocket两种接入方式的技术细节与适用场景。

3.1 常见交易所Tick数据源对比

不同交易所的数据粒度、传输延迟和订阅成本差异显著。下表列出了全球主流交易所的Tick数据源关键参数:

交易所 数据粒度 典型延迟 接入协议 费用模式
NYSE/纳斯达克 逐笔成交 + 逐笔报价 < 1ms (CoLo) ITCH / FIX / SoupBinTCP 按数据种类月费
CME Group 逐笔成交 + 深度快照 < 500μs (CoLo) FIX / iLink 3 / MDP 3.0 按产品线月费
币安 (Binance) 逐笔成交 + 增量深度 10-50ms (公网) WebSocket / REST 按订阅等级
欧交所 (Eurex) 逐笔成交 + 逐笔报价 < 1ms (CoLo) FIX / Eurex Enhanced 按连接月费
上期所 (SHFE) 逐笔成交 + 五档快照 10-100ms FIX / 私有TCP 按席位年费
选型建议: 对于高频做市策略,优先选择支持逐笔报价(Market By Order)的交易所,并考虑CoLo(机房托管)以降低物理延迟。对于中低频策略,WebSocket接入公网数据即可满足需求。

3.2 FIX协议接入:企业级Tick数据管道

FIX(Financial Information eXchange)协议是金融行业最成熟的消息标准,广泛应用于机构级市场数据接入。其核心优势在于消息格式标准化、会话层可靠、支持复杂的业务逻辑。

3.2.1 FIX协议核心组件

  • 会话层: 基于TCP长连接,通过Logon/Logout/Heartbeat消息管理会话生命周期。
  • 应用层: 使用Tag=Value格式编码业务消息,如市场数据增量(Market Data Incremental Refresh)。
  • 序列号与重传: 每个消息携带序列号,支持断线重连后的消息补传(Gap Fill / Resend Request)。
  • 快照与增量: 交易所通常先发送全量快照(Snapshot),后续推送增量更新(Incremental Refresh)。

3.2.2 FIX接入Tick数据流程

  1. 建立TCP连接: 连接到交易所指定的FIX网关IP和端口。
  2. 发送Logon消息: 包含用户名、密码、目标CompID等认证信息。
  3. 订阅市场数据: 发送Market Data Request消息,指定产品、订阅类型(快照/增量)、深度层级。
  4. 接收快照: 交易所返回Market Data Snapshot Full Refresh消息,包含当前完整订单簿。
  5. 处理增量流: 持续接收Market Data Incremental Refresh消息,更新本地订单簿。
  6. 心跳与重连: 定期发送Heartbeat,检测连接状态;断线后按序列号请求重传。
关键代码片段:FIX消息解析(Java QuickFIX/J)
// 接收市场数据增量消息
public void onMessage(quickfix.fix44.MarketDataIncrementalRefresh msg, SessionID sessionID) {
    // 获取MDEntries组
    int entryCount = msg.getNoMDEntries().getValue();
    for (int i = 1; i <= entryCount; i++) {
        Group group = msg.getGroup(i, MDEntryType.FIELD);
        char entryType = group.getChar(MDEntryType.FIELD);
        double entryPx = group.getDouble(MDEntryPx.FIELD);
        double entrySize = group.getDouble(MDEntrySize.FIELD);
        // 更新本地订单簿
        orderBook.update(entryType, entryPx, entrySize);
    }
}

3.3 WebSocket接入:轻量级实时数据流

WebSocket凭借其全双工通信、低开销、浏览器友好等特性,已成为加密货币和部分传统交易所的首选数据接入方式。它通过一个TCP连接提供持久化的双向数据通道。

3.3.1 WebSocket与FIX协议对比

对比维度 FIX协议 WebSocket
消息格式 Tag=Value 或 FIXML JSON / BSON / 二进制
会话管理 内置Logon/Logout/Heartbeat 需应用层实现心跳
重传机制 序列号 + Resend Request 需应用层实现(如订阅ID)
延迟 极低(二进制编码) 较低(JSON解析开销)
适用场景 机构级、高频、低延迟 零售、中低频、多平台
开发复杂度 高(需FIX引擎) 低(标准WebSocket库)

3.3.2 WebSocket接入Tick数据示例(币安)

  1. 建立连接: wss://stream.binance.com:9443/ws
  2. 订阅深度流: 发送JSON订阅消息,指定交易对和深度级别。
  3. 处理增量事件: 接收包含事件类型、价格、数量的JSON消息。
  4. 维护本地订单簿: 根据事件类型(新增/更新/删除)修改本地数据结构。
关键代码片段:WebSocket订阅深度流(Python)
import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    if data['e'] == 'depthUpdate':
        # 处理增量深度更新
        for bid in data['b']:  # bids: [price, quantity]
            order_book.update_bid(float(bid[0]), float(bid[1]))
        for ask in data['a']:  # asks: [price, quantity]
            order_book.update_ask(float(ask[0]), float(ask[1]))

def on_open(ws):
    # 订阅BTCUSDT 100ms深度流
    sub_msg = {
        "method": "SUBSCRIBE",
        "params": ["btcusdt@depth@100ms"],
        "id": 1
    }
    ws.send(json.dumps(sub_msg))

ws = websocket.WebSocketApp("wss://stream.binance.com:9443/ws",
                            on_open=on_open,
                            on_message=on_message)
ws.run_forever()

3.4 接入架构对比与选型决策

下图展示了两种接入方式在典型量化系统架构中的位置与数据流向:

FIX与WebSocket接入架构对比 FIX与WebSocket接入架构对比 FIX协议接入 交易所FIX网关 FIX引擎 (QuickFIX/C++) 消息解析 & 订单簿重建 内存Tick数据库 WebSocket接入 交易所WebSocket端点 WebSocket客户端 (asyncio) JSON解析 & 增量更新 内存Tick数据库 FIX适合机构级低延迟场景;WebSocket适合灵活、多语言、快速迭代的开发环境

3.5 接入选型决策矩阵

根据团队技术栈、延迟要求和运维能力,选择最适合的接入方式:

决策因素 推荐方案 理由
延迟敏感 < 1ms FIX + CoLo 二进制编码、硬件加速、专用线路
延迟敏感 1-10ms FIX 或 WebSocket (二进制) FIX更稳定,WebSocket需优化JSON解析
多语言团队 WebSocket 标准库支持广泛,开发效率高
加密货币为主 WebSocket 交易所原生支持,文档丰富
传统金融 + 合规 FIX 行业标准,审计日志完善
快速原型验证 WebSocket 代码量少,调试方便
常见陷阱:
  • FIX协议中序列号管理不当会导致数据丢失或重复,务必实现完整的Gap Fill逻辑。
  • WebSocket连接可能因网络抖动断开,必须实现自动重连和订阅恢复机制。
  • 不要混用快照和增量数据的时间戳,始终以交易所服务器时间为准。

3.6 灰度发布中的Tick数据接入策略

在灰度发布场景下,新旧系统需要同时接入Tick数据流。推荐采用双订阅 + 数据校验策略:

  1. 并行订阅: 新旧系统各自建立独立的FIX或WebSocket连接,订阅相同产品。
  2. 数据比对: 在灰度网关层对两路Tick数据进行逐笔比对,记录差异。
  3. 平滑切换: 当新系统数据一致性达到99.99%后,将生产流量逐步切至新系统。
  4. 回滚预案: 保留旧系统的连接,一旦发现异常立即切回。