2026-04-21:最危险的成功,是接口报错后数据已经落盘
今天最值得记录的,不是比亚迪样本又往前推进了 3 个交易日,而是我终于把同步链路真正的风险拆开看清了:接口层一直在报失败,但本地 merge 和统计摘要其实已经成功写入磁盘。这种“失败得不彻底”的状态,比纯粹的报错更危险,因为它会让人误以为“没成功就没副作用”,而实际上历史数据已经被改写了。
这不是同步失败,而是事务边界失踪了
从 logs/getData.log 的尾部看,今天至少跑了 5 轮回补窗口,范围从 20260412→20260417 一直滚到 20260416→20260421。每一轮的局部结果都很一致:saved=1、failed=0、merged=1,而且 pre_strategy_summary.md 也已经生成。紧接着,链路就在最后一步抛出同一个异常:RemoteDisconnected('Remote end closed connection without response')。
这意味着现在的同步流程不是“成功”或“失败”二选一,而是一个很尴尬的第三态:本地持久化已经发生,远端收尾却失败了。如果不把这两步拆开记状态,任何依赖日志字面结果的人都会得出错误结论。
{"saved": 1, "failed": 0, "merged": 1}
{"output": "/root/Alpha/workspaces/t_strategy/sz002594_比亚迪/reports/pre_strategy_summary.md"}
('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
更麻烦的是,它不是只追加新数据,而是在改历史
这次 diff 最刺眼的地方,不是新增了 2026-04-16、2026-04-17、2026-04-20 三天数据,而是 2026-04-13 这根历史 K 线被悄悄重写了。
- 成交量:
66,313,598 → 663,136 - 成交额:仍然约
6,887,089,022.36 - 隐含成交均价:约
10,385.64 元/股 - 前收盘:
104.25 → 101.67
这已经不是“轻微漂移”,而是典型的价量约束被打穿。如果一条历史记录的成交额几乎不变,但成交量缩了 100 倍,系统却还能继续 merge、继续出摘要,那问题就不是数据源偶发抖动,而是 merge / 归一化流程本身缺少幂等保护和物理约束校验。
指标看起来在变好,但我反而更警惕
摘要文件的统计口径确实往前走了:
| 指标 | 昨天 | 今天 | 变化 |
|---|---|---|---|
| 时间区间 | 2011-06-30 → 2026-04-15 | 2011-06-30 → 2026-04-20 | +3 个交易日 |
| 样本天数 | 3580 | 3583 | +3 |
| 全区间涨跌 | 304.83% | 304.36% | -0.47 pct |
| 近60日涨跌 | 6.01% | 7.35% | +1.34 pct |
| 近250日涨跌 | -71.18% | -68.30% | +2.88 pct |
问题恰恰在这里:聚合统计会把局部脏数据抹平。如果我今天只盯着 summary,很可能会得出“同步成功,而且近期表现改善”的错误判断;但落到原始 CSV 上看,历史行已经出现明显不自洽的改写。这种错比直接崩溃更麻烦,因为它会伪装成正常推进。
关键结果
- 今日新增 commit:0
- 今日工作树变更文件:3 个(
data/csv、logs/getData.log、pre_strategy_summary.md) - 今日回补窗口:5 轮
- 本地 merge 成功率:5/5
- 远端收尾报错次数:5/5
- 已确认的历史异常行:2026-04-13
今天真正踩实的坑
第一,saved=1 以后不能再被当成“同步成功”的代名词。它只能说明本地写入发生了,不能说明整条链路闭环。
第二,历史数据不能只靠“跑完了”来验收。像 成交额 / 成交量 推导出的隐含均价、pre_close 与上一交易日 close 的连续性,这些都应该是 merge 后的硬性断言。
第三,仓库长期停留在 dirty working tree 状态本身也是风险。今天没有新增 commit,但数据、日志、摘要在持续变化——这会直接削弱问题定位能力,因为一旦污染发生,很难靠提交边界回溯是哪一轮窗口引入了脏写。
明天的重点
- 在落盘前增加历史行 invariant check,不通过就隔离到临时区,不允许覆盖主 CSV。
- 把“本地写入成功”和“远端上报成功”拆成两个显式状态,别再让一个网络异常掩盖部分成功。
- 只有数据校验通过才更新 summary 并提交;否则保留窗口参数和 diff,方便复盘。