← → 翻页 · B 静态 · ESC 索引
交易所行情接入技术讲解
SSE · SZSE · HKEX · 01 / 18
MARKET DATA DISTRIBUTION

交易所行情接入

上交所 · 深交所 · 港交所
中证指数 · 供应商技术培训
→ swipe / arrow keys
02 / 18
DELIVERABLES
KEY REQUIREMENTS

行情接入
关键交付要求

中证指数 · 供应商技术培训
2026.06
FOUR DELIVERABLES
04 ITEMS
01

多协议适配

同时支持 BINARY · STEP+FAST · OMD-C 等多种协议族

02

行情标准化

将多种外部接口统一为符合内部协议的数据流

03

重传与恢复

具备重传机制的交易所需妥善利用机制,确保数据不丢

04

多路冗余 · 灾备感知

行情源之间建设多路冗余

05

频道订阅 · 动态调整

按成分券清单精准订阅,支持运行时动态增删频道

第一章 · 数据流总览
03 / 25
ARCHITECTURE

数据流
四层架构

交易所发原始行情 → 行情接入层标准化 → 指数计算 → 对外发布

01

交易所行情源

SSE LDDS/MDGW · SZSE MDGW · HKEX OMD-C · 各自独立的二进制协议与传输通道

02

行情接入层

协议解析 · 数据标准化 · 质量过滤 · 多源适配 · 99.995% 高可用

03

指数计算引擎

匹配成分券 · 统一标准化行情输入 · 实时指数计算 · 99.995% 高可用

⚠ 行情数据不是"接了就行",数据质量直接决定指数准确性

04

对外发布层

订阅数据分组 · 流式/文件发布 · 跨机房数据择优 · 99.995% 高可用

第二章 · 接入方式
04 / 25
SSE · 上交所双通道

Level-1 vs Level-2

01 Level-1 · MDGW
BINARY 协议
VSS 通过 TCP 直连 MDGW 行情网关,发送 Logon(S001) 完成登录验证后,MDGW 单向推送流式行情。
Binary 报文帧 · Header 24B + Body + Tail 4B
MsgType
SendingTime
MsgSeqNum
BodyLen
char[4]
uint64 · 8B
uint64 · 8B
uint32 · 4B
Body(按 MsgType 不同而异)S001 登录 · S002 注销 · S003 心跳 · M101 市场状态 · M102 快照
CheckSum
uint32 · 4B
  • 内容:快照 M102(股票/债券/基金/期权)+ 市场状态 M101
  • 重传:❌ 暂不支持,等下一快照周期
  • 心跳:S003 双向心跳,双方互发
  • 网络:专线 / 上证云 / 互联网,建议 8M
  • 协议:24B消息头 + 4B CheckSum · Big-Endian · GBK
02 Level-2 · LDDS
FIX → STEP → FAST
FIX 会话层文本协议 Key=Value → STEP(上交所 FIX 4.4 本地化裁剪扩展)→ FAST 编码压缩为二进制流
链路:STEP 明文 → FAST 编码 → TCP 发送 → FAST 解码 → STEP 明文
STEP 报文帧 · Tag=Value SOH(\001) 分隔
Tag 8
STEP.1.0.0
Tag 9
BodyLen
Body35=UA3202·49=VDE·56=VSS·10142=6·10072=N·95=Len·96=FAST
Tag 10
ChkSum
■ 蓝色 = STEP 纯文本■ 高亮 = FAST 二进制载荷
  • 内容:股票/基金快照、指数快照、债券快照、债券逐笔成交、业务合并逐笔、静态文件
  • 模板解码:XML 模板描述字段顺序/类型/操作符
  • 重传:✅ 重建端口,按产品类别+消息序号范围
  • 网络:专线 / 上证云 , 建议 20M
  • 协议文档:LDDS 接口说明书 · LDDS FAST 行情接口 · IS120 STEP 规范
第二章 · 接入方式
05 / 25
SZSE vs HKEX

深交所 vs 港交所

01 SZSE · 深交所 L1
TCP 直连 MDGW
VSS 直接与 MDGW 建立两个独立会话:实时会话 + 重传会话,各端口独立通信。
Binary 报文帧 · Header 8B + Body + Tail 4B
MsgType
uInt32 · 4B
BodyLength
uInt32 · 4B
Body300111 快照 · 300192 逐笔委托 · 300191 逐笔成交 · 390013 证券状态 …
CheckSum
uInt32 · 4B
■ 蓝色 = Binary 帧(Big-Endian · UTF-8)
  • 端口:实时 9129 + 重传 9130
  • 协议:TCP / UDP 组播双模(TCP 协议支持实时和重传数据,组播协议仅可用于实时数据)
  • 认证:网络层安全(非加密传输)
  • 重传:✅ 390094 按频道+起止序号精确补传
  • 流控:处理不及时会被 MDGW 主动断开
02 HKEX · 港交所
双路 UDP 组播
A/B 双路组播互为冗余,Live 频道推逐笔、Refresh 频道周期刷快照,RTS 提供 TCP 重传。易境通将 UDP 转 TCP。
OMD-C UDP 组播包 · Packet Header 16B + Messages[]
PktSize
uInt16·2B
MsgCnt
uInt8·1B
SeqNum
uInt32·4B
SendTime
uInt64·8B·ns
Msg₁ ~ Msgₙ(连续排列,无间隔)每条: MsgSize(uInt16·2B) + MsgType(uInt16·2B) + Body
实际处理消息类型
11 SecDef 52 TradeTicker 60 Statistics 62 ClosePrice 100 SeqReset 203 RefreshOK
■ 蓝色 = Packet Header■ 高亮 = 行情数据消息□ 白色 = 控制消息
  • 直连:Live(UDP×2) + Refresh(UDP) + RTS(TCP)
  • 冗余:A/B 路不同组播端口,内容完全一致
  • 认证:内部专线授权(不经过公网)
  • 重传:✅ RTS 逐笔 / 🔄 Refresh 快照恢复
  • 其他渠道:易境通CQG 网关,频道号 = 6000 + 原始频道;LDDS VDE渠道接收港股行情
第二章 · 消息类型归纳
06 / 25
CONTENT TAXONOMY

交易所发布内容六类

01

登录 / 注销

会话生命周期管理
SSE Level-1: S001/S002
SSE Level-2: 发送 Logon(35=A),接收并判断 Logout(35=5)
SZSE: Logon/Logout
HKEX: 加入组播即可

02

心跳 / 保活

链路状态监测
SSE: S003/UA1202
HKEX: 3×间隔断连

03

重传请求

丢包检测与补传
SZSE: 390094
HKEX: RTS / Refresh

04

静态信息

证券定义/公告/文件
SSE: mktdt00.txt
HKEX: News/Security Def

05

快照行情

定期全量刷新
股票/指数/基金
3s周期 / 实时推送

06

逐笔行情

实时逐笔推送
成交/委托
L2 专属 / HKex Live 频道

第三章 · 消息处理
07 / 25
SSE L1 · CHAPTER DIVIDER

上交所 Binary Level1

第三章 · 消息处理 · 上海Level1
08 / 25
SSE L1 · MDGW BINARY · PROTOCOL DESIGN

Level1协议四要素

参见接口文档§2.1.1

序号机制 — 最简洁的设计

每端维护 (NxtIn, NxtOut),从 1 连续递增
仅用于会话完整性校验,不用于重传定位

对比:L2 按 tag10142 产品类别编号 · SZSE 按频道号编号

参见接口文档§2.1.4

不支持重传 — 核心约束

"MDGW目前发布的行情应用消息不支持重传"

由于Level1丢包只能等下一快照周期(3s),考虑业务层补偿

→ 可能涉及主备切换

参见接口文档§2.1.6

心跳机制 — 连接健康判定

HeartBtInt 登录时协商间隔
2× 间隔无消息 → 判定异常 → 重建会话

对比:L2 UA1202 每 10s 单向推送,VSS 无需应答

参见接口文档附录一

CheckSum — 极简校验

uint8 逐字节累加,结果放入 uint32
仅检测基本字节错误

SZSE: uint32 累加 %256 (需注意Big Endian的影响) · L2 STEP: 字节累加 %256 · HKEX : 依赖 UDP 层校验

第三章 · 消息处理 · 上海Level1
09 / 25
SSE L1 · PRACTICAL NOTES

实战要点

01 · 主动断连

高吞吐场景三大陷阱

超时未登录:TCP 连接后几秒内未发送登录请求
登录异常: 收到MDGW发送的LOGOUT消息
消费积压:VSS 处理太慢,待发送消息超阈值,导致套接字被断开等

⚠ 需确保消费速度匹配 MDGW 推送速度
⚠ 重连或触发主备切换
⚠ 重连时机:登录失败 / 网络异常 / 连续收到无效包

02 · 快照处理

无状态 · 全覆盖 · 直接覆盖

无全量/增量区分:每条快照都是独立的最新完整状态
直接覆盖更新:收到新数据即覆盖旧值,无需增量合并
覆盖范围:指数 / 股票 / 债券 / 基金等所有快照

⚠ 收盘产品不应再被新快照数据更新, 除非重新放开锁定

03 · 备份恢复

原始数据 + 转发数据双备份

原始备份:MDGW 收到的有效消息在处理前先原样写盘
转发备份:全量快照与变化数据持久化至数据库
写入模式:缓冲模式(攒批写)vs 直接模式(逐条写)

⚠ 原始数据是纯二进制数据,不适合持久化至数据库
⚠ 生产环境推荐缓冲模式,减少磁盘 I/O 提升性能

第三章 · 消息处理
10 / 25
SSE L2 · CHAPTER DIVIDER

上交所 STEP Level2

第三章 · 消息处理 · 上海Level2
11 / 25
SSE L2 · VDE / VSS CONNECTION ARCHITECTURE

VDE/VSS 双层架构接入

Level 2 不是直连交易所撮合主机,而是通过 VDE 中间件接入 — VSS(我方行情应用)只能通过 VDE 获取数据

IDC · LDDS 数据发布服务器
推送 STEP+FAST 行情流 · 每 10s 发 UA1202 心跳
VDE Java 中间件 · JRE 1.8
上交所提供的 LDDS 专用接入程序,信息商必须安装
实时行情端口
TCP 长连接 · 推送模式
重建行情端口
TCP 短连接 · 请求/应答
同一局域网
VSS = 我方行情应用程序
协议解析 · FAST 解码 · 序号连续性校验 · 数据重建触发
必装中间件

VDE 是上交所提供的 Java 接入程序(JRE 1.8),我方 VSS 只能通过 VDE 获取数据,不能绕过

双端口连接

实时端口 = 长连接推送
重建端口 = 短连接请求
每端口仅允许唯一 TCP 连接

局域网部署

VSS 必须与 VDE 部署在同一局域网内
数据安全由信息商自行保证

重建短连接

每次重建请求完毕后 VDE 发 Logout
VSS 须断开,下次重建需重新连接

第三章 · 消息处理 · 上海Level2
12 / 25
SSE L2 · LDDS · STEP + FAST ARCHITECTURE

STEP 协议与 Body 内部结构

协议定位

STEP = FIX 信封 + 扩展 + FAST

保留 FIX 会话层结构(Tag 8/9/10、SOH 分隔)
裁剪通用金融字段,扩展 10xxx 自定义 tag
支持 Tag 96 内嵌 FAST 二进制载荷

⚠ STEP 是基于 FIX 协议框架的本地化定制版:它保留了 FIX 的会话层信封结构(Tag 8/9/10、SOH 分隔、校验和机制),裁剪了 FIX 中不适用的通用金融字段,同时扩展了大量 10xxx 范围的自定义 tag,以适配上交所 Level-2 行情的业务需求(包括嵌套 FAST 二进制载荷)。
⚠ 消息边界识别:一条完整的 STEP 消息以 8=STEP.1.0.0 开头,以 10=xxx 结尾(10域校验和必须是最后一个域

Body 分层

统一 tag=value 格式,不区分文本/二进制

会话字段:35=UA3202 · 49=VDE · 56=VSS
路由字段:10142=6(分类ID) · 10072=1(序号)
FAST 载荷:95=长度 · 96=二进制数据

⚠ SOH 分隔符(ASCII 0x01):每个 Tag=Value 对之间用 SOH 分隔,不是换行符也不是逗号,解析器必须正确处理这个不可见字符。

Tag 95/96

FAST 载荷的长度与指针

Tag 95 = FAST 载荷的字节长度(纯文本数字)
Tag 96 = FAST 压缩行情数据(二进制流)
两者都是 Body 内的普通 tag=value 字段

⚠ 不能简单地按 SOH 切分整条消息,需要先读 tag95 获取 FAST 数据长度,再精确截取 tag96 的二进制载荷

Tag 9/10

帧定界与校验和

Tag 9 = Body 长度(从 Body 起始到 Tag 10 含)
Tag 10 = 字节累加 %256,覆盖整个 Body
STEP_HEAD_LEN=15 · STEP_TAIL_LEN=7

校验范围含 95/96,即 FAST 二进制也参与校验

第三章 · 消息处理 · 上海Level2
13 / 25
SSE L2 · MESSAGE PROCESSING PIPELINE

消息路由 → FAST 解码

STEP 01

Tag 35 路由分发

RcvStepMsg() 收到帧
GetMsgType() 提取 Tag 35
35=A → 登录
35=5 → Logout break
35=UAxxxx → 业务路由

⚠ 模板文件 template.xml:FAST 解码器需要加载与当前行情匹配的模板文件,模板定义了每种消息(UA3202、UA5803 等)的字段结构和操作符(copy、default、increment、constant、none)
⚠ 操作符语义:FAST 操作符决定了解码行为——copy 表示同值省略、default 表示缺省值、increment 表示自增、constant 表示固定值、none 表示每次都传。如果操作符理解错误,解码出来的数据会完全不对
⚠ 接口文档升级可能导致模板变更(如新增字段、调整操作符),必须确保本地模板文件与交易所发布的版本严格一致

STEP 02

业务类型过滤

白名单匹配:
UA3202 竞价快照
UA3113 指数行情
UA5803 逐笔合并
UA5815 通道序号
UA3802 债券快照
UA3901 债券逐笔
UA3815 债券市场总览

STEP 03

FAST 载荷提取

DisposeDataMsg():
GetTagValue("95") → FAST 长度
GetFastValue("96") → 二进制指针
MsgQueSend() → 消息队列
→ 送入 FAST 解码线程

STEP 04

QuickFAST 解码

SynchronousDecoder:
加载 template.xml 模板
按模板 ID 匹配解码器
操作符:constant/copy/default
→ consumeMessage()
→ parseSnap/parseIndex

第三章 · 消息处理 · 上海Level2
14 / 25
SSE L2 · DUAL-LAYER SNAPSHOT PUBLISHING

快照双重发布策略

Level 2 快照比 Level 1 更精细 — 分为"变化全量"与"周期全量"两层,下游需容忍最长 30s 数据空窗

3s 周期

变化全量快照

每 3 秒发布一次快照,但只发有变化的数据
若某只股票长时间无交易,其快照会顺延不发

⚠ 不能假设每 3s 一定能收到某产品的快照
⚠ 债券(UA3802)仅 3s 单层策略,无双层发布

30s 周期

周期全量快照

每 30 秒无差别发布所有产品快照
无论数据有无变化,均会发布一次全量

保证所有产品至少 30s 刷新一次数据
⚠ 30s 周期全量为竞价专用,债券无此机制

盘后 6s

盘后快照加速 + ImageStatus

盘后固定价格交易快照(UA3108)周期全量频率为 6s
ImageStatus=1 表示全量快照,直接覆盖即可

盘后频率比盘中快 5 倍(6s vs 30s)
⚠ 债券不参与盘后固定价格交易

开发要点

下游系统防御性设计

• 不能假设每 3s 一定能收到某产品快照
• 需容忍最长 30s 数据空窗
• 全量快照直接覆盖,无需增量合并

停牌期间仍会发快照(状态=SUSP)

第三章 · 消息处理 · 上海Level2
15 / 25
SSE L2 · REBUILD MECHANISM & FIELD PRECISION

数据重建 & 精度处理

01 数据重建
Rebuild 机制与限制
快照类 ❌ 不支持重建,只能等下一轮快照(最多 30s)
逐笔类 ✅ 支持:UA3209 逐笔成交 + UA5803 逐笔合并 + UA3901 债券逐笔(ch801)
重建流程(短连接,每次请求完毕即断开)
连接重建端口 发 UA1201 收回补数据 收 Logout 断开
tag10075=1 按序列号回补 · tag10075=2 全量(已停用)· tag10075=3 逐笔回补(指定通道+序号范围)
  • 丢包检测:逐笔成交 TradeIndex(tag10011) / 逐笔合并 BizIndex(tag10021) 按 Channel 从 1 连续递增,序号不连续 = 丢包
  • 回补上限:每次建议 ≤ 1000 条,超出可能超时或被拒
  • 时间窗口:逐笔合并 09:25-16:00 · 盘后逐笔 15:05-16:00 · 债券逐笔 09:15-16:00
02 精度处理
字段溢出保护 & 精度
FAST 编码数值字段有明确精度上限,开发时必须做防御性处理
精度速查
数量字段 最大 15 位(999999999999999),超出截断 金额字段 最大 18 位,超出截断 IOPV tag10057=3位精度 · tag10140=5位精度
  • 收盘价 ≠ 最新价:tag31(LastPx) 只是最新成交价,必须以 tag10204(ClosePx) 为收盘价,且仅 ClosePx > 0 时有效
  • 昨收价以实时为准:实时 tag140 > 0 且与静态文件不同时,以实时为准
  • 单位差异:B 股价格 = 美元 · 其他 = 人民币元
    数量:股票=股 · 债券分销=千元面额 · 基金=份
    质押式回购价格字段 = 利率(非价格)
第三章 · 交易状态机 · 上海 Level1 vs Level2
16 / 25
LEVEL 1 · BINARY GATEWAY

Level1 状态信息

M101

市场级状态 · TradingSessionID (char[8])

SecurityType=1(股票/基金/指数/债券分销)

位1S=全市场启动 · T=交易期间 · E=闭市 位2I=开盘集合竞价结束 · 0=未结束 位3I=全市场行情结束 · 0=未结束 位4I=上海市场行情结束 · 0=未结束

Level 2 无此机制 — 需自行从逐产品状态推断全市场阶段

M102

产品级 · TradingPhaseCode (char[8])

MD002 股票 · MD003 债券分销 · MD004 基金(含REITs)

位1S=启动 · C=开盘集合竞价 · T=连续交易
U=收盘集合竞价 · E=闭市 · P=停牌
M=可恢复熔断(盘中集合竞价)
N=不可恢复熔断(暂停至闭市)
位20=不可正常交易 · 1=可正常交易 位30=未上市 · 1=已上市 位40=不接受新申报 · 1=可接受新申报

M / N 为 Level 1 独有熔断状态,Level 2 无对应枚举

LEVEL 2 · LDDS FAST · UA3202 / UA3802

Level2 状态信息

▸ 竞价 Level-2(UA3202)

▎股票(含收盘集合竞价 CCALL)

START OCALL TRADE CCALL CLOSE ENDTR

▎基金 / 债券分销产品(无 CCALL)

START OCALL TRADE CLOSE ENDTR

▸ 债券 Level-2(UA3802)

▎可转债(15:00 收盘,无 CCALL)

ADD START OCALL TRADE CLOSE ENDTR

▎债券现券 / 回购(除可转债,15:30 收盘)

ADD START OCALL TRADE CLOSE ENDTR

▎停牌

任意状态 SUSP CLOSE ENDTR

时段对照

状态码 含义 股票 基金/债券分销 可转债 现券/回购
ADD 产品未上市 ✓ 债券独有 ✓ 债券独有
START 启动 8:45~9:15 8:45~9:15 8:45~9:15 8:45~9:15
OCALL 开盘集合竞价 9:15~9:25 9:15~9:25 9:15~9:25 9:15~9:25
TRADE 连续自动撮合 9:25~14:57 9:25~15:00 9:25~15:00 9:25~15:30
CCALL 收盘集合竞价 14:57~15:00 — 无 — 无 — 无
CLOSE 闭市(计算收盘价) 15:00 15:00 15:00 15:30
ENDTR 交易结束 随后发 随后发 随后发 随后发

OCALL/CCALL 期间:申买价一/申卖价一 = 虚拟参考价
申买量一/申卖量一 = 虚拟匹配量 · 量二 = 未匹配量

第三章 · 消息处理
17 / 25
SZSE · CHAPTER DIVIDER

深交所 Binary

第三章 · 消息处理 · 深交所Binary
18 / 25
SZSE · BINARY PROTOCOL STRUCTURE

协议结构与会话机制

消息结构

消息头 + Body + 消息尾

消息头:MsgType(uInt32) + BodyLength(uInt32)
消息体:业务字段,按 MsgType 分发解析
消息尾:CheckSum(uInt32)

参见接口文档§4.2

编码规范

Big Endian · UTF-8 · CheckSum

所有整数类型:高字节序(Big Endian)
字符串:UTF-8 编码,不足最大长度补空格
Price=Int64 N13(4) · Qty=Int64 N15(2)

CheckSum: 逐字节累加 %256,覆盖消息头+消息体

会话管理

TCP 双端口 · 双会话

实时会话:端口 9129,接收全量行情
重传会话:端口 9130,仅网络版提供
Logon → 登录确认 → Heartbeat 保活

心跳间隔 Logon 时协商 · 2×间隔超时断连

频道体系

按业务分频道 · 独立编号

1=市场/证券状态 · 2=公告
10/11=指数/国证指数 · 12=基金净值
101x=股票快照 · 201x=股票逐笔 ……

每频道独立心跳 · 记录号频道内从 1 递增

第三章 · 消息处理 · 深交所Binary
19 / 25
SZSE · RETRANSMISSION & DEV NOTES

重传机制与开发注意

快照 vs 逐笔

两种数据的本质差异

快照行情:定时发布截面,不可重传
含股票/基金/指数/债券快照(300111/309011等)
逐笔行情:逐条记录,支持重传
频道内 ApplSeqNum 从 1 递增,跳变即丢包

参见接口文档§3.2/§3.3

重传机制

MsgType=390094 · 请求-应答

ResendType: 1=逐笔行情 · 2=公告信息
ChannelNo + ApplBegSeqNum/ApplEndSeqNum 定位
EndSeqNum=0 → 自动设为内存最大值
重传会话独立 TCP 连接(端口 9130)

多个重传请求按到达顺序依次处理

双心跳

会话心跳 + 频道心跳

会话心跳:Logon 时 HeartBtInt 协商间隔
空闲时发送,2×间隔超时 → 判定断连
频道心跳(390095):每频道独立 3 秒
含 ApplLastSeqNum + EndOfChannel 标志

频道心跳无记录号,不参与序号连续性检测

第三章 · 消息处理
20 / 25
HKEX · CHAPTER DIVIDER

港交所 OMD-C

UDP 组播 · A/B 双路仲裁 · RTS+RFS 恢复
第三章 · 消息处理 · 港交所OMD-C
21 / 25
HKEX · UDP MULTICAST · LINE ARBITRATION

线路仲裁与数据包结构

双数据流

Realtime 实时流 + Refresh 快照流

每个频道 = 两条独立组播流
① Realtime 实时增量流(A/B 双路 + RTS 重传)
② Refresh 定期全量快照流(A/B 双路,无 RTS)
刷新频道用专用组播地址,周期发送市场快照

Refresh Complete 标记快照周期边界,携带 LastSeqNum

核心原则

A/B 平等监听,不可优先 A

Line A 不保证比 B 快,两者同等优先级
A/B 打包方式可能不同(同一消息在不同包)
Gap 检测模块不应关心包来源

⚠ "先 A 后 B" 的思路是错误的

三大能力

丢重 · 排序 · Gap 检测

丢弃重复:(seqNum+msgCount) < nextSeqNum → 跳过
重排序:缓存乱序包,按序号处理
Gap 检测:seqNum > nextSeqNum → 触发恢复

统一通过 nextSeqNum 变量实现

SS 频道

Securities Standard (conflated) 频道

Ch1 Reference Data(参考数据)
Ch2 Trading Session Status(交易状态)
Ch10 Conflated 聚合行情(AggOB/价格/成交)
Ch3 Value Add · Ch4 News · Ch9 DR Signal

每个频道均有 Realtime(A/B) + Refresh(A/B) + RTS

第三章 · 消息处理 · 港交所OMD-C
22 / 25
HKEX · RECOVERY · RTS + RFS

恢复双通道:重传 + 刷新

01 RTS 重传服务 (TCP)
小 Gap 快速恢复
  • 连接方式:TCP 单连接,Logon 建立会话(5s 超时)
  • 缓存深度:每频道最近 50,000 条消息
  • 请求限制:单次 ≤10,000 条 · 每日 ≤1,000 次
  • 心跳维持:RTS 每 30s 发心跳,客户端 5s 内回复
  • Securities / Index 使用独立 RTS 服务器,地址不同

⚠ 仅用于实时补传,不可用于日内全量恢复

02 RFS 刷新服务 (组播)
全量快照恢复
  • 触发场景:日内启动 / 大 Gap / RTS 失败
  • 同步流程:订阅 Realtime → 订阅 Refresh → 丢弃首个 Refresh Complete 前的数据 → 处理两个 Refresh Complete 之间的完整快照 → 取 LastSeqNum → 合并
  • 合并策略:Realtime 缓存中 seqNum > LastSeqNum 的消息继续处理,≤ LastSeqNum 的丢弃
  • A/B 双路:同实时频道,支持线路仲裁
  • 无重传:刷新频道丢包只能等下一轮快照

⚠ 先刷新参考数据频道,再刷新行情频道

第三章 · 消息处理 · 港交所OMD-C
23 / 25
HKEX · EXCEPTION HANDLING

三大异常场景处理流程

场景 01

Sequence Reset

收到消息 100
→ 重置 nextSeqNum = 1
→ 清除该频道所有缓存
→ 订阅 Refresh 获取最新快照
→ 恢复实时处理

开盘前可能收到多次 Reset

场景 02

Intraday Restart

OMD-C 盘中重启
→ 所有 RTS 断开
→ 所有组播停止(含心跳)
→ 收到通知后清除全部缓存
→ 按迟连接流程重连

重启间隔可达 1 小时,不可依赖 Reset 消息

场景 03

Site Failover

DR Signal (105) 专用频道
DR Status 1 → 故障切换中
→ 清除所有缓存数据
DR Status 2 → 切换完成
→ 通过 RFS 重建市场镜像

目标 5 分钟内完成切换

第三章 · 消息处理 · 港交所OMD-C
24 / 25
HKEX · DEVELOPMENT PITFALLS

开发注意事项

心跳处理

MsgCount=0 → 不参与 Gap 检测

心跳 = 包头 + MsgCount=0,不携带序号
SeqNum 设为上一条消息的序号
必须跳过,否则 Gap 检测会误报
仅在线路空闲时发送(有行情时不发)

心跳间隔 2s · 超时阈值可配置

字节序

Little Endian · 与 A 股相反

所有二进制值均为 Little Endian
最低有效字节在低地址
C/C++ 可直接 cast 结构体指针

SSE/SZSE 使用 Big Endian,需注意切换

小数位

固定 / 可变 decimalPlaces

多数价格字段:固定小数位(如 3 位)
部分字段:可变小数位由同消息另一字段定义
例:CallPrice=1234567, Decimals=5 → $12.34567

必须按消息内 Decimals 字段动态还原

第三章 · 消息处理 · 重传流程
25 / 25
RECOVERY FLOW

丢包 → 重传四步

MsgSeqNum 序号跳变或频道记录号不连续时触发重传,不同交易所的重传粒度与通道各异

STEP 01 检测丢包 SSE: MsgSeqNum 序号跳变
SZSE: 频道内记录号不连续
HKEX: PktSeqNum 序号跳变
STEP 02 连接重传通道 SSE L2: VDE 重建行情端口
SZSE: TCP 重传端口 9130
HKEX: RTS TCP 重传服务
SSE L1: ❌ 无重传机制
SSE L2: UA1201请求
STEP 03 请求补传 SSE L2: 产品类别 + 序号范围
SZSE: 390094 · 频道+起止序号
HKEX: RetransRequest · SeqNum
STEP 04 数据恢复 逐笔均可补传,快照均不支持
SSE L1: ❌ 等下一快照周期
HKEX: 快照可等 Refresh 刷新