diff --git a/CLAUDE.md b/CLAUDE.md index 9465f32..d0f0e9d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,7 +57,7 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri ## 开发约定 - **交流中文**;代码/注释/commit message 用**英文**。 -- **Git**:feature 分支 + PR。**PR #1(P0+P1)、#2(P2-1)、#3(P2-2)、#4(进度文档)、#5(P2-3)、#6(进度文档)、#7(P2-4)、#8(进度文档)、#9(P3-1)、#10(进度文档)、#11(P3-2)、#12(P3-3)、#13(进度文档)、#14(P3-4)、#15(进度文档)、#16(P3-5)、#17(进度文档)、#18(P3-6)、#19(P3-7)、#20(进度文档)、#21(P3-8)、#22(进度文档)、#23(P4-1)、#24(进度文档)、#25(P4-2)、#28(tushare 权限/限频探测 + capability registry)、#29(I1–I4 分钟级 intraday pipeline,4 commit 一 PR)、#30(进度文档)、#31(P4-3 因子支撑端点缓存 + 21:00 data updater,2 commit 一 PR)、#33(P-I5a 事件驱动回测架构重构 + opt-in 分钟尾盘 event model,4 commit 一 PR)、#35(P-I5b 分钟尾盘执行期 raw stk_limit 涨跌停可行性,4 commit 一 PR)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)、#45(数据层 D3 report-only 数据质量层)、#47(数据层 D3b default-off `data-update` 质量报告钩子)、#49(数据层 D4 coverage ledger 批量写 + 进程内查找缓存)、#51(数据层 D5 opt-in 有界并发 + 全局限频器)、#53(P-I5e MMP 五分位 CSI300 独立泛化检验,负结果)、#55(P-I5f 分钟尾盘执行流动性/容量诊断,report-only)、#57(数据层 schema 注册表 + default-off drift 守卫)、#59(数据层 全A 增量 auto-warm + systemd 定时,default-off)、#61(数据层 全A 历史回填 `data-backfill`,分块/续跑/失败隔离)均已 merge 到 `main`**。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 +- **Git**:feature 分支 + PR。**PR #1(P0+P1)、#2(P2-1)、#3(P2-2)、#4(进度文档)、#5(P2-3)、#6(进度文档)、#7(P2-4)、#8(进度文档)、#9(P3-1)、#10(进度文档)、#11(P3-2)、#12(P3-3)、#13(进度文档)、#14(P3-4)、#15(进度文档)、#16(P3-5)、#17(进度文档)、#18(P3-6)、#19(P3-7)、#20(进度文档)、#21(P3-8)、#22(进度文档)、#23(P4-1)、#24(进度文档)、#25(P4-2)、#28(tushare 权限/限频探测 + capability registry)、#29(I1–I4 分钟级 intraday pipeline,4 commit 一 PR)、#30(进度文档)、#31(P4-3 因子支撑端点缓存 + 21:00 data updater,2 commit 一 PR)、#33(P-I5a 事件驱动回测架构重构 + opt-in 分钟尾盘 event model,4 commit 一 PR)、#35(P-I5b 分钟尾盘执行期 raw stk_limit 涨跌停可行性,4 commit 一 PR)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)、#45(数据层 D3 report-only 数据质量层)、#47(数据层 D3b default-off `data-update` 质量报告钩子)、#49(数据层 D4 coverage ledger 批量写 + 进程内查找缓存)、#51(数据层 D5 opt-in 有界并发 + 全局限频器)、#53(P-I5e MMP 五分位 CSI300 独立泛化检验,负结果)、#55(P-I5f 分钟尾盘执行流动性/容量诊断,report-only)、#57(数据层 schema 注册表 + default-off drift 守卫)、#59(数据层 全A 增量 auto-warm + systemd 定时,default-off)、#61(数据层 全A 历史回填 `data-backfill`,分块/续跑/失败隔离)、#62(进度文档)、#63(因子评估契约层 `analytics/eval/` + StandardFactorEvaluator + dashboard + PR-C 因子,4 commit 一 PR)、#64–#73(PR-D…PR-M 十个分钟因子复现,**一因子一分支一 PR**)、#74(因子评估契约 v0.8 + v0.9 判定门修复)、#75(尾盘执行价 VWAP + 分钟持有期收益复权)、#76(报告披露修正 + I5f 名义按真实规模重测)、#77(`adj_factor` 下降质量检查)均已 merge 到 `main`**;**OPEN 未合并:#38**(见 P-I5d 处置,未获授权关闭)、**#78**(#76 的 follow-up:扫描式正则守卫被七种改写实测证否 → 闸门描述改单一来源)、**#79**(十一因子改 14:51 VWAP exec-to-exec 基准)。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 - **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。 - **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。 - 文件小而专(<800 行),immutable 优先。 @@ -267,6 +267,92 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - **`start > today` 守卫**:逆序窗口本会被 `subtract_intervals` 当"零缺口=已覆盖"→ 未来 start typo 静默 no-op;故加 loud `ValueError`(仿 `DataCfg._check_date_order`)。config `data_update.backfill: {start, chunk_size, include_minute}`(全默认 → 现存配置照常 validate);`config/data_update_all_a.yaml` 加 `backfill:` 块 + 诚实成本注(冷全A 分钟回填数小时~多日,可续跑)。ops doc 加"历史回填"节(先回填再 enable 夜间 timer)。 - **不变量**:增量 `run_data_update` 路径**字节级不变**——唯一共享改动是 `_build_scheduler`/`_build_caches` verbatim 抽取(same kwargs/顺序);49 个既有 data_update 测试原样过(main-vs-branch pytest 对照 **771→793 恰好 +22、0 既有测试被动**)。phase0 `0.9600/0.8408` 不变;缓存仍 raw-only;无 token。 - **review 两轮**(cc 接替外部 reviewer 验收):security CLEAN(失败/进度日志只 counts+异常类型);code-review 无 CRIT/HIGH(共享重构 verbatim 验证),修 2 MEDIUM(`start>today` 静默 no-op 守卫 + 失败×续跑联合测)+ LOW(summary 显并发模式)。独立重跑 **793 passed / ruff / 20 配置 / phase0 0.9600·0.8408**。**建设侧完成;live rollout(先 `data-backfill` 补史 → 手动增量 warm → enable timer)= 用户 Stage-1 driver**。 -- ✅ 质量门:`pytest` **793 passed**(P0=97 / P1=78 / P2-1=22 / P2-2=22 / P2-3=14 / P2-4=8 / P3-1=10 / P3-2=18 / P3-3=16 / P3-4=15 / P3-5=22 / P3-6=27 / P3-7=25+1 throttle / P3-8=8 / P4-1=28 / P4-2=17 / **intraday I1 schema=14 + feed=9 / I2 cache=10 / I3 aggregate=13 / I4 execution=10 / P4-3 cache=10 + updater=7 / P-I5a event-backtest=19 / P-I5b exec-feasibility=16 / P-I5c mmp-minute=18 / P-I5d mmp-quintile=19 / P-I5e 仅 config(无新测试,`test_cache_config` 的 config glob 自动 +1)/ P-I5f intraday-liquidity=17(+ `test_cache_config` config glob 自动 +1)/ D1 token-dedup index-feed +2 / D2 cache-modularization +5 / D3 data-quality market=15 + intraday=12 + report=14 / D3b data-update-quality=18 / D4 coverage-ledger-scaling=13 / D5 scheduler=9 + concurrency=12 / schema-registry-guard=62 / all-A-incremental=12 / all-A-backfill=22**);`ruff` clean;`validate-config`(全部 20 配置含 data_update + phase_i5a + phase_i5b + phase_i5c + phase_i5d + phase_i5e + phase_i5f)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 不变**)。 -- ⚠️ 剩余(已显式披露):日线 only、demo 路径非真数据、旧三因子无信号(P3-3/P3-4 实证;但其组合在 2024-2026 holdout 上 SSE50/CSI300/CSI500 全正、CSI500 高达 +17.8%——小样本/regime 翻转的持续例证);value/低波信号获得**独立样本符号级确认**(P3-7 SSE50/CSI300 量级衰减;P3-8 CSI500 泛化成立且更强),组合级盈利能力仍未确立(排名跨 cell 翻转);subset 报告文件名已可配置(P3-8 起不再互覆盖)。 -- 路线图下一步:**MMP 暂缓推进(I5e 负结果)**(I5e 已在独立 universe CSI300 同窗口机器冻结复跑 → 单调性 **FAILS/反转**(Spearman −0.5,Q5 高 MMP 最差,合成 Q5−Q1 累计 −26.77%);I5d 的 CSI500 单调性疑 universe/regime 特异、**非稳健** → **在出现 disjoint 窗口 / 第三 universe 的正向证据前,不把 MMP 当稳健或可交易信号推进**;新 intraday 因子候选只作显式 EXPLORATORY 工作);**I5f 已落地 → I5g(可选,须单独显式 goal)**(I5f 已加 report-only 执行流动性/容量诊断,实测 10M RMB/5% 参与率下约半数 SSE50 单分钟 desired trade 容量不足;**强制 partial-fill / volume-cap(真正约束成交)= 可能的 I5g,仅在单独显式 goal 后启动**,本阶段未做,不声称已实现);**盘后全A auto-fetch**(数据正确性审计 PASS——D3 质量层实测 80GB 真实缓存结构干净、ann_date PIT 轴 100%、跨 shard schema 无漂移;PR #59 = PR-1 全A 增量 auto-warm + systemd @21:00 default-off 已落地;**PR #61 = PR-2 全A 历史回填**——分块/断点续跑/分钟全窗口 + per-symbol 失败隔离 + `start>today` 守卫,已落地。**建设侧完成,剩 live rollout = 用户 Stage-1**:先 `data-backfill` 补全A 历史(可续跑)→ 手动跑增量 warm 观察 → enable systemd timer);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / data-update summary 落 cache-stats artifact);**数据层 D6**(D1+D2+D3+D3b+D4+D5 已 merge:契约文档化 + token 解析收敛 + `TushareCache` specs/parsers 拆分 + report-only `data/quality/` 质量层 + default-off `data-update` 质量报告钩子 + coverage ledger `record_many` 批量写 + 进程内查找缓存 + opt-in 有界并发 + 全局限频器 + **schema 注册表/default-off drift 守卫(PR #57)**;剩余数据层 follow-up:schema 守卫接 live `data-update` 暖跑路径(当前仅接 pipeline/回测) + 分钟 schema 守卫;**D6**=`PanelStore` append/partition / 可选物化派生面板存储,**仅当因子研究需要可复用派生面板时才启动**——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。 +- ✅ **因子评估契约层 `analytics/eval/` + 十一个分钟因子复现**(**PR #63–#73 已 merge 到 `main`**,**EXPLORATORY,非业绩声明**):研报 → 复现循环(10/10 收官)与支撑它的判定契约层。全部因子同一数据面:CSI500 `000905.SH` 2021-07-01→2026-06-30 日频、cache-only(`stk_mins_live_calls=0`)、每因子 no_book / with_book 两跑(因子簿 = 已确认的 value_ep + value_bp + volatility_20)。 + - **契约层(PR #63,v0.1→v0.7 迭代后 frozen)**:`FactorSpec`(Factor 必带 classattr、**预注册 `expected_ic_sign`**、PIT 契约、intraday 块校验)+ `FactorEvaluator` ABC(8 个必填 section,缺一即 raise)+ `FactorEvalReport`(确定性 md/json,secret-redacting renderer)+ **三轴判决 Predictive × Incremental × Tradable → Adopt / Watch / Reject / INSUFFICIENT-DATA**。三条判定纪律:**非对称门**(hard Reject 先于样本量门)、**unknown never convicts**(判不了绝不定罪)、**PASS 一律读 N_eff 置信区间下界**(`N_eff = N/(1+2Σρ)`,Geyer 扩展;点估计不得买 PASS)。v0.7:增量轴独立门 `min_incremental_abs_icir=0.15`(正交化收缩残差尺度,沿用原始 0.30 是类别错误)+ 单调性作**方向门**(默认 0.0,非强度门)。exploratory 因子**封顶 Watch**(Tradable 轴全程 NOT_ASSESSED)。一次向量化 IR 喂全部 section(与朴素逐期循环等价性测试锁定)+ 单 PNG dashboard,带**强制 FACTOR DEFINITION 带**——不说明怎么算就不许展示因子。 + - **十一因子(下表 verdict 为当前 v0.9 close-to-close 口径,非各 PR 当时口径;出处 `tmp/design/RESULTS_post_pr75_2026-07-21.md` 参照表 + `tmp/Quantitative_Research_Report/factors/ledger.md`)**: + + | PR | 因子 | 家族 | sign | IC | ICIR | 换手 | 净1× | no_book / with_book | + |---|---|---|---|---|---|---|---|---| + | #63 | `jump_amount_corr` | 跳跃×成交额相关 | −1 | −0.0298 | −0.401 | 0.415 | −0.000834 | Watch / Watch | + | #64 | `minute_ideal_amplitude` | 振幅 | −1 | −0.0291 | −0.464 | 0.990 | −0.001981 | Watch / Watch | + | #65 | `amp_marginal_anomaly_vol` | 振幅波动 | **+1** | −0.0412 | −0.425 | 0.285 | −0.000504 | Reject / Reject(documented negative:预注册 +1 未迁移,**实测负 IC ≠ sign=−1**) | + | #66 | `volume_peak_count` | 计数 | +1 | +0.0177 | +0.210 | 0.304 | **+0.000071** | Reject / Reject(符号迁移成功但 ICIR 下界 0.151 < 0.30 预注册门) | + | #67 | `intraday_amp_cut` | 振幅 | −1 | −0.0347 | −0.435 | 0.578 | −0.000260 | **INSUFFICIENT-DATA** / Watch | + | #68 | `peak_interval_kurtosis` | 时序 | +1 | +0.0002 | +0.006 | 0.576 | −0.000463 | Reject / Reject(诚实空结果;研报称 RankIC +7.19%/ICIR 4.63 → 本循环最大复现落差) | + | #69 | `valley_relative_vwap` | 价格比值 | +1 | +0.0327 | **+0.506** | 0.473 | −0.000085 | Watch / Watch | + | #70 | `valley_ridge_vwap_ratio` | 价格比值 | +1 | +0.0339 | +0.425 | **2.101** | −0.001705 | Watch / Watch(对齐单调 CI 下界仅 **+0.0010**,全表最薄) | + | #71 | `ridge_minute_return` | 收益 | −1 | −0.0312 | −0.381 | **2.108** | −0.001983 | **INSUFFICIENT-DATA** / Reject(增量轴与因子簿冗余) | + | #72 | `valley_price_quantile` | 价格位置 | +1 | +0.0265 | +0.414 | 0.679 | **+0.000048** | Watch / Watch(按日单调 +0.1064 全表最高) | + | #73 | `peak_ridge_amount_ratio` | 成交额 | +1 | **+0.0401** | +0.488 | **2.127** | −0.001402 | Watch / Watch(IC 全场最高,零价格含量) | + + - **三条循环级结论**:① **家族图谱**——计数弱正 / 时序归零 / 收益 Reject / **价格比值×2 + 价格位置 + 成交额 = 四个双轴 PASS**;峰岭谷行为学划分本身有效,且 **不止价格信息有效**(PR-M 零价格含量却 IC 最高)。② **IC 强 ≠ 可交易(贯穿证据)**——11 个因子里只有 PR-F(+0.71bp)与 PR-L(+0.48bp)在 1× 费率下净多空为正,且 PR-L 扛不住 2×;毛价差常相近,差距**几乎全部来自换手**(PR-I/L 的 0.47/0.68 vs PR-J/K/M 的 2.1+)。③ **假说证伪记录(不得作为已确立规律引用)**——"秩IC/Pearson 背离比预测单调性"被 PR-M 证伪(3.86×→0.60 与 PR-J 4.22×→0.90 交叉),仅两个极端处有不确定关联。 + - **方法论(本轮建立,已作常设规则)**:① **不可能失败的测试**——三个实例:PR-L 的旗舰反泄漏测试(全截面统一扰动是带截距 OLS 残差不可见的仿射变换)、`compare_postmerge.py`(拿新结果和自己比,见下条 #74 重跑对账)、I5b fixture 给每根 bar 定价使 **VWAP ≡ close**(对"闸门读哪个"结构性失明)。**任何不变性测试都必须有实际跑过的 mutation 证据,且 mutation 要打中所主张的那个具体性质**。② **行为变了而措辞没变**(#76/#78 实证)——正确的修法**不是**"断言不存在第 N+1 处副本"(#76 就是这么做的,用扫描式正则,被七种改写全部绕过),而是 **把主张只写一遍、其余每一处都去组合它**:**正则断言不了"没有别的句子这么说",而"根本没有别的句子"可以**。 +- ✅ **因子评估契约 v0.8 + v0.9**(**PR #74 已 merge 到 `main`**,`1ae555e`):十一个因子在 `analytics/eval/` **严格 no-touch** 下跑完后暴露的两项 frozen 缺陷,本 PR 是**对该 frozen 契约的首次授权修改**。 + - **缺陷一:对齐净价差把成本加了回去(判定门缺陷,非仅展示)**。四处写成 `sign * net`(`net` 已扣成本),`sign=−1` 下展开为 **`−gross + cost`**——因子付的手续费被当利润返还。正确语义 `aligned = sign*gross − cost`(先按假设翻腿、再永远扣成本)。**其中两处在 `verdict.py`(`_base_spread` / `_all_spreads_negative`),直接喂 Tradable 轴 PASS 条件**,历来未触发仅因该轴全程 NOT_ASSESSED。手算实证:`gross 0.000125 / net 1× −0.001983 → cost 0.002108 → aligned −0.002233`(缺陷式给 **+0.001983**)。`sign=+1` 逐比特不变。年化展示值修正:jump_amount_corr **+23.14%→−0.01%**、minute_ideal_amplitude **+64.07%→−0.27%**、intraday_amp_cut **+6.30%→−20.52%**、ridge_minute_return **+64.28%→−43.25%**(**旧值全是虚高**)。 + - **缺陷二:用量级敏感的池化统计量给秩基轴把门**。`monotonicity_spearman` 是"桶序号 vs 跨日等权算术均值"的相关,无界,少数极端收益日集中于某桶即可翻号,而每日封顶的秩 IC 几乎不动。新增 `monotonicity_spearman_by_date`(逐日 Spearman,先封顶 [−1,1] 再平均,与秩 IC 同构)并把门移过去;池化版保留为报告字段 + 回退披露。 + - **v0.9:新统计量被日内噪声衰减,裸 0.0 门落在噪声带内**。实测分位阶梯完美的因子按日只有 **0.045–0.106**,门却仍在裸 0.0 且无离散度估计,两个因子相差 0.021 就分生死。改为读该按日序列的 **N_eff 置信区间**(复用既有 `mean_ci`),三值:对齐 CI 下界 > bar → **HOLDS**;对齐 CI 上界 < 0 → **CONTRADICTED**(FAIL);跨零 → **UNKNOWN**(既不定罪也不放行)。实测 CI 半宽 **0.0291–0.0448** → 裸 0.0 实为一道约 0.035 的隐式门槛。**最要害的路由规则:UNKNOWN 绝不救本就不合格的因子**——单调性已从点信号布尔链中摘出(三值事实塞进 `and` 链必然坍缩),ICIR / NW-t / win / OOS 任一不清关仍走 FAIL,UNKNOWN 只在其余全清关时把预测轴落到 INSUFFICIENT_DATA。 + - **3 处 verdict 变化**(全部归因于门的变化,并如此陈述):`intraday_amp_cut`(no_book) Reject→INSUFFICIENT-DATA(对齐 CI [−0.0353,+0.0343] 跨零)、`intraday_amp_cut`(with_book) **Reject→Watch**(同上 + 增量轴本就 PASS)、`ridge_minute_return`(no_book) Watch→INSUFFICIENT-DATA(对齐 CI [−0.0151,+0.0558] 跨零)。`ridge_minute_return` 跨三版本轨迹 **v0.7 Reject → v0.8 Watch → v0.9 INSUFFICIENT-DATA**:前两次都是在噪声上判决、只是方向不同,第三次才承认判不了。 + - **不变量**:IC / ICIR / NW-t / win / 增量 ICIR / 两个单调点值 **全部逐比特不变**(修复未泄漏到 IC 路径与增量路径)。**路由自检**:`amp_marginal_anomaly_vol`(OOS 符号翻转,第一步即 FAIL)与 `peak_interval_kurtosis`(OOS 不一致 + ICIR 0.006)单调方向均为 UNKNOWN 但仍 Reject,无渗漏。 + - **合并后十一因子干净全量重跑(`main` @ `1ae555e`,11/11 rc=0,~87min)**:`repro_reconcile.py` 11 因子 × 20 字段 = 220 项,**容差 0.0**(精确浮点相等,不用 `isclose`、不留 epsilon —— 1e-6 是"可能动"的下限,用恰好为零来测才能让任何 ≥ 该下限的变化浮出来)→ **0 处差异**;`repro_compare.py` 对 22 个 JSON artifact 做展平叶子深比 → **5,756 叶、0 处不同**,外加 **22/22 Markdown 逐字节相同**。防空过:22 个 JSON 确实被重写(mtime 落在各自 run 窗口 09:24:33→10:43:54)、前后 HEAD 都是 `1ae555e`、11 个 rc=0、全程 `stk_mins_live_calls=0`。 + - ⚠️ **记一次自己的失误:写了一个不可能失败的对账脚本**。第三个脚本 `scratchpad/compare_postmerge.py` 曾被跑并报出结论,**但它是空的,其输出什么也不证明**:它执行 `_baseline_table.py` 取新值,而那个脚本第 123 行**会写** `baseline_rows.json`,随后"旧值"读的正是刚被覆盖的同一个文件 → `old == new` 由构造成立,哪怕 artifact 错得离谱也会打印"11 个全部精确复现"(已在沙箱里用 baseline `ic=1.0` vs fresh `ic=999.0` 复现该假通过)。它还顺带毁掉了 `baseline_rows.json`。**这正是整轮重跑要消灭的失效模式,而我们亲手造了一个**(同 P2-3「曾误以为是粒度」、P3-4「过拟合签名」,照实记录)。上面的结论只站在不碰该文件的两个脚本上(其中一个跑在覆盖之前)。**权威基线是 `scratchpad/baseline_reports/`(22 文件,冻结于 run 前);复核必须比它,不是 `baseline_rows.json`。** +- ✅ **尾盘执行价改 VWAP + 分钟持有期收益复权**(**PR #75 已 merge 到 `main`**):两项改动都源于"14:50 就知道的信号为什么按 15:00 形成的价格计分"。 + - **改动 1:成交价 = 执行 bar 的 VWAP**(`amount/volume`,整分钟成交量加权均价)而非收盘 tick。`IntradayCfg.execution_price_basis: "bar_vwap"|"bar_close"`,默认 `bar_vwap`;`bar_close` **逐比特复现旧行为**——用独立 worktree 跑 main 版本、**字节比对价格矩阵与完整 fills 日志**(含 `exec_time` 与 block `reason`)验证,非断言。VWAP 未定义(volume≤0 / amount≤0 / 非有限)→ 走**显式阻挡**路径,**绝不退回 bar 收盘价、更不退回日收盘**。 + - **闸门改比实际成交价**:涨停分钟只有两种形态——**LOCKED 封死**(全部成交在涨停价 → VWAP = 涨停价)与 **OPENED 盘中打开**(有成交低于涨停 → VWAP < 涨停价),恰好对应"能不能买到";按收盘价判两头都错。这是**有意的行为变化,且被计数不被静默**:`opened_limit_up_minutes()` / `opened_limit_down_minutes()` 报出与收盘价闸门的每一处分歧。真实数据取证:`601858.SH 2023-05-15 14:51`,close = up_limit 46.13、VWAP 46.048583(差 0.18%,远高于舍入量级)。 + - **容差保持 `1e-6`**:实测 13,699 根 14:51 bar(149 根收在限价),LOCKED 偏离 ≤0.0021%、OPENED 0.013–0.017%(两总体不重叠)。1e-6 下 100% 的 OPENED 正确放行,代价是 2.1% 的 LOCKED 被误判为打开(≈全样本 0.02%)。**残差偏乐观且有界**,已写入 docstring。0.001 在本样本双向为 0%,但那是在 149 个观测上重标定阈值 = 后验调参,不为 0.02% 的效应破例。 + - **改动 2:分钟持有期收益复权(先前缺陷)**。`holding_returns` 原在 **raw 未复权价**上算 `exec(exit)/exec(entry)−1`,而日频模型用 qfq 面板 → 两条路径不对称,除权除息的机械性下跌被读成亏损。改为 `(raw_exit·af_exit)/(raw_entry·af_entry)−1`(qfq 锚在比值中相消,无需另存复权序列)。缺 `adj_factor` **不静默按 1.0**(那会把刚去掉的除权偏差放回来),走既有丢弃路径 + `missing_adj_factor_pairs()` 计数。复权**不渗进 I5b 限价闸门**(保持 raw-vs-raw),有专测钉住。 + - **实测发生率(月频调仓)**:I5d CSI500 52,923 个 (symbol, 持有期) 对中 **4,450 (8.41%)** 跨 `adj_factor` 变化,修正均值/中位 **+3.92% / +1.07%**,92.9% 为正;I5e CSI300 26,314 对中 **2,566 (9.75%)**,**+3.74% / +1.31%**,94.5% 为正。均值远高于中位 = 右尾**送转股**(af 翻倍 → raw 价腰斩 → 未复权读成 −50% 假亏损)。 +- ✅ **报告披露修正 + I5f 名义按真实规模重测**(**PR #76 已 merge 到 `main`**,`runtime/` 行为未变):**报告曾谎报自己做的检查**——PR #75 把闸门从 bar 收盘价移到实际成交价,却漏改了两个 report writer 里**描述闸门本身**的那句,此后每次跑出的报告都在描述一个它没有执行的检查。在"绝不静默降级"是常设红线的项目里,报告写错自己的方法比不出报告更糟。 + - **三个一直在算却被丢弃的计数器进报告**:`opened_limit_up_minutes` / `opened_limit_down_minutes`(本闸门与收盘价闸门的**全部分歧集合**——什么能不能成交变了,绝不许静默)、`missing_adj_factor_pairs`(因锚点 `adj_factor` 不可用而丢掉的持有期;非零即已测覆盖率短少)。尾盘报告另行声明收益是复权的并给出恒等式("exec-to-exec"一词已不足以描述它们)。 + - 措辞抽成 `limit_basis_lines()` 并由三个测试钉住;**mutation evidence 实跑**:把措辞改回收盘口径 → 2 个测试 FAIL;从分组表里删掉新计数器 → 第 3 个 FAIL。**旧 I5b 测试为何没抓到**:其 fixture 给每根执行 bar `volume=1.0, amount=close` → **VWAP ≡ close**,使所有断言在两个基准上都成立,对"闸门读哪个"结构性失明;已写进 module docstring 防止重建同一盲点。 + - ⚠️ 本 PR 的守卫办法**随后被证明不够**——见下条 **PR #78**。 +- ✅ **`adj_factor` 下降质量检查**(**PR #77 已 merge 到 `main`**,D3 层新检查,WARNING、report-only):`data/quality/market.py::check_decreasing_adj_factor` 接进 `run_adj_factor_checks`。tushare 的累计复权因子随每次公司行为**只增不减**,`front_adjust` 拿它乘 raw 价,一个发布出来的下降会直穿到每一个下游收益;而真实实例是**手工**发现的(见下条审计)。 + - **阈值 1%(相对,非绝对)由全缓存扫描定**(扫全部 5562 只已缓存票的每一个负步进:7898 个事件、涉及 4479 只票): + + | 阈值 | 触发事件数 | 触发的**非已知缺陷**票数 | + |---|---|---| + | 0.01% | 3653 | 2429(纯浮点噪声) | + | 0.10% | 179 | 2 | + | 0.50% | 178 | 1(`603081.SH`) | + | **1.00%** | **177** | **0** | + | 2.00% | 176 | 0 | + + 低于 1% 会点名状态**判不了**的票:`603081.SH` 最坏步 −0.776%,对应 raw close −1.810%,而真实公司行为需要 +0.782%——有缺陷的**形状**,但在该量级上普通日波动淹没隐含值,价格检验没有功效,结论不可解释。高于 1% 则漏掉一个真事件(1% 触发 177、2% 只触发 176,多出的那个属已知缺陷票)。1% 同时让最小的**已确认**缺陷(`000998.SZ` −2.636%)站在门槛的 2.6× 而非 1.3×——report-only 层宁可误报(代价一行 WARNING)也不可漏报(代价是被污染的价格静默通过)。 + - **相对而非绝对**(factor 跨缓存 ~1…~500):mutation 实证 `pct_change()`→`diff()` 让原六个测试**全部通过**(fixture 都落在 factor ~1–11 两种切法重合处),补两个别的尺度才有牙(`0.200→0.195` 是真 −2.5% 断裂而绝对门看成 −0.005 放行;`500.0→499.97` 是 −0.006% 舍入而绝对门 −0.03 误报)。 + - **本条 WARNING 的语义与 `check_extreme_returns` 不同**:本模块所有 HARD 检查都是零参数的代数不可能(重复键 / 非正 OHLC / high50% 的收盘跳变确实可能是拆股或复牌,而累计复权因子**没有任何合法的变小方式**。severity 反映的是阈值标定风险,不是对主张本身的怀疑。 +- 🔄 **闸门描述改单一来源**(**PR #78 OPEN,未合并**,`refactor(qt)`;#76 的结构性 follow-up):#76 加了一道扫描式正则守卫,并在 commit message 里声称"再多一处错误描述就会失败而不是发出去"。**review 用实测证否了这个声称**:写了七种自然改写("its last print"、"the final tick"、"1-minute" 代替 "1min" 等)跑真正的正则,**七种全部逃逸**——这是拿词法守卫去守语义主张的普遍下场。 + - **修法是结构性的,不是再加一条正则**:`limit_basis_phrase()` 成为**唯一被撰写的那句话**,feasibility 段、分组报告、报告的 Limitations 条目三处**组合它**而非各写各的;`_load_price_limits` 的 docstring 改为指向它而不再复述。**渲染出的报告文本逐字节不变**——本 PR 只改"有多少处可以各自出错"。正则守卫**保留**,但 docstring 缩到它真能做的事:抓**字面 revert**(坏 merge / rebase 把旧句子带回来),而这正是真实发生过的那次失效。 + - **可带走的规则(已写进上面的方法论 ②)**:**正则断言不了"没有别的句子这么说",而"根本没有别的句子"可以。** mutation 证据用的正是 review 自己那批能逃逸的措辞——它们**通过**正则守卫、**失败**于结构性测试(Limitations 条目改写成"the execution minute's final tick"、分组报告改写成"the selected bar's last print",两者都被结构测试判死)。 + - gates(PR 正文):`pytest` **1741 passed**、`ruff` clean、phase0 `0.9600/0.8408` 不变、secret scan 0。 +- ✅ **日频除权正确性审计**(用户点名最高优先级;调查记录 `tmp/design/FINDING_adj_factor_seam_2026-07-21.md`,全程只读 `artifacts/cache/tushare/v1`,无独立 PR):**结论 GENUINE——日频 qfq 路径本来就是对的,没有 vintage 接缝**;十一因子的 close-to-close 前瞻收益一直是除权正确的。 + - **接缝假设被证否**(双向检验:重述接缝既可能是降也可能是升):CSI500 池 996 票、979 票的 `adj_factor` 来自 >1 次 fetch、960 对相邻交易日跨 vintage 边界,其中因子**真的变化的只有 12 对**——全部为正、全部落在同一个边界(2026-05-29→06-01,A股年度除权高峰首个交易日,12/996 = 1.2% 属正常季节性),且大的都伴随 raw 价格的对应跳变(`002837.SZ` Δaf +30.24% / raw close −27.41% / 隐含 −23.22%)。**任何 fetch 边界上都不存在负向因子变化。** + - **`−57.27%` 是北交所占位符,不是分布尾部**:`920627.BJ` 一只票占全部 −2% 以下 176 行中的 171 行,因子在 `2.3404 ↔ 1.0000` 之间反复跳(175 行正好等于 `1.0000` = "无调整"占位符),其数据来自**单次 fetch**(一次 API 响应内不可能有跨 vintage 接缝),且**连一行 `market_daily` 收盘都没有**(永远进不了价格面板)。`1/(1−0.572723)−1 = +134.04%` —— 最初报的 `+134%` 上尾与 `−57.3%` 下尾是**同一只票的一正一负**。 + - **评估池内暴露:603,258 个 (symbol, date) 对里 1 对**(`000998.SZ` 2023-06-01,PIT 确认的 CSI500 成分:af −2.636% 而 raw close **+1.228%**、当日**开盘 −0.41% 没有任何机械缺口** → 判 **AMBIGUOUS**,倾向 tushare 自身发布缺陷而非缓存 artifact);**CSI300 零**。传播后:单日分位桶均值畸变 0.0208pp、摊到 1,211 个评估日 **0.0000172pp**、多空价差 ≤0.0000344pp——比任何能动 verdict 的量级低四个数量级,**不重述任何因子结果**,只作披露。 + - **污染的均值 vs 干净的均值(独立复测)**:全 CSI500 评估窗口日频 1,154,642 对中 6,906(**0.5981%**)跨因子变化,均值修正 **+2.28%**、中位 **+0.52%**、82% 为正,摊到全样本 **+1.37bp/日 ≈ +3.4%/年**(正是 A股股息率量级)。与最初被污染的测量对照:**发生率(0.604% vs 0.5981%)与中位(+0.45% vs +0.52%)一直是对的,错的只有均值(+4.38% vs +2.28%)与尾部(+134%)**——单个极端污染样本的典型签名(中位稳健、均值不稳健)。**经验:当均值与其中位差一个数量级,先去找那一行坏数据,别先给分布编故事。** + - 与 PR #75 的关系:**那是另一个 bug**——*分钟* `exec_to_exec` 路径用未复权价算持有期收益,日频路径从来不受影响。BSE `920xxx.BJ` 的 `adj_factor` 一律按不可信处理(零成本:无研究 universe 含它们,且它们没有日线价格行)。 +- ✅ **I5d / I5e / I5f 在修正引擎上重跑**(出处 `tmp/design/RESULTS_post_pr75_2026-07-21.md`;**EXPLORATORY,非业绩声明**)。⚠️ **读数前提(不许混谈)**:三个 run 的 NAV 全线上移**全部来自 bug 修复**(把除权除息还回去),**不是业绩改善**;VWAP 成交基准本身是**略微不利**的(−0.18pp)。 + - **I5f 四档归因**(SSE50 2026-03-03→06-12,3 期,`covered=58/58`,`stk_mins_live_calls=0`,每档同窗口实跑、确定性): + + | 引擎配置 | final NAV | delta | + |---|---|---| + | 已验收 I5b/I5f:`bar_close` 成交 + **未复权**收益 | `0.976448` | — | + | `bar_close` 成交 + **复权**收益 | `1.021137` | **+4.47pp** | + | `bar_vwap` 成交 + 复权收益(**新默认**) | `1.019318` | **−0.18pp** | + + 复权修正 ≈ 全部位移(该窗口正跨 A股年度除权高峰,暴露处于季节最大值);**更诚实的成交价反而差 0.18pp**(单根收盘 tick 比整分钟成交量加权价"更走运",方向符合预期)。闸门没有放松任何东西:`opened_limit_up_minutes`=**0**、`opened_limit_down_minutes`=**0**(这正是本闸门与收盘价闸门可能分歧的**全集**,本窗口为空),涨停挡买仍 1 笔、跌停挡卖 0 笔;限价覆盖 174/174;`missing_adj_factor_pairs`=**0**(修正测在全样本上)。 + - **I5f 容量按真实规模重测**:`portfolio_notional` 10,000,000 → **1,000,000 RMB**(用户明示资金上限),`max_participation_rate` 0.05 不变。43 笔 desired trade / 1 笔已被既有 feasibility 挡 / 42 笔有可用 ratio:**below 1.0x 由 20 笔变 0 笔**,ratio min/p10/median/p90 由 `0.122/0.222/1.104/2.730` 变 **`1.217/2.219/11.037/27.296`**。**此前"约半数单分钟 desired trade 容量不足"描述的是一个比本项目会跑的任何组合大一个数量级的规模**;真实规模下单分钟容量在该 universe/窗口**不构成约束**(最紧 1.22×)。这**不取消** partial-fill / volume-cap(可能的 I5g),只是重新界定其动机;仍是诊断,**非可交易性/业绩声明**,不外推到其他 universe / 名义 / 窗口。 + - **I5d(CSI500 五分位,2021-06→2026-05,59 期):原结论不成立**。Q1→Q5 终值 `0.9822/1.0423/1.0495/1.1275/1.1577` → **`1.1758/1.2310/1.2313/1.3090/1.2712`**;**单调 Spearman +1.0000 → +0.9000**、合成 Q5−Q1 累计 **+17.15% → +8.65%**(腰斩)、**Q5 不再是最优组**(Q4 1.3090 > Q5 1.2712)——I5d 的全部主张就是那条完美的 Q1→Q5 排序,它断了。分钟覆盖 892/995 → 900/995;`stk_mins_live_calls=0`;限价覆盖 52836/52836;各组 `returns dropped: no adj_factor` 均为 **0**。 + **四档归因(四件事同时变,实跑中间配置而非猜)**:① 老引擎 + **新缓存**(900 票)Spearman 仍 **+1.0000** → **样本变化被排除**;② `bar_close` 成交 + 闸门不变、**只把分红除回去**即已 Spearman **+0.9000**、价差 **+8.83%** → **复权修正是全部效应**;③ 再换 `bar_vwap` Spearman 不变、价差 −0.18pp → **VWAP 基准近乎惰性**。**即 I5d 的完美单调性实质上是"把除权下跌记成亏损"的产物**:高 MMP 的 Q5 篮子除权暴露低于 Q4,错扣分红反而抬高了 Q5 相对 Q4;把账算对,Q4 就超过它。74 个 (date,symbol) 对收在限价却盘中打开、现在获准成交(opened limit-up 22/14/10/10/18、limit-down 3/2/1/2/4),真实且已披露,但按 ②→③ 不是移动结果的原因。 + - **I5e(CSI300 独立泛化):负结果不变且更强**。Q1→Q5 `0.8809/0.7377/0.9418/0.7573/0.6665` → `1.0919/0.8777/1.1575/0.9223/`**`0.7850`**;**Spearman −0.5000 完全不变**,合成 Q5−Q1 累计 **−26.77% → −31.82%**(更负);Q5 仍是最差组(年化 −4.81%、maxDD −47.79%);覆盖 448→450/481;opened limit-up 21 对(远小于 I5d 的 74)。**这正是该问的问题:若光靠复权修正就能翻转 I5e,那个负结果就有一部分是"把分红记成亏损"的假象。它没翻——泛化失败是因子的属性,不是执行假设的产物。** + - **MMP 合并读数**:唯一的正面证据在修正引擎上**退化**,独立 universe 上的负面证据**加强** → **暂缓 MMP 的理由比过去更强,而不是不变**。 +- 🔄 **十一因子改用 14:51 VWAP 的 exec-to-exec 基准**(**PR #79 OPEN,未合并**,分支 `feat/exec-to-exec-rebasis`;数字出处 `tmp/design/RESULTS_post_pr75_2026-07-21.md` + PR #79 正文):每个因子**只算一次、在两个基准上各评估一次**;既有 `{stem}_{no,with}_book` artifact 原样不动,新增的是 `{stem}_exec_{no,with}_book`。**why**:分钟因子在 14:50 截止时就已定死,而本框架**能建模的唯一成交**是 14:51 开始的那根 1min bar;按 `close(t+h)/close(t)` 计分等于把一个**本项目模拟不了的收盘集合竞价**算进因子功劳(`closing_call_proxy` 需要 `stk_auction_*`,数据方案不含)。 + - **回归先行**:rebasis 分支的 `close_to_close` artifact vs 已验证的主树版本 **5,756 个叶子、0 处不同** → 本次是**加了一个基准,不是移动了一个**(两个目录由两次独立文件读取比对,不经任何共享中间产物——正是上面那次空对账的教训)。 + - **22 格(11 因子 × no_book/with_book)中 20 格不变;移动的 2 格都朝"更没把握"走**: + - `valley_ridge_vwap_ratio`(no_book)Watch → **INSUFFICIENT-DATA**:对齐按日单调 CI `[+0.00100,+0.07110]` → `[−0.00535,+0.06804]`。它的 Watch 本就建立在 +0.0010 这个全表最薄的下界上(**跑之前就已在参照表里标注**),CI 稍宽即跨零 → 方向 UNKNOWN → 预测轴 INSUFFICIENT_DATA。其 with_book 仍是 Watch,但**改由增量轴独扛**(正交 ICIR 下界 +0.232 > 0.15)——同一个标签靠的是不同证据,reasons 里写明。 + - `ridge_minute_return`(with_book)Reject → **INSUFFICIENT-DATA**:close 基准上增量轴 FAIL(正交 ICIR −0.141≈0,与因子簿冗余);exec 基准上点估计 −0.151 方向仍对,但对齐下界 +0.084 够不到 0.15 门 → 既不通过也不否证。**这是把握变弱,不是翻案**:INSUFFICIENT-DATA 的语义是"既没证明也没证否",且它到不了正面主张。 + - **机制只有一个**:点估计几乎全面**变强**(|ICIR| 11 个里 10 个上升;唯一例外 `peak_interval_kurtosis` 0.0058→0.0008,本就是空因子),但 **N_eff 11 个里 9 个下降**(1187.7→1116.0、1009.5→933.3、1122.9→1055.8)——exec-to-exec 的 IC 序列比 close-to-close 带更多自相关,于是每个 CI 都变宽。**更强的点估计落在更宽的区间里**,恰是 v0.9 那道门被造出来裁的情形,而它裁得保守。 + - **新基准的诚实代价(两个分母刻意分开,因为 `1,541` 在两种口径下都会出现)**:**按锚点**(面板网格 1,158,912 个 (date, symbol) 对)——`ok` 1,156,368(99.78%)/ `no_bar` 执行窗口内无 1min bar **1,734(0.150%)**/ `bad_vwap` 有 bar 但 VWAP 未定义 810(0.070%)/ `bad_adj_factor` **0**。**按前瞻收益对**(每因子各自的评估网格)——比 close_to_close 少 3,170–3,274 对(**0.278%–0.283%**),涉及 175–180 只票,`bad_adj_factor` 十一个因子**全为 0**,`stk_mins_live_calls` 全为 0。**VWAP 定价比 bar-close 基准多挡 1,541 对(占收盘基准可测的 1,156,183 的 0.133%),因为那一分钟根本没有成交——这部分排除与流动性相关、有方向、非随机**(被排掉的正是最不流动的分钟):**这是有偏的样本限制,不是舍入损失;百分比小不等于随机,不许当随机报**(每份 exec 报告都带 `coverage_bias_bad_vwap` 原话,且 sanity 报告把这句话放在覆盖率表**之上**,使读者不会先看到百分比;有测试钉住措辞)。N_eff 在 9/11 上缩水是更真实基准**付出的统计功效代价**,是真实借方而非记账层面的假象。 + - **VWAP 与 bar close 在无条件分布层面几乎同一序列**:均值差 **+1.0e-07**(SE 1.3e-06,t = 0.074)、中位差 0、逐日相关中位 **0.998** → 改基准买到的是**执行锚点的真实性,不是另一个信号**,与 I5d 归因(VWAP 什么都没动、复权动了全部)一致。**close-to-close 结果保留作并排对照**,exec_to_exec 为操作基准。 + - **正确性验收(CSI500 全规模,996 票 / 1,210 日,cache-only,十个日频/universe gap-fetch 计数器全 0)**:① 与 close_to_close 的逐日截面相关中位 **0.9890**(p10 0.9821 / p90 0.9933,Spearman 中位 0.9814),下限 0.90 → PASS(**低于下限时 builder 直接 raise 而不是继续跑**);② 量级同阶(exec mean 0.000429 / std 0.027718 vs c2c 0.000451 / 0.028050);③ **5 行从 raw 1min parquet 用普通算术手算复核**(不 import 任何执行层 helper,故不会继承其 bug),最坏绝对差 **0.0 精确**;④ 除权持有期两种口径并列(如 `000564.SZ` 2021-12-29→12-31:未复权 −0.598581 → 复权 **−0.045367**)。gates(PR 正文):`pytest` **1774 passed**(= `main` 的 1740 + 34,恰为两个新测试文件、0 个既有测试被挤掉)、`ruff` clean、phase0 `0.9600/0.8408`、31 配置、secret scan 0。 +- ✅ 质量门(**当前 `main` @ `aa19968` 实测**:`python -m pytest -p no:warnings` **1740 passed**、`ruff` clean、`validate-config` **31/31 配置逐个 OK**、`run-phase0`(demo)**ic 0.9600 / annual 0.8408 不变**)。新增测试分组(`--collect-only` 实数):**因子评估契约层 contract=337 + standard=113 + figures=7 / 十一因子(factor + eval runner,21 文件)=421 / PR#75 exec-vwap-basis=46 / D3 market quality 15→21(含 #77 `decreasing_adj_factor` 及其相对-vs-绝对尺度 mutation 测试)**。历史分组(旧 793 基线):`pytest` **793 passed**(P0=97 / P1=78 / P2-1=22 / P2-2=22 / P2-3=14 / P2-4=8 / P3-1=10 / P3-2=18 / P3-3=16 / P3-4=15 / P3-5=22 / P3-6=27 / P3-7=25+1 throttle / P3-8=8 / P4-1=28 / P4-2=17 / **intraday I1 schema=14 + feed=9 / I2 cache=10 / I3 aggregate=13 / I4 execution=10 / P4-3 cache=10 + updater=7 / P-I5a event-backtest=19 / P-I5b exec-feasibility=16 / P-I5c mmp-minute=18 / P-I5d mmp-quintile=19 / P-I5e 仅 config(无新测试,`test_cache_config` 的 config glob 自动 +1)/ P-I5f intraday-liquidity=17(+ `test_cache_config` config glob 自动 +1)/ D1 token-dedup index-feed +2 / D2 cache-modularization +5 / D3 data-quality market=15 + intraday=12 + report=14 / D3b data-update-quality=18 / D4 coverage-ledger-scaling=13 / D5 scheduler=9 + concurrency=12 / schema-registry-guard=62 / all-A-incremental=12 / all-A-backfill=22**);当时 `ruff` clean、`validate-config` 20 配置(data_update + phase_i5a…phase_i5f)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 自 P0 起从未变过**)。 +- ⚠️ 剩余(已显式披露):日线 only、demo 路径非真数据、旧三因子无信号(P3-3/P3-4 实证;但其组合在 2024-2026 holdout 上 SSE50/CSI300/CSI500 全正、CSI500 高达 +17.8%——小样本/regime 翻转的持续例证);value/低波信号获得**独立样本符号级确认**(P3-7 SSE50/CSI300 量级衰减;P3-8 CSI500 泛化成立且更强),组合级盈利能力仍未确立(排名跨 cell 翻转);subset 报告文件名已可配置(P3-8 起不再互覆盖)。**分钟因子侧新增披露**:十一个复现因子全部 EXPLORATORY、**封顶 Watch,无一到 Adopt**,1× 费率下净多空为正的只有 2 个(PR-F/PR-L,且 PR-L 扛不住 2×)——**IC 强 ≠ 可交易**;MMP 的唯一正面证据(I5d)在修正引擎上退化、I5e 负结果加强;I5f 的容量结论已按**真实 100 万名义**重写(1000 万口径的"约半数不足"作废);**日频除权审计已完成**(GENUINE、无 vintage 接缝、评估池暴露 1/603,258,不重述任何因子结果),**分钟路径的复权缺陷已在 PR #75 修**;exec-to-exec 改基准已开 **PR #79(未合并)**,close-to-close 与 exec 两套 artifact 并存;闸门描述单一来源化的 **PR #78 亦未合并**;schema 守卫**仍未接** live `data-update` 暖跑路径;HTML compendium(`artifacts/reports/factor_compendium.html`)**还读 v0.8 结果,待按最终结果修订**。 +- 路线图下一步:**MMP 暂缓推进——理由在修正引擎上比过去更强,不是不变**(I5e 独立 universe CSI300 同窗口机器冻结复跑 → 单调性 **FAILS/反转** 且**在修正引擎上更负**:Spearman **−0.5000 不变**、Q5 高 MMP 仍最差、合成 Q5−Q1 累计 **−26.77% → −31.82%**;而 I5d 的 CSI500 完美单调性在修正引擎上**退化**(Spearman **+1.0000 → +0.9000**、Q5−Q1 **+17.15% → +8.65%**、Q5 让位 Q4),四档归因实测**归到复权修正本身**——原结论实质是"把除权下跌记成亏损"的产物 → **在出现 disjoint 窗口 / 第三 universe 的正向证据前,不把 MMP 当稳健或可交易信号推进**;新 intraday 因子候选只作显式 EXPLORATORY 工作);**I5f 已落地 → I5g(可选,须单独显式 goal)**(I5f 已加 report-only 执行流动性/容量诊断;**按用户真实规模 100 万 RMB / 5% 参与率重测:below-1.0x 由 20 笔变 0 笔、最紧 1.22×——单分钟容量在该 universe/窗口不构成约束**;此前"10M RMB 下约半数不足"的说法**已作废**,它描述的组合比本项目会跑的大一个数量级;**强制 partial-fill / volume-cap(真正约束成交)= 可能的 I5g,仅在单独显式 goal 后启动**,本阶段未做,不声称已实现);**盘后全A auto-fetch**(数据正确性审计 PASS——D3 质量层实测 80GB 真实缓存结构干净、ann_date PIT 轴 100%、跨 shard schema 无漂移;PR #59 = PR-1 全A 增量 auto-warm + systemd @21:00 default-off 已落地;**PR #61 = PR-2 全A 历史回填**——分块/断点续跑/分钟全窗口 + per-symbol 失败隔离 + `start>today` 守卫,已落地。**建设侧完成,剩 live rollout = 用户 Stage-1**:先 `data-backfill` 补全A 历史(可续跑)→ 手动跑增量 warm 观察 → enable systemd timer);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / data-update summary 落 cache-stats artifact);**数据层 D6**(D1+D2+D3+D3b+D4+D5 已 merge:契约文档化 + token 解析收敛 + `TushareCache` specs/parsers 拆分 + report-only `data/quality/` 质量层 + default-off `data-update` 质量报告钩子 + coverage ledger `record_many` 批量写 + 进程内查找缓存 + opt-in 有界并发 + 全局限频器 + **schema 注册表/default-off drift 守卫(PR #57)**;剩余数据层 follow-up:schema 守卫接 live `data-update` 暖跑路径(当前仅接 pipeline/回测) + 分钟 schema 守卫;**D6**=`PanelStore` append/partition / 可选物化派生面板存储,**仅当因子研究需要可复用派生面板时才启动**——均尚未实现);**因子层收尾**(① `feat/exec-to-exec-rebasis` 两基准对照已跑完并开出 **PR #79,待评审合并**——22 格中 20 格不变、2 格朝更保守走;同时 **PR #78(闸门描述单一来源)待合并**;② HTML compendium 按最终结果修订;③ 十一因子**无一到 Adopt、净多空几乎全负** → 下一步优先做**换手/成本敏感**的组合层验证与更长 holdout,而不是继续堆新因子);研究侧:更长 holdout 滚动复检 / 成本模型细化。