From 91b99dc032300ef5111c544d58555f52c3b38380 Mon Sep 17 00:00:00 2001 From: shaofl <2899218482@qq.com> Date: Tue, 21 Jul 2026 15:29:58 -0700 Subject: [PATCH] docs: record #78 and #79 as merged, with the em-dash regression and the review that never returned Both follow-ups landed after PR #80 was written, so the file still described them as open. Corrected, and two things worth keeping are recorded rather than smoothed over. - #78 (ecd8db2): its PR body claimed rendered report text was byte-identical. It was not. A rendering probe -- building the same lines on main and on the branch and comparing strings -- found two of the three hosts dropped the CLOSING em-dash, shipping an unmatched dash under a claim of no output change. Review had asked that exact question before the probe ran. Fixed in 5b4d1ec, probe re-run to confirm identity, invariant now pinned by a test. The entry also states the trade: composing one fragment into several sentences swaps three ways to state the fact wrong for one way to punctuate it wrong. - #79 (b04c966): its dispatched code review did not return in ~1.7h and it merged on self-verification, not on a review pass. The entry lists what was independently verified (5,756-leaf regression identity, h stepping the factor grid, no lookahead, the cache-key payload, coverage partitioning) and what was not (the five mutation claims, the eleven runner edits, the execution_capacity passthrough), and states that a later finding restates the exec-basis numbers only -- close-to-close remains the validated reference. - PR list: #78, #79, #80 merged; #38 stays OPEN. Quality gate re-measured on this tree at b04c966: pytest 1776 passed, not the 1742 from the #78 branch -- that predated #79's +34. Composition now recorded (1740 -> 1742 -> 1776). ruff clean, 31/31 configs, phase0 0.9600/0.8408. --- CLAUDE.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d0f0e9d..7f823a3 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`,分块/续跑/失败隔离)、#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)。 +- **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` 下降质量检查)、#78(#76 的 follow-up:扫描式正则守卫被七种改写实测证否 → 闸门描述改单一来源)、#79(十一因子改 14:51 VWAP exec-to-exec 基准,**评审未返回、靠自查合并**)、#80(进度文档)均已 merge 到 `main`**;**OPEN 未合并:#38**(见 P-I5d 处置,未获授权关闭)。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 - **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。 - **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。 - 文件小而专(<800 行),immutable 优先。 @@ -319,10 +319,12 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri 低于 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 把旧句子带回来),而这正是真实发生过的那次失效。 +- ✅ **闸门描述改单一来源**(**PR #78 已 merge 到 `main`**,`ecd8db2`;#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 把旧句子带回来),而这正是真实发生过的那次失效。 + - ⚠️ **"渲染文本逐字节不变"这个声称一开始是错的**(合并前修掉,`5b4d1ec`):一次**渲染探针**(在 main 与分支上各自构造同样那几行、比较字符串)查出**三个宿主里有两个丢了收尾的破折号**,渲染成 `...on the `bar_vwap` basis to the raw `stk_limit` band` 这样**破折号不成对**的病句——即一次以"没有输出变化"名义发出去的真实输出变化。**review 在探针跑之前恰好问过这个问题**("在一处读起来通顺的片段,换个上下文可能不合语法"),答案是它已经发生了。两处修复后重跑探针:所有组合出的行与 main **字符串完全相同**,并加测试钉住"片段被嵌进句中时,起头的破折号必须在其后被闭合"。 + - **代价面照记**:把一个片段组合进多个句子,是用**"三处可以各自把事实说错"换成"一处可以把标点打错"**——仍是划算的交易,**但它是一笔交易,不是白拿**。 - **可带走的规则(已写进上面的方法论 ②)**:**正则断言不了"没有别的句子这么说",而"根本没有别的句子"可以。** 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。 + - gates(`5b4d1ec` 修复后):`pytest` **1742 passed**、`ruff` clean、phase0 `0.9600/0.8408` 不变。 - ✅ **日频除权正确性审计**(用户点名最高优先级;调查记录 `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%` 下尾是**同一只票的一正一负**。 @@ -344,7 +346,7 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri **四档归因(四件事同时变,实跑中间配置而非猜)**:① 老引擎 + **新缓存**(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_*`,数据方案不含)。 +- ✅ **十一因子改用 14:51 VWAP 的 exec-to-exec 基准**(**PR #79 已 merge 到 `main`**,`b04c966`;⚠️ **合并方式见下条**;数字出处 `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 里写明。 @@ -352,7 +354,8 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - **机制只有一个**:点估计几乎全面**变强**(|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 滚动复检 / 成本模型细化。 + - **正确性验收(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。 + - ⚠️ **它是怎么合并的:派出的 code review 约 1.7 小时未返回,本 PR 靠自查而非评审通过而合并**(PR 正文下有一条 comment 如实说明,以免日后有人以为它被评审签过字)。**合并前独立核过的**:① 既有路径没动——分支的 `close_to_close` artifact vs 已验证的主树版本 **5,756 叶、0 处不同**(两个目录分别读取、无共享中间产物),与 diff **+2595/−0 纯新增**一致;② **`h` 走的是因子自己的评估网格而非价格面板的行**(`exec_forward_returns` 先 `isin(dates)` 再 `groupby(symbol).shift(-h)`,正是 `analytics/eval/ir.py::_resolve_forward_returns` 标注为 close 路径隐患的那条性质;非正分母掩成 NaN);③ 因子信息集**无前视**(日 d 的入场锚是 d 当天 14:51 的执行 bar,因子 14:50 已知,因果成立);④ 共享 artifact 的 **cache key 完整**(含 schema 版本 / universe 类型 + 指数代码 / 起止 / 缓存根 / `price_adjust` / 全部执行参数 / **精确 symbol 集合与精确日期网格各自的 sha1**)——陈旧 artifact 无法被喂给另一份配置,那正是"悄悄拿错收益给一族因子打分"的失效模式;⑤ 覆盖率成因**按构造互斥划分**(先归入场锚、否则归出场锚)。**未独立核、因此仍对后续检查开放的**:五条 mutation 声称(只读了、未重跑)、十一个 runner 改动是否机械等同、`EvalContext.execution_capacity` 透传是否在作者自带测试之外仍保持 Tradable 轴 `NOT_ASSESSED`。**若日后评审在这个未核集合里查出问题,要重述的是 exec 基准的数字——不是 close-to-close,后者未被触碰且仍是已验证的参照。** +- ✅ 质量门(**当前 `main` @ `b04c966` 实测**:`python -m pytest -p no:warnings` **1776 passed**、`ruff` clean、`validate-config` **31/31 配置逐个 OK**、`run-phase0`(demo)**ic 0.9600 / annual 0.8408 不变**)。构成对得上:`aa19968` 实测 **1740** → #78 加 2(含钉住破折号闭合的那条)= **1742** → #79 加 34(两个新测试文件,0 个既有测试被挤掉)= **1776**。新增测试分组(`--collect-only` 实数,`aa19968` 口径):**因子评估契约层 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 并存;⚠️ **#79 的 code review 未返回、靠自查合并**,其"未独立核"清单(五条 mutation 声称 / 十一个 runner 改动是否机械等同 / `execution_capacity` 透传)仍待后续检查——若查出问题,重述 exec 基准数字而非 close-to-close;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 格朝更保守走;**补一次 #79 的 code review**(原评审未返回,未独立核的三项见上);② HTML compendium 按最终结果修订;③ 十一因子**无一到 Adopt、净多空几乎全负** → 下一步优先做**换手/成本敏感**的组合层验证与更长 holdout,而不是继续堆新因子);研究侧:更长 holdout 滚动复检 / 成本模型细化。