交易所协议概览:沪深交易所、中金所、大商所等主流交易所的协议差异

做量化交易的朋友,早晚要面对一个现实:不同交易所的协议,长得完全不一样

我刚开始接触这块时,以为各家交易所的协议大同小异。结果第一次对接深交所的逐笔委托,直接被它的字段排列方式搞懵了。嗯,后来我才明白,每个交易所都有自己的“脾气”

今天咱们就来聊聊,沪深交易所、中金所、大商所这些主流交易所,协议到底差在哪。

为什么会有协议差异?

说白了,历史原因和业务需求不同。

  • 上交所:最早推出逐笔数据,协议设计偏“紧凑型”,能省则省。
  • 深交所:后来者,协议更“规整”,字段对齐做得更好。
  • 中金所:期货交易所,协议里带了很多风控字段。
  • 大商所:商品期货,协议里多了交割相关的信息。

你想想看,一个做股票高频的,和一个做期货套保的,他们关心的数据能一样吗?

核心结论: 没有“万能解析器”,你必须针对每个交易所写专门的解析代码。

协议结构对比

我习惯把协议结构分成三层来看:

  1. 消息头:包含消息长度、消息类型、时间戳等。
  2. 消息体:真正的业务数据,比如委托价格、数量、方向。
  3. 消息尾:校验和、预留字段等。

各家交易所的差异,主要集中在这三层上。

交易所 消息头长度 消息体对齐方式 校验方式 典型消息类型
上交所 12字节 4字节对齐 CRC16 委托、成交、撤单
深交所 16字节 8字节对齐 CRC32 委托、成交、行情快照
中金所 20字节 4字节对齐 CRC16 委托、成交、持仓
大商所 14字节 2字节对齐 校验和 委托、成交、交割

看到没?光是消息头长度,就从12字节到20字节不等。你写解析器时,连读多少个字节都得小心

字段命名与含义的“坑”

我曾经踩过一个坑:上交所的“委托价格”字段叫 Price,深交所叫 OrderPrice,中金所叫 OrdPx。你以为只是名字不同?

不,单位也可能不同

  • 上交所:价格单位是“元”,精确到小数点后2位。
  • 深交所:价格单位是“元”,但精确到小数点后4位。
  • 中金所:价格单位是“指数点”,精确到小数点后2位。
  • 大商所:价格单位是“元/吨”,精确到小数点后2位。

所以,你解析出来的价格,不能直接拿来用。得先搞清楚单位,再换算。

我的习惯: 在解析器里,先定义一个“统一价格结构体”,所有交易所的价格都转成这个结构体。这样上层业务代码就不用关心底层协议了。

消息类型编码差异

每家交易所对“委托”、“成交”、“撤单”这些消息,都有自己的编码方式。

消息类型 上交所编码 深交所编码 中金所编码 大商所编码
委托 0x01 0x10 0x21 0x31
成交 0x02 0x11 0x22 0x32
撤单 0x03 0x12 0x23 0x33

你看,同样是“委托”,上交所是 0x01,深交所是 0x10。如果你写死了 if (type == 0x01),那对接深交所时肯定出问题。

我建议的做法是:用配置文件或枚举表,把消息类型映射关系抽出来。这样换交易所时,改配置就行,不用改代码。

协议版本与扩展

交易所的协议不是一成不变的。我遇到过好几次,交易所升级协议,加了新字段,结果我的解析器直接崩溃了。

为什么会这样?

因为有些交易所的协议,新字段是直接塞在消息体中间的。如果你按旧协议解析,后面的字段全对不齐了。

避坑指南: 我曾经因为没处理协议版本号,导致解析器在交易所升级后,连续三天解析出乱码。后来我学乖了:解析前先检查协议版本号,版本不匹配就报警,而不是硬解析

协议解析的通用思路

虽然各家协议不同,但解析思路是通用的。我总结了一个“三步走”方法:

  1. 读消息头:先读固定长度的消息头,拿到消息类型和消息体长度。
  2. 读消息体:根据消息类型,选择对应的解析函数。
  3. 校验:用消息尾的校验码,验证数据完整性。

下面是一个简单的伪代码示例:

// 伪代码:通用解析器框架
void parse_message(const char* raw_data, int len) {
    // 1. 解析消息头
    MessageHeader header = parse_header(raw_data);
    
    // 2. 根据消息类型,选择解析函数
    switch (header.msg_type) {
        case ORDER_ENTRY:
            parse_order_entry(raw_data + HEADER_LEN);
            break;
        case TRADE_REPORT:
            parse_trade_report(raw_data + HEADER_LEN);
            break;
        default:
            log_error("Unknown message type: %d", header.msg_type);
            return;
    }
    
    // 3. 校验
    if (!check_crc(raw_data, len)) {
        log_error("CRC check failed");
    }
}

这个框架,换哪个交易所都能用。你只需要替换 parse_header 和各个 parse_xxx 函数的具体实现就行。

用SVG梳理一下知识体系

下面这张图,把各家交易所的协议差异和解析思路串起来了:

交易所协议差异与解析思路 上交所 深交所 中金所 大商所 差异点:消息头长度 | 字段对齐 | 校验方式 | 消息类型编码 | 价格单位 通用解析框架:三步走 第一步:读消息头 获取消息类型和长度 第二步:解析消息体 按类型选择解析函数 第三步:校验 CRC/校验和验证 输出:统一格式的委托/成交数据

这张图的核心逻辑是:不管底层协议怎么变,上层解析框架是稳定的。你只需要针对每个交易所,实现具体的解析函数就行。

小结

今天咱们聊了沪深交易所、中金所、大商所的协议差异。说白了,就是消息头长度、字段对齐、校验方式、消息类型编码、价格单位这五个维度的不同。

我个人习惯是:先搭一个通用的解析框架,再针对每个交易所写具体的解析插件。这样换交易所时,只需要加一个插件,不用动主框架。

嗯,下一节咱们会深入上交所的逐笔委托协议,看看它的字段到底是怎么排列的。到时候我会拿一个真实的二进制数据包,手把手带你解析。


专注资料整理