Skip to content

修复同步后停牌残留反复触发完整性修复 - #213

Open
yushenglin01 wants to merge 1 commit into
shy3130:mainfrom
yushenglin01:fix/realtime-integrity-residue
Open

修复同步后停牌残留反复触发完整性修复#213
yushenglin01 wants to merge 1 commit into
shy3130:mainfrom
yushenglin01:fix/realtime-integrity-residue

Conversation

@yushenglin01

Copy link
Copy Markdown

问题与复现

开启实时行情时,历史完整性门禁会把已完成 batch 同步的日期继续判定为停机前盘中快照,并反复创建修复任务。实际分区主体已是权威 batch 数据,仅残留极少数停牌股票在 09:15 写入的零成交实时行。

根因

  • 实时日 K 构建先把 open/high=0 填成昨收价,导致停牌零成交记录被伪装成有效日 K。
  • batch 同步会过滤停牌日,但 merge-upsert 不会删除未返回的旧实时行。
  • 完整性检测只取分区最大的 quote_ts;任意一条当日 15:00 前记录都会把整个分区判为快照。
  • 旧版已经填充 OHLC 的零成交记录无法被原有 open/high=0 停牌判据过滤。

解决方案

  • 实时日 K 在 OHLC 填充前复用停牌过滤,阻止新的零成交停牌行落盘。
  • 完整性检测二次检查可疑分区:有成交活动的实时行仍判为快照;权威 batch 行占主体且仅夹杂零成交实时行时视为已修复;整分区盘前快照仍保持拦截。
  • 停牌过滤兼容 volume=0amount=0 的历史遗留行,避免污染 MA、ATR 等指标。
  • 增加误判、盘前快照、历史兼容和实时门禁日期边界回归测试。

兼容性

  • 不改变 API、配置、Parquet schema 或数据源契约。
  • 不删除用户数据;历史遗留行在读取和计算边界被安全过滤。
  • 股票、ETF、指数共用既有日 K 停牌过滤规则。

性能

正常全 null 或收盘后分区仍只读取 Parquet 元数据。只有最大 quote_ts 命中盘中时才读取 quote_ts/volume/amount 三列做二次判定;该逻辑只在启动检查、开启实时行情和管道完整性检查时执行,不进入实时轮询热路径。

验证

  • uv run --frozen pytest tests/test_data_integrity.py -q:29 passed
  • 相邻 indicators/enriched 测试:37 passed
  • 相邻 quote/settings/preferences 测试:21 passed
  • uv run --frozen ruff check --select F ...:通过
  • git diff --check:通过
  • 使用实际问题数据扫描:current_data_issues=[]
  • Docker 容器内扫描:container_integrity_issues=[],HTTP 200

界面证据

本 PR 无前端界面改动。修复前开启实时行情会提示 2026-08-24、2026-08-26、2026-08-27 为盘中快照;修复后同一数据目录扫描为空,不再创建重复修复任务。

风险与回滚

主要风险是第三方数据源将零成交日作为有效交易日返回;当前仅在 volumeamount 同时为 0 时按停牌过滤,并保留“可疑实时行占主体”时继续 fail-closed 的门禁。回滚可直接撤销本提交,未引入数据迁移。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant