3、市场数据接口:FIX协议入门、REST API与WebSocket对比、数据延迟分析

做高频交易,说白了就是跟时间赛跑。你拿到的数据比别人慢1毫秒,可能就错失了一笔利润。这一章我们来聊聊市场数据接口——怎么拿数据,用什么协议拿,哪个最快。

我个人习惯把数据接口分成三类:FIX协议、REST API、WebSocket。它们各有各的脾气,选错了,延迟能差出几个数量级。

3.1 FIX协议入门

FIX(Financial Information eXchange)协议,是金融界的“普通话”。几乎所有交易所、券商、做市商都支持它。我最早接触FIX是在做美股交易的时候,那会儿被它的标签号搞得头晕——后来习惯了,反而觉得它很优雅。

3.1.1 FIX协议长什么样?

FIX协议是纯文本的,用“标签=值”的方式组织。每个字段前面有个数字编号,比如35代表消息类型,55代表股票代码。消息之间用SOH(0x01)分隔。

看个例子,一条简单的订单请求:

8=FIX.4.2|9=78|35=D|49=CLIENT1|56=EXCHANGE|34=1|52=20250315-10:30:00.123|11=ORD001|55=600519|54=1|38=1000|40=2|10=234|

这里我用“|”代替了SOH字符,方便阅读。解释一下关键字段:

  • 8:协议版本,这里是FIX 4.2
  • 35:消息类型,D表示新订单
  • 55:证券代码,600519是贵州茅台
  • 54:买卖方向,1是买入
  • 38:数量,1000股
  • 40:订单类型,2是限价单
  • 10:校验和,用于完整性检查
我的小技巧:刚开始学FIX时,别死记标签号。用个FIX字典文件(比如QuickFIX的DataDictionary),查起来快得多。我当年手抄了50个常用标签,后来发现完全没必要。

3.1.2 用Python解析FIX消息

实际项目中,我们不会手写FIX解析器——太容易出错了。我推荐用quickfix库,它是C++写的,Python绑定,性能很好。

import quickfix as qf

# 创建一个FIX消息
message = qf.Message()
message.getHeader().setField(qf.BeginString("FIX.4.2"))
message.getHeader().setField(qf.MsgType("D"))  # 新订单
message.setField(qf.ClOrdID("ORD001"))
message.setField(qf.Symbol("600519"))
message.setField(qf.Side('1'))  # 买入
message.setField(qf.OrderQty(1000))
message.setField(qf.OrdType('2'))  # 限价单
message.setField(qf.Price(150.50))

# 发送(假设已建立连接)
# session.send(message)

嗯,这里要注意:FIX协议虽然强大,但学习曲线陡。如果你只是做国内期货或数字货币,可能用不到它——交易所通常提供更简单的接口。

3.2 REST API与WebSocket对比

REST API和WebSocket,是目前最主流的两种数据接口。我经常被问到:“到底该用哪个?”

我的回答是:看场景

3.2.1 REST API:简单但慢

REST API基于HTTP协议,请求-响应模式。你发一个GET请求,服务器返回数据。优点是简单、无状态、容易调试。

但缺点也很明显——每次请求都要建立TCP连接、发送HTTP头、等待响应。延迟通常在50-200ms之间,对于高频交易来说,太慢了。

import requests
import time

# 获取订单簿快照
start = time.time()
resp = requests.get("https://api.exchange.com/orderbook?symbol=btcusdt")
data = resp.json()
latency = (time.time() - start) * 1000
print(f"延迟:{latency:.2f} ms")

我曾经用REST API做行情展示,发现价格刷新总是慢半拍。后来换成WebSocket,体验完全不一样。

3.2.2 WebSocket:实时推送

WebSocket建立一次连接后,服务器可以主动推送数据。延迟通常在1-10ms,比REST快一个数量级。

看个例子,订阅数字货币的订单簿:

import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    # 处理订单簿增量更新
    print(f"收到更新:{data['bids'][:3]}")

def on_error(ws, error):
    print(f"错误:{error}")

def on_close(ws, close_status_code, close_msg):
    print("连接关闭")

def on_open(ws):
    # 订阅订单簿
    sub_msg = {
        "type": "subscribe",
        "channel": "orderbook",
        "symbol": "btcusdt"
    }
    ws.send(json.dumps(sub_msg))

ws = websocket.WebSocketApp("wss://ws.exchange.com/stream",
                            on_open=on_open,
                            on_message=on_message,
                            on_error=on_error,
                            on_close=on_close)
ws.run_forever()
核心区别:REST是“你去拿”,WebSocket是“它送过来”。高频交易必须用WebSocket或FIX,REST只适合做查询和下单。

3.2.3 对比表格

特性 REST API WebSocket FIX协议
通信模式 请求-响应 全双工推送 会话式推送
典型延迟 50-200ms 1-10ms 0.1-1ms
协议开销 高(HTTP头) 低(帧头) 极低(二进制)
适用场景 查询、非实时 行情订阅、交易 高频交易、机构
学习成本

3.3 数据延迟分析

延迟是高频交易的核心指标。你想想看,如果别人比你快1毫秒,他就能在你之前成交。这1毫秒,可能就是盈亏的分界线。

3.3.1 延迟从哪里来?

我总结了一下,延迟主要来自四个环节:

  1. 网络延迟:数据在网线、光纤里传输的时间。光速是30万公里/秒,但实际受路由、交换机影响,延迟会更高。
  2. 协议延迟:FIX、WebSocket、REST各自的协议开销不同。FIX的二进制编码比JSON快很多。
  3. 处理延迟:你的代码解析数据、更新订单簿的时间。Python比C++慢,但开发快。
  4. 交易所延迟:交易所内部撮合、推送数据的时间。这个我们控制不了,只能选快的交易所。
避坑指南:我曾经以为网络延迟是主要瓶颈,花大价钱升级了光纤。结果发现,代码里一个JSON解析函数用了正则表达式,每次解析多花了2ms。嗯,优化要从内到外。

3.3.2 如何测量延迟?

测量延迟不能只测一次,要统计分布。我习惯用百分位数:P50、P99、P99.9。

import time
import numpy as np

latencies = []
for i in range(1000):
    start = time.perf_counter_ns()
    # 模拟接收数据并处理
    # process_data()
    end = time.perf_counter_ns()
    latencies.append((end - start) / 1_000_000)  # 转为毫秒

latencies.sort()
print(f"P50: {np.percentile(latencies, 50):.3f} ms")
print(f"P99: {np.percentile(latencies, 99):.3f} ms")
print(f"P99.9: {np.percentile(latencies, 99.9):.3f} ms")

为什么看P99而不是平均值?因为平均值会被少数慢请求拉高,而P99能告诉你“最差的1%情况有多慢”。高频交易里,那1%的慢请求可能让你爆仓。

3.3.3 延迟优化思路

如果你发现延迟太高,可以从这几个方向入手:

  • 换协议:从REST换成WebSocket,延迟能降一个数量级
  • 用二进制:FIX的二进制版本(FAST协议)比文本版更快
  • 本地缓存:订单簿数据在本地维护,只接收增量更新
  • 选机房:把服务器放在交易所的同一机房,延迟能降到微秒级
我的经验:做数字货币高频交易时,我把服务器托管到了交易所的机房。网络延迟从5ms降到了0.1ms。但成本也高——一个月租金够买一台服务器了。值不值?看你交易量。

3.4 本章知识体系

下面这张图,帮你理清三种数据接口的关系和选择逻辑:

市场数据接口选择逻辑 REST API 延迟:50-200ms WebSocket 延迟:1-10ms FIX协议 延迟:0.1-1ms 适用场景 查询历史数据 非实时行情展示 适用场景 实时行情订阅 中频交易 适用场景 高频交易 机构级交易 核心原则:延迟要求越高,协议越底层,学习成本越高 选型时权衡:延迟 vs 开发效率 vs 维护成本

好了,这一章的内容就到这里。三种接口各有千秋,选型时别盲目追求低延迟——如果你的策略是分钟级持仓,REST API完全够用。但如果你做的是高频做市,那FIX协议几乎是唯一选择。

记住一句话:没有最好的接口,只有最适合你策略的接口


公众号:蓝海数据掘金营,微信deep3321