# 数据修准影响面证据（Mac 实操侧 → 研究侧 / Owner 裁决用）

- 日期：2026-09-14 · 我方 head：`d9af457`（本文档随其后新提交）
- 背景：研究侧 0914 对账指出两端 baseline/model 不同构（我方 6013 / 对方 5853 行，共有键 5810，仅我方 203 / 仅对方 43），
  并提出二选一：**方案 A**（baseline 也回退到记录版 88438d5^）或 **方案 B**（两端采纳数据修准 + 版本号 + 生效日 + 全历史重验）。
  本文给出判据，结论是 **B**。

## 1. 数据修准到底改了什么（字段级，来自修复清单，可复跑）

清单文件：`code/_repair_manifest_20260913_1434.csv.gz`（三列）、`code/_adjfactor_manifest_20260913_1505.csv.gz`（因子轮1）、`code/_adjfactor_manifest_20260913_1514.csv.gz`（因子轮2）。字段：`code,trade_date,field,old,new`。

| 字段 | 改动行数 | 涉及股票 | 中位 \|Δ\| | p90 \|Δ\| | 最大 \|Δ\| | 中位相对差 |
|---|---|---|---|---|---|---|
| `pre_close` | 344,068 | 284 | 0.910 | 17.020 | 777.140 | 5.50e-02 |
| `change` | 233,177 | 284 | 0.020 | 0.460 | 114.420 | 9.21e-02 |
| `pct_chg` | 176,857 | 281 | 0.025 | 0.081 | 0.532 | 2.30e-02 |
| `adj_factor`（轮1，逐日对齐 tushare） | 6,577,268 | 4,172 | 7.30e-05 | 6.76e-04 | 3.138 | 2.25e-05 |
| `adj_factor`（轮2，tol=0 收尾） | 69,486 | 2,971 | 1.0e-06 | 1.0e-06 | 1.0e-06 | 6.66e-07 |

- 三列脏区**集中在 hs300 副本的 284 只**（早期推算残值）；因子修正**遍布全库 4,172 只**（旧值为内部 6dp 推算链，新值为 tushare 按日真值）。
- 可复现示例（修前 → 修后）：
  - `000001.SZ 20210104` `pre_close` 15.45 → **19.34**；`000001.SZ 20210105` `pre_close` 14.86 → **18.60**
  - `000001.SZ 20210104` `adj_factor` 111.100274 → **111.049**（相对 4.6e-04）
  - `920593.BJ 20220701` `adj_factor` 0.1564 → **1.02**（相对 5.52 倍，最大相对差样例）

## 2. 这些字段是否进判定链（代码级）

- `pre_close`：**不进链**。`code/exdiv_judge.py` 与 `code/update_daily.py` 头部明文禁用（"不要用 A=(raw_close/pre_close-1)*100 参与判定"）。
- `change`：**不进链**（仅落盘记录）。
- `pct_chg`：**进链** —— `grid_or.signal_detect` / `scan_daily_tb` 用它判 T0 涨停（阈值 `LIMIT_UP = main 9.9 / gem 19.9 / star 19.9 / bj 29.9`）。
  在 176,857 行修正中，**跨阈值 61 行**（翻为涨停 48 / 翻离涨停 13）→ 这些日的 T0 选择可能改变。
- `adj_factor`：**进链**（`hfq = raw × factor`，判定/链特征全走 hfq）。

## 3. 隔离实验（决定性：变化来自数据修准，还是重建路径？）

做法：用**当前（修准后）**数据在**不改任何文件**的前提下重跑交易集生成（`build_strength_v4` 的 trades 生成段：`g.build_sig` + `ie.ideal_backtest` + `chain_for_buy`），
把得到的键集合分别与「记录版 `88438d5^` baseline 5837 键」「重建版 `88438d5` baseline 5776 键」对拍。

| 对照 | 交集 | 仅重跑有 | 仅该版有 |
|---|---|---|---|
| 记录版 `88438d5^`（5837） | 5573 | 213 | **264** |
| 重建版 `88438d5`（5776） | **5775** | 11 | **1** |
| 现行 HEAD（5997，含回补行） | 5775 | 11 | 222 |

重跑结果：hs300 189 / zz500 304 / zz1000 1250 / zz2000 4193 = **5786 键**。

**判读**：当前数据重跑 ≈ 重建版（交集 5775，只差 11 只），而离记录版差 264+213。
⇒ **5837 → 5776 的变化由数据修准本身造成，不是重建路径的副产品**；记录版 baseline 是**基于旧（脏）数据**的产物。
⇒ 因此 baseline 回退到记录版（方案 A）会把脏数据算出的交易集带回来 → **应走方案 B**。

## 4. 我方现状与建议

- **模型**：已恢复为**记录版 14 键**（`88438d5^` 的 `strength_model.json`，其 weights 与研究侧分支逐键相同：f12 0.0560 / f13 -0.0519 / f14 0.0002）。
  注意：**不能用 `build_strength_model_v3.rebuild()` 去重建 14 特征模型** —— 它从现行 baseline 重算权重（f1~f11 全体漂移，f4 0.1801→0.1872），且池级三特征退化成 0.8。
- **baseline**：回测区（5,776 键）已是修准后数据的产物；近端 221 行是**历史实盘记录**（两端 nav 逐日一致：0911 = 90,849.65，0914 = 90,297.81 逐值相同），**不动**。
- **建议（属 Owner 红线，需其裁定）**：方案 B ——
  1) 两端各自**基于修准后数据重建 baseline + 百分位表**（对端那份"我方 baseline 存量陈旧待重建（0913 裁定待办）"即此项）；
  2) 加**版本号 + 生效日**（建议 `data-v2`，生效日 = 两端重建完成日）；
  3) 全历史重验：模拟盘 nav（0901 起逐日，两端互对）、四文件对账、滚动窗口/月度分布重解读（强度分组会变）。
- **遗留小项**（我方自查，稍后清理）：`strength_baseline.csv` 残留 `f12_crowd_pool_x/_y`、`f13_pool_zt_x/_y`、`f14_pool_avgret_x/_y` 六个**全空**列（早期 merge 残留），下文重建时一并去掉。

## 5. 复跑命令（脚本已入仓）

```bash
cd ~/zt_app
python zt_venv/bin/python code/chk_datarepair_impact.py   # 字段级统计(读 code/_repair_manifest_*.csv.gz)
python zt_venv/bin/python code/chk_keyset_isolation.py    # 隔离实验(只读, 不写任何文件; 全四池回测约 2 分钟)
```
