综合

实时行情监控重连成功了,但那 3 分钟的跳变正在污染你的异动检测

作者: TickDB Research · 发布: 2026/6/12 · 阅读: 9

标签: W23-Q03, 知乎 / A005 https://zhuanlan.zhihu.com/p/2048805398036079841

凌晨 2:15:03,WebSocket 行情连接断开。2:18:12,重连成功。日志里安静地躺着 disconnectedreconnected,系统继续运行。

2:18:13,异动告警触发:某个品种瞬间涨了 2.1%。你被叫醒,打开看盘软件,价格确实变了。你开始排查市场原因。

!image.png

但这不是市场冲击。是你的系统在 3 分 09 秒的空窗期内漏掉了数十次价格变动,重连瞬间把它们压缩成了一次跳变。你的告警系统抓住的,是自己断线的证据。

重连成功只代表通道重新建立,不代表断线窗口的数据已经恢复。系统若把空窗两端的价格直接相连,就可能把累积变化误判成一次异动。


监控结果是否可信,不只取决于重连代码是否健壮。

它也取决于你的数据源能否同时提供三种能力:当前状态校准、历史轮廓查询、持续行情接收。三个能力缺一个,断线恢复就容易出现盲区——你以为接上了,数据还断着。


一、断线三分钟,系统在经历什么

!image.png

把行情数据想象成一条传送带。你每隔几秒取下一个包裹,按顺序登记价格。

传送带停了 3 分 09 秒。重新启动后,下一个包裹写着当前价格。上一个被你登记的包裹,写着 3 分 09 秒前的价格。两个包裹之间不是空的——这段时间的交易全部从传送带上掉了下去。

但如果你只看手里这两个数字——21.50 和 21.95——你会自然认为 0.45 是一次连续变化。统计模型把它当正常波动,异动检测拿它跟阈值比较。

这就是重连后系统在做的事:把时间上不连续的两个点,当成序列中相邻的观测值。

这个错误有三个层次:

断线窗口。 从断线到重连的时间区间。它一定存在,长度取决于重连策略和服务端状态。

数据空洞。 窗口内所有本应收到的数据全部缺失。“价格没变”是可记录的平盘,“不知道发生了什么”是不可记录的盲区。前者让计算继续,后者应该让系统暂停。

重连后状态漂移。 空洞两端的价格差值被当成连续变化,污染下游的波动率计算、均线更新和异动告警。数据来自正常的 WebSocket 帧,但在应用层是一次未经校准的跳变。


二、为什么重连成功不等于恢复连续

大多数监控脚本的逻辑是:断线 → 重连 → 继续跑。这个链条里缺了一个环节。

WebSocket 协议保证消息的完整性和有序性,但不保证连续性。它不承诺缓存断线期间的消息,也不承诺重连后首条数据与断线前最后一条数据之间有时序关系。

重连是传输层的握手。连续性是应用层要自己解决的问题。

重连成功后,你收到的是重连后的第一条行情数据。它只能说明系统重新开始接收数据,不能证明它与断线前数据连续,也不能证明断线期间的数据已经补齐。

检验标准很简单——你的日志能否回答三个问题:

  • 断线发生在什么时间?
  • 重连发生在什么时间?
  • 空窗内每个品种的价格跳变了多少?

前两个问题 WebSocket 库能记录,第三个需要你主动做对账。


三、重连恢复不是一个事件,而是一段流程

大多数系统把重连当成事件处理:on_reconnect 回调触发,打一行日志,继续跑。这等于把一段需要时间来处理的对账过程,压缩成一个毫秒级的信号。

断线 3 分 09 秒,市场继续运行,产生了数十次价格变动。系统在重连那一毫秒就宣布"恢复了"——它不可能在那一毫秒内处理完 3 分 09 秒的信息缺失。

重连恢复不是一个时间点上的事件,而是一个时间区间里的流程。

把重连设计成流程,不是事件。这个流程有起始条件、持续时间、结束条件和失败出口。不做校准,重连流程就没走完。


四、三步校准:不是恢复,是对账

!image.png

重连后要做的第一件事,不是继续跑策略,是校准——搞清楚你错过了什么,手里的新数据能不能信。

完成这套校准,最好能在同一数据源中获得当前快照、历史轮廓和持续行情流。

跨源对齐会引入额外复杂度——不同数据源的 symbol 格式、时间戳精度、价格口径可能各不相同。用一个数据源完成校准全流程,比用三个数据源分别完成再拼起来,要干净得多。

步骤做什么为什么这一步必须在继续之前
第一步:当前状态对齐用 REST 拉 ticker 快照,与 WebSocket 重连后首条数据做交叉对照提高对当前状态的确认度;即使二者一致,也只说明当前状态大体对齐,不代表断线空窗被恢复
第二步:标记数据空窗记录断线和重连时间戳,写入审计日志,明确标记为空窗区间让下游知道这段时间数据不可信。空窗标记是"不可用"戳,不是"留空等填"的占位符
第三步:有限影响评估在支持的周期和时间范围内,拉取覆盖空窗的历史 K 线或聚合数据,用 OHLC 评估影响OHLC 能帮助评估空窗内的价格范围和波动量级。OHLC 不能还原区间内的变化顺序,K 线不能替代逐笔数据

三步之间有顺序。先对齐当前坐标,再标记不可信区间,最后用有限历史信息评估影响。


TickDB 在这个场景中的位置:

断线恢复校准三通道
├── REST   → 当前状态参照(对齐坐标)
├── K 线    → 空窗轮廓评估(评估影响范围)
└── WebSocket → 恢复后持续行情接收(继续跑)

三种通道是分工,不是互相替代。

  • REST 快照能帮你确认"现在在哪",但不能补齐断线窗口
  • K 线能帮你评估"空窗内波动有多大",但不能还原逐笔顺序
  • WebSocket 恢复推送后,校准未完成前不应触发异动告警

若只是单次、低频、单市场查询,轻量方案可能已经够用。只有需要持续监控和断线校准闭环时,这套分工才更有价值。

三步全部完成前,异动检测应暂停或标记为"未校准"。重连瞬间的价格跳变天然容易越过异动阈值——你不先区分"市场变化"还是"断线跳变",告警就会混入假阳性。


五、四个最容易踩的坑

坑一:用本地接收时间冒充市场时间。 重连后给数据打本地时间戳,与断线前的市场 timestamp 比较——两个时钟,偏差可能从毫秒到秒级。校准时统一使用行情数据中的 timestamp 字段。

坑二:把跳变误报成异动。 重连瞬间的跳变幅度常超过异动阈值。处理方式:刚从断线恢复时,首条数据不触发告警或标记为"待确认"。阈值是策略参数,断线跳变是数据质量事件,两者不应混在一个判断里。

坑三:把 K 线回补当逐笔恢复。 K 线提供 OHLC,不提供区间内的变化顺序。可以用它评估空窗严重程度,但不能当成数据已恢复完整。

坑四:认为重连成功就万事大吉。 TCP 握手完成、WebSocket 升级完成、新数据开始推送——只证明你又能收到数据了,不证明连续性。把传输层成功当成应用层恢复,是最根深蒂固的断线 bug。


六、把校准写进系统,不是写进备忘录

前置条件化。 维护一个状态机:正常 → 断线中 → 恢复校准中 → 正常。只在"正常"状态下输出异动结果。

结构化审计。 记录断线时间、重连时间、空窗时长、受影响品种、快照对齐结果、跳变幅度、是否触发假异动。

函数化。 写成 reconnect_calibrate(),重连事件触发时自动执行。失败告警,通过才放行策略。


重连后校准检查卡

  • [ ] 已记录断线时间和重连时间,精确到秒
  • [ ] 已通过 REST 快照与 WebSocket 重连后首条数据做交叉对照
  • [ ] 已标记断线区间为数据空窗,下游消费者可见
  • [ ] 已拉取空窗区间历史数据,记录 OHLC 评估影响
  • [ ] 已检查重连瞬间价格跳变幅度,判断是否为假异动
  • [ ] 异动检测在恢复校准完成后才恢复正常输出
  • [ ] 断线事件已写入结构化审计日志

不能从本文推出什么

  • 本文讨论的断线恢复方法——状态对齐、标记空窗、有限回补——是通用工程实践,不依赖特定行情 API。文中以 TickDB 的 REST、K 线和 WebSocket 通道分工作为可复核示例,不代表其他 API 有相同通道或行为。
  • 本文不构成投资建议,不讨论任何策略的收益、有效性或买卖决策。
  • 本文不涉及具体延迟数字、SLA 条款、不断线或不漏数据的承诺。
  • 三步校准解决的是重连后的状态对账问题,不是数据完整性恢复。K 线回补不能替代逐笔数据。需要逐笔精度的策略,断线空窗无法被完全修复,只能被标记和评估。
  • 文中提到的 TickDB REST、K 线和 WebSocket 的具体端点路径、参数和返回字段,均以 TickDB 官方文档为准,本文不自行补充。

你的监控脚本,重连之后第一件事是做什么?继续跑策略,还是先做一次对账?

如果你已经在日志里记录了断线和重连时间,但还没加上第三步——拉 K 线看一眼空窗区间里到底发生了什么——可以在下次维护窗口里加上。

想复现本文中的校准流程,可查看 TickDB 的 REST、K 线和 WebSocket 文档,或申请试用 Key 做一次模拟断线测试。


通过 TickDB API 获取实时行情数据

一个 API 接入外汇、加密货币、美股、港股、A股、贵金属和全球指数的实时行情。支持 WebSocket 低延迟推送,免费开始使用。

免费领取 API Key查看 API 文档

相关文章