Skip to content

本文从交易所产生市场事件开始,沿着行情发布系统、交易所接入网络和券商行情网关,一直讲到券商收到原始行情。重点不是行情程序如何解码或构建订单簿,而是先回答一个更基础的问题:量化机构最终使用的行情,在进入券商内部网络之前经历了哪些系统,以及这些系统如何保证数据来源、完整性和可恢复性。

本篇范围:交易所撮合结果成为行情消息,直到券商行情接入节点收到数据。券商内部 UDP 组播、Colo 网络和服务器网卡在下一篇讨论;网卡之后的行情程序处理放在后续系列。

1. 为什么先研究交易所到券商

行情程序出现跳号、断流或延迟突增时,问题不一定发生在行情程序内部。数据可能在更早的位置已经缺失:

  • 交易所行情会话异常;
  • 券商接入链路中断;
  • 券商行情接入节点积压;
  • 主备节点共享同一个上游故障点;
  • 券商收到的数据本身已经不完整。

如果不了解上游链路,系统只能看到“本地少了一条消息”,却无法判断消息究竟是交易所未发布、链路未送达,还是券商未接收。

因此,行情可靠性不是从订单簿程序开始,而是从行情源、接入权限、通信链路和接收节点开始。

2. 本篇的系统边界

本文涉及四类角色:

角色主要职责本文关注点
交易所撮合系统接收申报并形成成交结果产生委托、撤单、成交等市场事件
交易所行情发布系统把市场事件转换为行情产品消息类型、频道、序号、状态和发布会话
交易所接入网络把行情送到市场参与者链路、权限、会话和主备路径
券商行情接入节点接收并验证交易所行情会话维护、完整性检查、恢复和原始记录

本文不讨论:

  • 券商如何向 Colo 客户发送 UDP 组播;
  • 量化服务器网卡如何收包;
  • A/B 消息如何去重合并;
  • Channel 和 Seq 如何驱动订单簿;
  • 行情解码、标准化和订单簿构建。

这些内容需要建立在“上游数据已经可靠到达”的前提上,因此放在后续文章。

3. 撮合系统和行情发布系统不是同一个程序

初学者容易把交易所理解成一台服务器:投资者订单进入交易所,交易所立刻把行情发出来。真实系统通常会明确分离交易处理和行情发布职责。

3.1 撮合系统负责什么

撮合系统负责处理交易申报,例如:

  • 接收买卖订单;
  • 检查申报是否符合交易规则;
  • 按价格和时间优先等规则撮合;
  • 形成成交;
  • 处理撤单;
  • 更新交易状态。

它的核心输出不是给量化机构直接使用的网络包,而是一系列有明确先后关系的市场事件。

3.2 行情发布系统负责什么

行情发布系统把市场事件整理成不同的行情产品,并通过规定的接口对外发布。它通常需要处理:

  • 市场状态;
  • 证券状态;
  • 行情快照;
  • 逐笔委托;
  • 逐笔成交;
  • 频道心跳;
  • 会话心跳;
  • 可恢复数据的重传。

行情发布系统存在的原因是,交易处理和数据分发面对的目标不同。撮合系统强调交易规则与状态正确;行情系统强调大量市场参与者能够连续、及时地收到数据。

4. 券商接入的不是一个模糊的“Level-2”

“Level-2 行情”只是一个宽泛称呼,不能据此判断具体能收到什么数据。实际接入前需要明确行情产品、市场范围和接口版本。

4.1 常见行情类型

行情类型表达的内容是否能还原订单级变化
快照行情某个时刻的盘口和累计统计通常不能
逐笔委托新增、撤销等订单事件取决于协议字段
逐笔成交每笔成交及关联信息取决于协议字段
市场状态集合竞价、连续竞价、休市、闭市等不直接构建盘口,但决定消息语义
证券状态停牌、复牌、风险警示等不直接构建盘口,但影响可交易性

如果只有十档快照,接收端可以看到每个价格档位的聚合数量,但无法知道这些数量由哪些具体订单组成。要构建更精细的本地订单簿,通常需要逐笔委托、逐笔成交以及足够完整的订单标识和事件语义。

4.2 接入前必须确认的清单

  • 行情产品名称;
  • 覆盖的交易所和证券类型;
  • 是否包含逐笔委托、逐笔成交和撤单;
  • 是否包含市场状态和证券状态;
  • 协议版本及生效日期;
  • 价格和数量的单位;
  • 频道划分方式;
  • 序号重置规则;
  • 快照和逐笔分别是否支持恢复;
  • 盘中重新接入时如何同步。

这里最危险的问题不是完全收不到行情,而是只收到部分产品或字段,程序仍然运行,却误以为数据完整。

5. 交易所行情网关是什么

行情网关可以理解为交易所对市场参与者提供的标准化接入边界。券商的用户行情系统与行情网关建立会话,接收规定格式的实时行情。

以上海证券交易所公开的 BINARY 行情网关规范为例,用户行情系统通过 TCP 与行情网关建立会话,登录成功后接收市场状态、快照、逐笔行情和频道心跳;会话中还包含消息序号、心跳和重传机制。该公开接口只是一个具体例子,不能据此推断所有交易所、所有行情产品和所有券商接入方式完全相同。

5.1 会话层解决什么问题

会话层主要负责:

  • 登录与身份确认;
  • 协议版本协商;
  • 判断连接是否仍然存活;
  • 维护会话消息序号;
  • 发现连接异常并重建会话;
  • 对可恢复数据发起请求。

它解决的是“双方是否在正常通信”,而不是完整代替业务层的逐笔连续性检查。

5.2 为什么不能把 TCP 等同于绝不丢数据

TCP 可以保证一个正常连接内的字节流按序到达,但不能解决全部问题:

  • 上游应用可能根本没有生成某条业务消息;
  • 接收程序可能处理过慢,导致上游主动断开;
  • 连接中断后需要重新建立会话和恢复状态;
  • 业务频道仍需用自己的业务序号判断是否完整;
  • 券商内部重新封装后,后续链路可能改用 UDP。

因此,传输协议可靠不等于整条行情业务链路天然可靠。

6. 交易所到券商之间的网络

交易所行情不会经过普通互联网随意传输。市场参与者通常通过受控的接入网络、专用线路或交易所认可的技术服务体系连接行情网关。

从系统设计角度,需要关注的不是线路名称,而是以下属性:

  • 是否存在 A/B 两条物理路径;
  • 两条路径是否经过独立设备;
  • 是否共享同一运营商、机房或光缆;
  • 链路带宽和峰值包速率是否足够;
  • 链路错误、抖动和中断是否可监控;
  • 主备切换后行情会话如何恢复;
  • 网络安全策略是否可能阻断会话或重传。

6.1 “两条线”不一定是真冗余

下面的结构看起来有两条链路,但仍有明显单点:

如果单一上游节点故障,两条链路会同时失效。真正的冗余需要分析完整故障域:

实际拓扑是否达到这种独立程度,需要以交易所和券商提供的正式设计为准,不能只根据服务器上有两个接口进行推断。

7. 券商行情接入节点负责什么

券商行情接入节点是交易所接口和券商内部行情系统之间的边界。它通常接收交易所原始行情,然后把数据交给内部标准化、分发或录制系统。

7.1 输入

  • 交易所实时行情会话;
  • 行情账户和权限;
  • 协议版本配置;
  • 交易日和证券基础信息;
  • 重传或恢复响应;
  • 时间同步信号。

7.2 输出

  • 已接收的原始行情消息;
  • 会话状态;
  • 频道和业务连续性状态;
  • 缺口与恢复状态;
  • 原始行情记录;
  • 供内部系统使用的行情流。

7.3 它负责什么

  • 建立并维护行情会话;
  • 检查消息格式和基础校验;
  • 跟踪连接、心跳和序号;
  • 发现缺口并执行协议允许的恢复;
  • 保存足够的原始证据;
  • 把健康状态传递给下游。

7.4 它不负责什么

券商行情接入节点不一定负责:

  • 为每个 Colo 客户直接发包;
  • 给量化机构构建订单簿;
  • 保证下游交换网络绝不丢包;
  • 保证所有供应商标准化后的字段仍与交易所原始字段一一对应。

这些职责可能属于后续的行情分发、标准化或客户接入系统。

8. 券商接入节点常见的故障

问题直接表现风险解决方向
行情会话未登录完全没有某类行情盘前即不可用权限、地址、版本和登录时点检查
心跳超时或连接断开行情突然停止下游使用陈旧数据自动重连、状态降级、主备切换
接入程序处理过慢延迟上升或被上游断开数据积压和缺失容量测试、进程隔离、队列监控
协议版本不匹配解码异常或字段错位静默数据错误版本绑定、灰度验证、原始包留存
权限不完整部分市场或产品缺失系统误判数据完整盘前产品清单比对
主备共享单点A/B 同时异常冗余失效绘制真实故障域并拆除共同依赖
重传不可用缺口无法恢复下游状态长期不可信独立备用源、缓存和重同步方案

8.1 最危险的是静默错误

完全断流通常很容易发现。更危险的是:

  • 价格倍率错误;
  • 某种消息类型被过滤;
  • 新协议字段没有被识别;
  • 部分频道没有订阅;
  • A/B 两个接入节点使用不同配置;
  • 时间戳来源被错误理解。

这类问题可能不会导致进程崩溃,却会把错误数据持续交给下游。

9. 时间同步从上游就必须开始

在券商接入层,至少可能出现以下时间:

  • 交易所消息中的时间;
  • 券商网络接口接收时间;
  • 券商接入程序读取时间;
  • 券商向内部系统发布时间。

如果时间定义不清或设备未同步,就无法可靠分析:

  • 交易所到券商的传播时间;
  • A/B 哪一路更快;
  • 延迟来自网络还是程序;
  • 主备切换前后的时间变化;
  • 某条异常消息究竟先发生还是后发生。

需要为每个时间戳记录:

text
时间戳名称
生成设备
生成位置
使用的时钟源
精度与分辨率
是否可能回跳
是否与其他设备可比较

延迟计算还应使用单调时钟,避免墙上时间调整造成负延迟或超时判断错误。

10. 上游链路应该监控什么

10.1 行情产品层

  • 当前收到哪些市场和产品;
  • 每类消息的数量;
  • 是否收到市场状态和频道心跳;
  • 盘前预期产品与实际产品是否一致。

10.2 会话层

  • 登录状态;
  • 会话建立和断开次数;
  • 心跳超时;
  • 会话消息序号;
  • 上游主动注销原因;
  • 重传请求和结果。

10.3 业务层

  • 各频道最新业务序号;
  • 缺口、重复和回退;
  • 快照与逐笔活跃状态;
  • 交易阶段是否合理;
  • A/B 节点消息数量差异。

10.4 基础设施层

  • 链路状态;
  • 端口错误;
  • 峰值流量和包速率;
  • CPU、内存和接收队列压力;
  • 时间同步状态;
  • 原始记录是否持续写入。

11. 如何验证交易所到券商链路

11.1 盘前验证

  1. 验证交易日和协议版本;
  2. 验证行情账户和产品权限;
  3. 验证 A/B 节点都能建立会话;
  4. 验证市场状态和频道心跳;
  5. 对比两个节点的消息数量和关键字段;
  6. 检查时间同步;
  7. 确认原始行情录制已启动;
  8. 行情健康状态通过后才允许下游进入就绪状态。

11.2 故障注入

  • 主动断开一条接入链路;
  • 重启一个接入节点;
  • 模拟会话心跳超时;
  • 模拟协议版本不匹配;
  • 模拟某个频道短暂缺口;
  • 验证重传、切换和状态上报;
  • 验证异常期间不会把“连接仍在”误报为“行情完整”。

11.3 盘后对账

  • 对比 A/B 原始消息数量;
  • 统计每个频道缺口和重传;
  • 检查会话中断时间;
  • 分析延迟分布而不只看平均值;
  • 保存协议、配置和节点版本;
  • 对异常时间段执行原始消息回放。

12. 关键设计取舍

12.1 低延迟和可恢复性

为了降低延迟,可以减少缓存和处理层次;但缓存过少会降低突发吸收和恢复能力。接入层不能只追求最快转发,还要保留足够的原始数据和状态,才能在下游发现问题时追溯原因。

12.2 主备热运行和资源成本

冷备节点成本低,但故障后需要建立会话、同步状态和追赶数据。高频场景通常更需要主备节点持续热运行,使备用源始终知道自己是否完整,而不是故障发生后才启动。

12.3 原始协议和内部统一协议

保留原始协议有利于审计和精确追溯,但会增加下游适配复杂度。转换成统一协议便于内部使用,却引入字段丢失、语义转换和版本管理风险。后续文章会单独讨论券商内部如何选择透传、标准化或重建后分发。

13. 仍需向交易所或券商确认的问题

以下信息不能通过通用架构推断,必须以正式接口文档和现场拓扑为准:

  • 实际行情产品及协议版本;
  • A/B 接入节点是否对应独立上游发布节点;
  • 两条线路是否真正物理独立;
  • 逐笔和快照的恢复机制;
  • 可恢复历史长度;
  • 券商接入节点是否重新编号或过滤消息;
  • 券商内部是否保留交易所原始 Channel 和业务 Seq;
  • 时间戳的生成位置;
  • 市场参与者可获得哪些上游监控信息。

未获得正式资料前,这些内容都应标记为“未确认”,不能写成既定事实。

14. 下一篇:券商如何把行情送入 Colo

券商收到交易所行情后,通常还要经过内部行情总线、分发节点、UDP 组播、A/B 交换网络和 Colo 接入交换机,最终到达量化服务器网卡。

下一篇将讨论:

  • 券商原始透传、标准化和订单簿输出的区别;
  • UDP 组播为什么适合一对多行情分发;
  • A/B 双路、双节点和双源如何区分;
  • VLAN、IGMP、交换机缓存和微突发;
  • 光纤、光模块和服务器网卡前的故障定位。

参考资料

本文仅为个人学习笔记和系统架构设计整理,不构成任何投资建议或交易建议。高频量化交易系统涉及市场风险、技术风险、合规风险和运维风险,任何实盘部署都应经过充分测试、独立验证和风险评估。

Last updated:

Powered by VitePress. Written with AI, reviewed by human.