# cme_data_feed **Repository Path**: initios/cme_data_feed ## Basic Information - **Project Name**: cme_data_feed - **Description**: cme国内接收行情说明 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-16 - **Last Updated**: 2025-11-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 1. 项目说明 本指南用于帮助快速搭建CME组播数据接收环境,并实现基本的数据解码 --- ### 2. 组播配置 ### 2.1 服务器配置 目前我们回传的是cme原始数据包,数据包中的IP目的地址为组播地址。要接收组播数据,需要加入组播组。 在加组之前,需要先禁用源地址路由校验,方法如下: ```bash # 编辑系统配置文件: vi /etc/sysctl.conf # 添加以下内容 net.ipv4.conf.all.rp_filter = 0 net.ipv4.conf.default.rp_filter = 0 net.ipv4.conf.ens1f1.rp_filter = 0 ``` 运行以下命令可以查看配置是否生效: ```bash sysctl -p ``` 配置生效之后,就可以加入组播组了 ```bash # 使用项目中我们提供的addgroup程序加入组播组(在主机中输入) ./addgroup -g multi://MULTI_IP@LOCAL_IP#10.123.100.21 # 参数说明: # MULTI_IP - 组播目的地址 # LOCAL_IP - 本机IP地址 # 10.123.100.21 - 组播源地址 ``` --- ### 2.2 交换机配置 为了确保组播数据能够正常传输,还需要在交换机上运行PIM(Protocol Independent Multicast)协议,并开启IGMPv3,配置示例如下: ```bash # 进入以太网接口1/1的配置模式 int interface Ethernet1/1 # 将接口从二层模式切换到三层模式,使其支持IP路由 no switchport # 为接口配置IP地址和子网掩码 ip address x.x.x.x/x # 在接口上启用PIM稀疏模式,用于组播路由 ip pim sparse-mode # 在交换机上启用IGMPv3 ip igmp version 3 # 在交换机上配置到组播源地址的静态路由 # 其中x.x.x.x为下一跳地址 ip route 10.123.100.21/32 x.x.x.x ``` --- ### 2.3 验证组播接收 ```bash # 使用tcpdump验证组播数据包接收 # 其中NIC_NAME需替换为实际的网卡名称 tcpdump -i NIC_NAME -nnn tcpdump -i NIC_NAME -nnn host x.x.x.x ``` --- ### 3. CME数据包解码 ### 3.1 MDP 3.0包结构 CME市场数据协议(MDP)3.0版本使用二进制格式传输数据,每个数据包由三部分组成: (1)包头部(Packet Header):包含序列号和发送时间(纳秒精度),用于数据包排序和延迟计算 (2)消息头部(Message Header):包含消息大小、模板ID、模式ID、版本,用于定义数据内容 (3)FIX消息体(FIX Message Body):实际数据内容,如订单更新和交易消息类型 消息头部和FIX消息体加起来称为一个MDP消息,一个数据包可以有多个MDP消息 更详细的说明可以参考以下链接的CME官方文档: - [MDP 3.0 - Packet Structure with Event Based Messaging](https://cmegroupclientsite.atlassian.net/wiki/spaces/EPICSANDBOX/pages/457326496/MDP+3.0+-+Packet+Structure+with+Event+Based+Messaging) --- ### 3.2 主要消息类型 前面提到,一个数据包可以有多个MDP消息,每个MDP消息的类型由消息头部中的模板ID决定,不同的模板ID对应不同的消息类型,具体可以参考项目中的templates_v13.xml文件, 以下是一些主要的消息类型: (1) MD Incremental Refresh Book (Template ID: 46),订单簿增量更新信息,用于更新订单簿,主要包含以下字段: - SecurityID:合约代码,用于唯一标识一个交易合约 - MDEntries:订单簿条目,包含价格、数量等信息 (2) MD Incremental Refresh Trade Summary (Template ID: 48),交易摘要更新信息,用于更新交易摘要,主要包含以下字段: - SecurityID:合约代码 - TradeID:交易编号,用于唯一标识一笔交易 - Price:成交价格 - Size:成交数量 (3) Snapshot Full Refresh (Template ID: 52),完整市场快照信息,用于完整市场数据刷新,主要包含以下字段: - SecurityID:合约代码 - MDEntries:市场数据条目,包含完整的市场状态 (4) Snapshot Full Refresh Order Book (Template ID: 53),完整订单簿快照信息,用于完整订单簿刷新,主要包含以下字段: - SecurityID:合约代码 - OrderID:订单编号,用于唯一标识一个订单 - MDEntries:订单簿条目,包含完整的订单簿状态 (5) MD Instrument Definition Future (Template ID: 54),期货合约定义信息,用于定义期货合约,主要包含以下字段: - SecurityID:合约代码 - Symbol:合约符号,如ES、NQ等 - MaturityDate:到期日期(期货特有) 更详细的消息类型定义可以参考以下链接的CME官方文档: - [MDP 3.0 - Message Specification](https://cmegroupclientsite.atlassian.net/wiki/spaces/EPICSANDBOX/pages/457323107/MDP+3.0+-+Message+Specification) - 项目中的templates_v13.xml文件(包括各字段的大小和类型也定义在文件中) --- ### 3.3 SBE解码说明 CME的消息头部和FIX消息体使用的是SBE编码,这是一种在传统的FIX/FAST协议基础上改进的编码方式,因为高效性,目前被广泛使用在金融领域。关于SBE的详细说明可以参考以下链接: - [Simple Binary Encoding (SBE) Wiki](https://github.com/aeron-io/simple-binary-encoding/wiki) 该git库同时是SBE的开源实现代码库,提供了Java、C++、Golang、C#、Rust等多种编程语言的编解码库。在下载并构建完成之后,只要提供templates.xml文件,就可以生成对应的解码头文件代码。对于C语言,简要的生成步骤是: (1)安装Linux JDK (2)编译SBE项目 查询安装成功后,就可以在git clone的SBE根目录下运行gradlew,对项目进行编译 ```bash ./gradlew ``` (3)准备模板文件 将我们提供的templates_v13.xml复制到SBE根目录下 (4)运行SBE生成代码 ```bash java --add-opens java.base/jdk.internal.misc=ALL-UNNAMED \ -Dsbe.generate.ir=true \ -Dsbe.target.language=C \ -Dsbe.target.namespace=sbe \ -Dsbe.output.dir=include/gen \ -Dsbe.errorLog=yes \ -jar sbe-all/build/libs/sbe-all-1.35.0-SNAPSHOT.jar \ templates_v13.xml # 参数说明: # Dsbe.target.language=C:指定输出目标代码语言为C # Dsbe.output.dir=include/gen:指定输出目录 # sbe-all-1.35.0-SNAPSHOT.jar:编译完成后在sbe-all/build/libs/下找到的jar包名字 # templates_v13.xml:模板文件名 ``` (5)获取生成的头文件 生成的头文件位于include/gen/sbe目录下,可以直接复制到你自己的解码项目中使用 更详细的说明可以参考链接中的README文档: - [Simple Binary Encoding (SBE) Code](https://github.com/aeron-io/simple-binary-encoding) 下面这个链接是CME官方提供的SBE解码示例,详细展示了如何解码一个Limits and Banding消息。示例中包含了完整的SBE Schema定义,十六进制消息的逐字节解码过程,字段类型、长度和值的详细说明,价格字段的编码规则(如PRICENULL9类型),重复组(Repeating Group)的处理方法 - [MDP 3.0 - SBE Decoding Example](https://cmegroupclientsite.atlassian.net/wiki/spaces/EPICSANDBOX/pages/457638169/MDP+3.0+-+SBE+Decoding+Example) --- ### 4. 参考工具 ### 4.1 解码接收工具 我们同时提供解码后的数据参考,解码后的数据的组播地址是239.239.240.130。加入这个组播组后,运行下面代码库中的程序时,可以收到如下格式的数据: ``` GCJ5, CST 2025-01-22 12:00:09.943974061, 27925.00, 1 GCJ5, CST 2025-01-22 12:00:09.943974061, 1726, 27876.00_1, 27882.00_1, 27883.00_1, 27888.00_1, 27890.00_14, 27894.00_2, 27900.00_1, 27902.00_1, 27906.00_3, 27912.00_1 | 27927.00_1, 27928.00_1, 27936.00_1, 27940.00_1, 27942.00_1, 27946.00_1, 27948.00_3, 27949.00_2, 27950.00_10, 27954.00_2 ``` 每行数据以``或``开头,分别表示最优价和深度行情: BEST的字段分别表示合约代码,时间戳和最优价数据 DEEP的字段分别表示合约代码,时间戳,买十档价格和卖十档价格 参考代码库: - [CME解码后组播接收代码库](https://gitee.com/initios/cme_sub)