第二章 核心协议基础:FIX协议详解、二进制协议对比、RESTful API在交易中的应用

各位同学,今天我们来聊聊交易接口的“通用语言”。做量化交易这些年,我最大的感触就是:接口协议选得好,后面少踩一半坑。这一章,咱们就把FIX、二进制协议、RESTful API这三兄弟掰开揉碎了讲清楚。

2.1 FIX协议:金融界的“普通话”

FIX协议,全称Financial Information eXchange。说白了,它就是金融行业里约定俗成的消息格式标准。我2015年刚入行时,对接的第一家券商就是用的FIX 4.4版本。那时候觉得这玩意儿真啰嗦,一个订单要写一堆标签。后来才发现,正是这种“啰嗦”保证了跨系统的兼容性。

2.1.1 核心结构

FIX消息由三部分组成:

  • 头(Header):包含消息类型、发送方、序列号等元信息
  • 体(Body):具体的业务数据,比如订单价格、数量
  • 尾(Trailer):校验和,保证消息完整性

举个例子,一个简单的限价买入订单长这样:

8=FIX.4.4|9=78|35=D|49=CLIENT1|56=BROKER1|34=1|52=20240101-00:00:00|11=ORD001|21=1|55=600519.SH|54=1|38=100|40=2|44=150.00|10=123|

嗯,这里要注意:每个字段用“|”分隔(实际是SOH字符,0x01)。标签号是固定的,比如35代表消息类型,D就是新订单。我刚开始写解析器时,经常把标签顺序搞反,结果券商那边一直报错。后来养成了习惯:先校验头,再解析体,最后算校验和。

2.1.2 会话层与业务层

FIX协议分两层:

  • 会话层:负责登录、心跳、重连、序列号管理。这部分是“管道”
  • 业务层:负责订单、成交、行情。这部分是“水”

我个人习惯把会话层单独封装成一个模块。为什么?因为业务层变化快,会话层相对稳定。你想想看,交易所改个订单字段,你只需要改业务层,会话层不用动。我在一个项目中见过有人把两者混在一起写,结果每次升级都像在拆炸弹。

避坑指南:我曾经在对接港交所时,忽略了FIX会话层的序列号校验。结果网络闪断后重连,序列号对不上,交易所直接拒绝所有消息。后来我加了个本地序列号缓存,每次重连前先同步,问题才解决。

2.2 二进制协议:速度与激情的选择

FIX虽然通用,但有个硬伤——慢。一个订单消息可能有几百字节,其中一半是标签名。对于高频交易来说,这简直是灾难。于是,二进制协议应运而生。

2.2.1 为什么快?

二进制协议的核心思想:去掉标签,固定位置。比如,消息的前4个字节是消息长度,接着2个字节是消息类型,再接着8个字节是价格……解析器直接按偏移量读取,不需要字符串匹配。

我做过一个对比测试:同样100万笔订单,FIX解析耗时约1.2秒,二进制协议只要0.3秒。差距就在这里。

2.2.2 常见二进制协议

协议名称 特点 典型场景
FIX/FAST 基于FIX的压缩版,用模板减少冗余 行情数据、批量订单
SBE(Simple Binary Encoding) 固定偏移,零拷贝解析 高频交易、FPGA加速
Protobuf Google出品,灵活但性能略逊 内部系统通信
自定义二进制 交易所自研,通常最快 CTP、XTP等国内柜台

我个人最常用的是SBE。为什么?因为它支持零拷贝。什么意思?就是网卡收到数据后,CPU可以直接从内存缓冲区读取字段,不需要复制数据。这对延迟敏感的交易系统来说,简直是福音。

小技巧:如果你要设计二进制协议,记住一条原则:固定长度字段放前面,变长字段放后面。这样解析器可以快速跳过固定部分,按需读取变长部分。

2.3 RESTful API:慢但友好的“万金油”

说到RESTful API,很多做高频的同学会嗤之以鼻:“太慢了,毫秒级延迟,谁用啊?”但我想说,存在即合理。RESTful API在以下场景中非常实用:

  • 查询历史成交、持仓、资金
  • 管理订单(撤单、改单)
  • 非实时行情获取
  • 账户风控设置

2.3.1 设计要点

一个标准的交易RESTful API通常包含:

  • POST /order:提交订单
  • DELETE /order/{id}:撤单
  • GET /order/{id}:查询订单状态
  • GET /account:查询账户信息

嗯,这里要注意:RESTful API的幂等性设计。我曾经遇到过一个问题:网络超时后,客户端重试,结果同一个订单被提交了两次。后来我要求所有POST请求必须带一个唯一的幂等键(Idempotency-Key),服务端根据这个键去重。从此再也没出过双单问题。

2.3.2 性能优化

虽然RESTful API天生慢,但我们可以优化:

  • 连接池:复用HTTP连接,避免三次握手
  • 压缩:启用gzip压缩,减少传输量
  • 缓存:对不频繁变动的数据(如合约信息)做本地缓存
  • 异步回调:用Webhook替代轮询

我见过一个团队,把RESTful API的查询延迟从200ms优化到了20ms。怎么做到的?就是用了连接池+本地缓存。说白了,大部分查询请求都是重复的,没必要每次都去交易所拉数据。

警告:千万不要用RESTful API做高频交易的下单通道。我见过有人用Python requests库每秒发1000个订单,结果网关直接把他IP封了。RESTful API适合管理类操作,交易类操作请用FIX或二进制协议。

2.4 三种协议的对比与选择

好了,三种协议都讲完了。我们来做个对比:

维度 FIX协议 二进制协议 RESTful API
延迟 中等(微秒级) 低(纳秒级) 高(毫秒级)
可读性 高(文本协议) 低(需要解码) 高(JSON/XML)
兼容性 高(行业标准) 低(需双方约定) 高(HTTP标准)
开发成本 中(有现成库) 高(需自研) 低(框架成熟)
适用场景 订单路由、行情分发 高频交易、FPGA 查询、管理、风控

我个人建议:不要只用一种协议。一个成熟的交易系统,应该是FIX做订单路由,二进制协议做高频通道,RESTful API做管理后台。各取所长,才是正道。

2.5 本章知识体系图

下面这张图,是我自己画的三种协议的关系和选择逻辑。你仔细看看,应该能理解为什么我说“没有银弹”。

跨市场交易接口协议选择逻辑 FIX协议 行业标准 · 可读性强 二进制协议 极致性能 · 低延迟 RESTful API 简单易用 · 管理类 订单路由 · 行情分发 高频交易 · FPGA加速 查询 · 管理 · 风控 如何选择?按场景组合使用 我的建议: 高频通道 → 二进制协议(SBE/FAST) 订单管理 → FIX协议(行业标准) 后台查询 → RESTful API(开发效率高)

你看,这张图把三种协议的应用场景和选择逻辑都串起来了。说白了,没有最好的协议,只有最合适的组合。我在设计跨市场交易系统时,通常会先画这样一张图,然后根据每个市场的特点,决定用哪种协议。

好了,这一章的内容就到这里。记住:协议是工具,不是目的。你的目标是让交易系统稳定、快速、可维护。选对协议,事半功倍。


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