LabHub
学习 学习路径 课程

资本市场与清结算

处理行情源的缺口与延迟

在 LabHub 中继续学习

目标

区分行情源捕获中真正丢失的数据与延迟到达的数据;通过 A/B 仲裁区分可补齐的数据与真正的缺口;使用百分位数度量延迟,定位尾部集中区间;并能够为不同区间确定恢复方式。

为什么重要

行情源建立在既不保证顺序也不保证到达的传输之上,因此接收方必须根据序号进行判断。如果判断方式错误,问题不会悄无声息地过去,而会堵塞线路。若按到达顺序统计缺口,结果会比实际值高出五倍以上;按这个数量请求重传,又会增加请求流量并加剧延迟,延迟进一步增加乱序,使缺口看起来更多。

本练习强制执行的四点都是实际现场规则。缺口按集合判断——晚到不等于丢失,仅凭到达顺序无法区分两者。请求重传前先查看另一个通道——这正是部署冗余的原因,无需请求即可补齐的比例占绝大多数。通过尾部观察延迟——平均值会把两个世界混合成一个数字。将计算方式写入文件——百分位数定义不同,同一数据就会得出不同结论,从此讨论的不再是数据,而是定义。

本次捕获覆盖 2026-08-27 开盘后约 11 分钟。交易所发送的原始数据从序号 1 到 12000,没有缺口;我们通过 A、B 两个通道接收。两个通道都发生了丢包,并且在开盘后不久以及 09:08 左右出现了显著的延迟峰值。

百分位数按如下方式计算——最近秩法。将值按升序排列后,取第 idx = ceil(p * n / 100) 个值(从 1 开始计数)。使用 Python 整数时为 lat[(p*n + 99)//100 - 1]。平均值用总和除以数量后向下取整。延迟分析仅以通道 A 为对象;如果同一个 seq 到达多次,只使用最先到达的一条

步骤

  1. 创建 /root/cap/feed,原样运行答案中的生成器,生成 /root/cap/feed/feed.jsonl。若更改随机种子,结果将与评分值不符。
  2. /root/cap/feed/shape.txt 中写七行:lines=ch_a_lines=ch_b_lines=ch_a_unique=ch_b_unique=ch_a_dup=seq_max=
  3. /root/cap/feed/gaps.txt 中写入 arrival_jumps_a=missing_a=missing_b=gap_runs_a=;将通道 A 未收到的序号按连续区间分组,写入 /root/cap/feed/gaps_a.csv,表头为 from_seq,to_seq,count
  4. /root/cap/feed/arb.txt 中写入 recoverable_from_b=true_holes=hole_runs=;将两个通道都未收到的区间写入 /root/cap/feed/holes.csv,格式为 from_seq,to_seq,count
  5. /root/cap/feed/latency.txt 中写入 method=nearest_rank 以及 n=p50_us=p95_us=p99_us=max_us=mean_us=
  6. ts_send 所在分钟分桶,在 /root/cap/feed/tail.csv 中写入 minute,n,mean_us,p99_us,over_10ms,并在 /root/cap/feed/tail.txt 中写入 worst_minute=worst_p99_us=over_10ms_total=burst_minutes=minute 是以 09:00 为 0 的整数,burst_minutes 则用逗号连接平均值超过 10ms 的分钟。
  7. 针对每个真正的缺口区间,在 /root/cap/feed/retx.csv 中写入 from_seq,to_seq,count,action。连续 5 个以上时使用 snapshot,少于 5 个时使用 retransmit。在 /root/cap/feed/retx.txt 中写入 retransmit_runs=retransmit_seqs=snapshot_runs=snapshot_seqs=
  8. /root/cap/feed/report.md 中编写报告。需要 ## 무슨 일이 있었나## 갭## 지연## 돈으로 얼마인가## 무엇을 고쳐야 하나 五个章节。

参考

创建 A/B 冗余行情源捕获

创建 /root/cap/feed,原样运行答案中的生成器,生成 /root/cap/feed/feed.jsonl。若更改随机种子,结果将与评分值不符。

原样运行生成器即可。若更改随机种子,结果将与评分值不符。

统计各通道的接收数量和重复项

/root/cap/feed/shape.txt 中写七行:lines=ch_a_lines=ch_b_lines=ch_a_unique=ch_b_unique=ch_a_dup=seq_max=

分别统计各通道的行数和不同 seq 的数量。如果两个数字不同,其差值就是重复数量。

区分丢失与延迟到达

/root/cap/feed/gaps.txt 中写入 arrival_jumps_a=missing_a=missing_b=gap_runs_a=;将通道 A 未收到的序号按连续区间分组,写入 /root/cap/feed/gaps_a.csv,表头为 from_seq,to_seq,count

使用两种方式统计:一是按到达顺序读取,统计 seq 跳跃幅度大于 1 的位置;二是统计 1..12000 中该通道一次也未收到的序号。

使用通道 B 补齐,只留下真正缺口

/root/cap/feed/arb.txt 中写入 recoverable_from_b=true_holes=hole_runs=;将两个通道都未收到的区间写入 /root/cap/feed/holes.csv,格式为 from_seq,to_seq,count

从通道 A 未收到的序号集合中减去通道 B 已收到的序号,就是真正的缺口。再将这些序号按连续区间分组。

计算延迟百分位数

/root/cap/feed/latency.txt 中写入 method=nearest_rank 以及 n=p50_us=p95_us=p99_us=max_us=mean_us=

仅使用通道 A,并且每个 seq 只取最先到达的一条。百分位数采用最近秩法——升序排列后取第 ceil(p*n/100) 个值。平均值使用整数除法向下取整。

定位尾部集中的区间

ts_send 所在分钟分桶,在 /root/cap/feed/tail.csv 中写入 minute,n,mean_us,p99_us,over_10ms,并在 /root/cap/feed/tail.txt 中写入 worst_minute=worst_p99_us=over_10ms_total=burst_minutes=minute 是以 09:00 为 0 的整数,burst_minutes 则用逗号连接平均值超过 10ms 的分钟。

按 ts_send 所在分钟分桶,分别计算每个桶的数量、平均值、p99 和超过 10ms 的数量。平均值超过 10ms 的分钟即为 burst。

区分重传与快照

针对每个真正的缺口区间,在 /root/cap/feed/retx.csv 中写入 from_seq,to_seq,count,action。连续 5 个以上时使用 snapshot,少于 5 个时使用 retransmit。在 /root/cap/feed/retx.txt 中写入 retransmit_runs=retransmit_seqs=snapshot_runs=snapshot_seqs=

按长度划分第 4 步得到的真正缺口区间。连续 5 个以上时使用 snapshot,少于 5 个时使用 retransmit。

编写行情源质量报告

/root/cap/feed/report.md 中编写报告。需要 ## 무슨 일이 있었나## 갭## 지연## 돈으로 얼마인가## 무엇을 고쳐야 하나 五个章节。

需要五个章节。延迟章节必须包含 p99;措施章节则要说明要更改缺口判断方式、监控指标和去重中的哪一项。