From 5591ee315ab41499808f9bc3c8f9918163a6b5a8 Mon Sep 17 00:00:00 2001 From: shaofl <2899218482@qq.com> Date: Sat, 20 Jun 2026 21:55:24 +0800 Subject: [PATCH] docs: record I5e CSI300 generalization result (negative) Docs-only progress sync after merging PR #53 (I5e MMP quintile CSI300 independent generalization). Records the negative result: the I5d CSI500 Q1->Q5 MMP monotonicity does NOT generalize to CSI300 over the same 2021-06-01..2026-05-31 window (Spearman -0.5000, Q5 high-MMP worst, synthetic Q5-Q1 cumulative -26.77%) -> FAILS / not robust; pause MMP promotion until disjoint-window / third-universe evidence. - merged-PR list += #53 - new I5e progress bullet (EXPLORATORY, config-only, covered=448/481, stk_mins_live_calls=0, NAV/annual/Spearman, caveats preserved) - quality gate 677 -> 678 passed; 17 -> 18 configs; phase0 0.9600/0.8408 unchanged - roadmap: MMP framed conservatively (not robust/tradable); D6 / endpoint schema registry remain deferred No code/config/test changes; AGENTS.md kept byte-identical to CLAUDE.md. --- AGENTS.md | 12 +++++++++--- CLAUDE.md | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cfed104..d36b2f3 100644 --- a/AGENTS.md +++ b/AGENTS.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 有界并发 + 全局限频器)均已 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 独立泛化检验,负结果)均已 merge 到 `main`**。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 - **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。 - **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。 - 文件小而专(<800 行),immutable 优先。 @@ -213,6 +213,12 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - **真实 run(CSI500 `000905.SH`,2021-06-01→2026-05-31,59 月调仓,~95min)**:`covered=892/995`(**103 只分钟未覆盖成分被 drop 并披露,5 年窗口不缩短**)/ `stk_mins_live_calls=0`(cache-only)/ `fee_rate=0.001`;final NAV Q1→Q5 **0.9822 / 1.0423 / 1.0495 / 1.1275 / 1.1577**(**单调 Spearman 1.0000**,等额 rank 桶对 MMP 肥尾稳健);合成 Q5−Q1 spread +0.29%/期、累计 **+17.15%**;限价覆盖 52,584/52,584(严格 `require_price_limit_coverage=true` 过)。 - ⚠️ **caveat(保留,不移除)**:单因子/单重叠 5 年窗口/单 universe,无调参/无 robustness/无 learned 权重;`covered=892/995`(103 drop);`stk_mins_live_calls=0`;**Q5−Q1 是合成 long-only 腿差,非单独执行的 dollar-neutral 组合**;执行模型仍缺 partial-fill / liquidity / volume-cap;**Q5>Q1 不作业绩声明**。这是项目首个正向 intraday 信号,下一步需独立泛化(CSI300/中证1000 或 disjoint 窗口,机器冻结)。 - **PR 处置**:#37(I5c)随 #39 落地后其 head 成 `main` 祖先,GitHub **自动 merged**(非本次手动 merge);#38(i5d stacked on i5c,base 非 main)已被 #39 **完全取代**(零 remaining commit/file diff vs main),保持 **OPEN 待清理**(未获显式授权关闭)。 +- ✅ **P-I5e MMP 五分位 CSI300 独立泛化检验**(**PR #53 已 merge 到 `main`**,**EXPLORATORY,非业绩声明、非调参;负结果**):冻结已验收的 I5d MMP 五分位机器,在**独立 universe** CSI300(`000300.SH`)同窗口(2021-06-01→2026-05-31)复跑,检验 I5d 在 CSI500 上的 Q1→Q5 单调性是否归因于因子而非 universe/regime。**仅加一个 config(`config/phase_i5e_mmp_quintile_csi300_generalization.yaml`),零代码/机器改动**——MMP 数学 / 等额 rank 桶(Q1 最低 Q5 最高)/ I5a/I5b 尾盘 event model(14:50 决策 / 14:51 执行 / exec-to-exec)/ raw `stk_limit` 执行可行性 / cache-only anchor-date 分钟加载全冻结;report 名/标题已 config 驱动故无需改代码。本地 handoff:`tmp/context/session_handoff_20260620/cc_goal_i5d_independent_generalization_20260620/`。 + - **Preflight 选 CSI300(非 fallback CSI1000)**:全窗口 481 distinct 成分,分钟全窗口覆盖 **448/481=93.1%**(≥ CSI500 89.6%)→ 够切 5 等额组,窗口不缩短;CSI300 日频成分 ledger 诚实仅覆盖近 1 年(无谎报、无静默截断),缺的经 P4 日频 read-through 补(21 次 index_weight,允许,同 I5d)。 + - **真实 run(CSI300,59 月调仓,~30min)**:`covered=448/481`(**33 只分钟未覆盖成分 drop 并披露,5 年窗口不缩短**)/ `stk_mins_live_calls=0`(cache-only,缺分钟即 hard miss 绝不暖)/ `fee_rate=0.001`;限价覆盖 26386/26386 全过。 + - **结论:FAILS / 不泛化**。final NAV Q1→Q5 **0.8809 / 0.7377 / 0.9418 / 0.7573 / 0.6665**;年化 **−2.55% / −6.00% / −1.21% / −5.50% / −7.92%**;**单调 Spearman −0.5000**(vs CSI500 +1.0000);合成 Q5−Q1 累计 **−26.77%**(vs CSI500 +17.15%)。**Q5(高 MMP)在 CSI300 上最差**——高 MMP 组不跑赢低 MMP 组,I5d 的 CSI500 单调性在独立 universe 上**反转**,强烈提示其为 universe/regime 特异、非稳健因子属性。这正是独立检验要拿到的证据。 + - ⚠️ **caveat(保留)**:单因子/单重叠 5 年窗口/单 universe;Q5−Q1 是合成 long-only 腿差非 dollar-neutral 执行;丢弃未覆盖分钟名的 coverage bias;执行模型仍缺 partial-fill/liquidity/volume-cap;无调参/无 learned alpha;**非业绩声明**。CSI500 对照仅作 context,不作任何组业绩声明。 + - **回归不破 + 范围克制**:phase0 `0.9600/0.8408` 不变;`pytest` 678 passed(677 基线 + `test_cache_config.py` 的 `config/*.yaml` glob 参数化自动覆盖新 config 的 +1,无新测试文件);**不动 progress docs 以外的代码/config/test**,不碰 schema registry / D6;**PR #38 未动**。 - ✅ **数据层 D1 — cache/store 契约文档化 + token 解析去重**(**PR #41 已 merge 到 `main`**,行为保持型重构,非研究/非数据语义变更):数据层第一步低风险清理,只做两件事——把 `cache` vs `store` 边界写成可提交契约,并把重复的 token 解析收敛到既有 `data/feed/secret.py::read_token`。 - **契约文档** `docs/data/data_layer_contracts.md`:`data/cache` = 可复用 raw endpoint 缓存 / SoT;`data/store/PanelStore` = per-run canonical 面板 artifact(非 raw lake,`artifacts/data/*.parquet` 不当缓存权威);缓存只存 raw;`front_adjust` / PIT 成分 / PIT SW 行业 / `ann_date` 财务对齐 / raw 涨跌停检查 / factor·alpha·portfolio·runtime 数学全在下游;`data-update` 只暖缓存不跑研究;data-quality + 并发是后续阶段(不声称已实现)。 - **token 去重**:`tushare_feed.py` 删掉重复的 module-level `_lookup_dotted` + 内联 json/Path 解析(`_read_token` 变 `read_token(...)` 一行 wrapper);`index_feed.py` 不再从 `tushare_feed` 导入私有 `_lookup_dotted`,`_client` 直接走 `read_token`。`_lookup_dotted` 全仓清零;6 个 tushare feed(feed/index/flags/fina/intraday/covariates)统一走 `secret.read_token`。构造签名 / `__repr__` token 安全 / fetch+cache 路径全不变;+2 窄测试锁定 index feed 真实 token 路径(fake config、不碰网络、不泄漏)。 @@ -241,6 +247,6 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - **缓存并发**(`TushareCache(max_workers=)`):`==1` 串行字节级不变;`>1` 且多 symbol → **只有日频密集 per-symbol 取数**走有界 `ThreadPoolExecutor`,**store upsert + ledger 写仍在主线程按计划序**(成功 gap 先 durable 再抛首个失败,失败 gap 不记覆盖、可重试;store/ledger 内容与取数完成序无关)。snapshot / `index_weight` 90 天分页 / intraday 在 D5 仍串行(并发开启时仍共享同一限频器)。 - **updater 接线**:`run_data_update` 仅 `max_workers>1` 才建**一个** `GlobalRateLimiter`(用 `rate_limit_per_min`),经 `_build_feeds` 共享给全部 feed(6 个 feed 加 `scheduler=None` 默认不变参);`UpdateResult`+`format_summary` 暴露 `max_workers`/全局 `rate_limit_per_min`(非密)。 - **测试**(`tests/test_scheduler.py` + `tests/test_data_update_concurrency.py`,network-free,21):全局时隙在争用下逐次升 sleep(fake clock)/ **8 线程实测全局非按线程**(`next_allowed==N*interval`)/ 重试逐次 acquire / scheduler 模式不做 per-call sleep / 失败 secret-safe(仅异常类型)/ feed 转发其 scheduler / config 校验(`<1` 拒;默认 1)/ **serial==concurrent** 帧·ledger·请求计数 / 失败留 gap 未覆盖可重试而成功 durable / empty·not_ready 不变 / 单 symbol 仍串行。真实 token 扫描 **0 hits**;**未跑 live `data-update`**(network-free 验收)。 -- ✅ 质量门:`pytest` **677 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 / 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**);`ruff` clean;`validate-config`(全部 17 配置含 data_update + phase_i5a + phase_i5b + phase_i5c + phase_i5d)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 不变**)。 +- ✅ 质量门:`pytest` **678 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)/ 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**);`ruff` clean;`validate-config`(全部 18 配置含 data_update + phase_i5a + phase_i5b + phase_i5c + phase_i5d + phase_i5e)+ `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 起不再互覆盖)。 -- 路线图下一步:**I5d 独立泛化**(MMP 五分位单调性是项目首个正向 intraday 信号,但只一个重叠 5 年窗口/一个 universe → 在第二个 universe(CSI300/中证1000)和/或 disjoint 窗口上机器冻结复跑分组回测,使单调性可归因于因子而非该 regime,沿 P3-7/P3-8 独立确认先例);**I5b/执行 follow-up**(执行期 feasibility 可再扩 partial-fill / liquidity / volume cap,size-aware 读数前补);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / updater 加 stk_mins 历史回填 / 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 有界并发 + 全局限频器;剩余数据层 follow-up:**endpoint schema registry** 仍延后;**D6**=`PanelStore` append/partition / 可选物化派生面板存储,**仅当因子研究需要可复用派生面板时才启动**——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。 +- 路线图下一步:**MMP 暂缓推进(I5e 负结果)**(I5e 已在独立 universe CSI300 同窗口机器冻结复跑 → 单调性 **FAILS/反转**(Spearman −0.5,Q5 高 MMP 最差,合成 Q5−Q1 累计 −26.77%);I5d 的 CSI500 单调性疑 universe/regime 特异、**非稳健** → **在出现 disjoint 窗口 / 第三 universe 的正向证据前,不把 MMP 当稳健或可交易信号推进**;新 intraday 因子候选只作显式 EXPLORATORY 工作);**I5b/执行 follow-up**(执行期 feasibility 可再扩 partial-fill / liquidity / volume cap,size-aware 读数前补);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / updater 加 stk_mins 历史回填 / 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 有界并发 + 全局限频器;剩余数据层 follow-up:**endpoint schema registry** 仍延后;**D6**=`PanelStore` append/partition / 可选物化派生面板存储,**仅当因子研究需要可复用派生面板时才启动**——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。 diff --git a/CLAUDE.md b/CLAUDE.md index cfed104..d36b2f3 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 有界并发 + 全局限频器)均已 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 独立泛化检验,负结果)均已 merge 到 `main`**。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。 - **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。 - **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。 - 文件小而专(<800 行),immutable 优先。 @@ -213,6 +213,12 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - **真实 run(CSI500 `000905.SH`,2021-06-01→2026-05-31,59 月调仓,~95min)**:`covered=892/995`(**103 只分钟未覆盖成分被 drop 并披露,5 年窗口不缩短**)/ `stk_mins_live_calls=0`(cache-only)/ `fee_rate=0.001`;final NAV Q1→Q5 **0.9822 / 1.0423 / 1.0495 / 1.1275 / 1.1577**(**单调 Spearman 1.0000**,等额 rank 桶对 MMP 肥尾稳健);合成 Q5−Q1 spread +0.29%/期、累计 **+17.15%**;限价覆盖 52,584/52,584(严格 `require_price_limit_coverage=true` 过)。 - ⚠️ **caveat(保留,不移除)**:单因子/单重叠 5 年窗口/单 universe,无调参/无 robustness/无 learned 权重;`covered=892/995`(103 drop);`stk_mins_live_calls=0`;**Q5−Q1 是合成 long-only 腿差,非单独执行的 dollar-neutral 组合**;执行模型仍缺 partial-fill / liquidity / volume-cap;**Q5>Q1 不作业绩声明**。这是项目首个正向 intraday 信号,下一步需独立泛化(CSI300/中证1000 或 disjoint 窗口,机器冻结)。 - **PR 处置**:#37(I5c)随 #39 落地后其 head 成 `main` 祖先,GitHub **自动 merged**(非本次手动 merge);#38(i5d stacked on i5c,base 非 main)已被 #39 **完全取代**(零 remaining commit/file diff vs main),保持 **OPEN 待清理**(未获显式授权关闭)。 +- ✅ **P-I5e MMP 五分位 CSI300 独立泛化检验**(**PR #53 已 merge 到 `main`**,**EXPLORATORY,非业绩声明、非调参;负结果**):冻结已验收的 I5d MMP 五分位机器,在**独立 universe** CSI300(`000300.SH`)同窗口(2021-06-01→2026-05-31)复跑,检验 I5d 在 CSI500 上的 Q1→Q5 单调性是否归因于因子而非 universe/regime。**仅加一个 config(`config/phase_i5e_mmp_quintile_csi300_generalization.yaml`),零代码/机器改动**——MMP 数学 / 等额 rank 桶(Q1 最低 Q5 最高)/ I5a/I5b 尾盘 event model(14:50 决策 / 14:51 执行 / exec-to-exec)/ raw `stk_limit` 执行可行性 / cache-only anchor-date 分钟加载全冻结;report 名/标题已 config 驱动故无需改代码。本地 handoff:`tmp/context/session_handoff_20260620/cc_goal_i5d_independent_generalization_20260620/`。 + - **Preflight 选 CSI300(非 fallback CSI1000)**:全窗口 481 distinct 成分,分钟全窗口覆盖 **448/481=93.1%**(≥ CSI500 89.6%)→ 够切 5 等额组,窗口不缩短;CSI300 日频成分 ledger 诚实仅覆盖近 1 年(无谎报、无静默截断),缺的经 P4 日频 read-through 补(21 次 index_weight,允许,同 I5d)。 + - **真实 run(CSI300,59 月调仓,~30min)**:`covered=448/481`(**33 只分钟未覆盖成分 drop 并披露,5 年窗口不缩短**)/ `stk_mins_live_calls=0`(cache-only,缺分钟即 hard miss 绝不暖)/ `fee_rate=0.001`;限价覆盖 26386/26386 全过。 + - **结论:FAILS / 不泛化**。final NAV Q1→Q5 **0.8809 / 0.7377 / 0.9418 / 0.7573 / 0.6665**;年化 **−2.55% / −6.00% / −1.21% / −5.50% / −7.92%**;**单调 Spearman −0.5000**(vs CSI500 +1.0000);合成 Q5−Q1 累计 **−26.77%**(vs CSI500 +17.15%)。**Q5(高 MMP)在 CSI300 上最差**——高 MMP 组不跑赢低 MMP 组,I5d 的 CSI500 单调性在独立 universe 上**反转**,强烈提示其为 universe/regime 特异、非稳健因子属性。这正是独立检验要拿到的证据。 + - ⚠️ **caveat(保留)**:单因子/单重叠 5 年窗口/单 universe;Q5−Q1 是合成 long-only 腿差非 dollar-neutral 执行;丢弃未覆盖分钟名的 coverage bias;执行模型仍缺 partial-fill/liquidity/volume-cap;无调参/无 learned alpha;**非业绩声明**。CSI500 对照仅作 context,不作任何组业绩声明。 + - **回归不破 + 范围克制**:phase0 `0.9600/0.8408` 不变;`pytest` 678 passed(677 基线 + `test_cache_config.py` 的 `config/*.yaml` glob 参数化自动覆盖新 config 的 +1,无新测试文件);**不动 progress docs 以外的代码/config/test**,不碰 schema registry / D6;**PR #38 未动**。 - ✅ **数据层 D1 — cache/store 契约文档化 + token 解析去重**(**PR #41 已 merge 到 `main`**,行为保持型重构,非研究/非数据语义变更):数据层第一步低风险清理,只做两件事——把 `cache` vs `store` 边界写成可提交契约,并把重复的 token 解析收敛到既有 `data/feed/secret.py::read_token`。 - **契约文档** `docs/data/data_layer_contracts.md`:`data/cache` = 可复用 raw endpoint 缓存 / SoT;`data/store/PanelStore` = per-run canonical 面板 artifact(非 raw lake,`artifacts/data/*.parquet` 不当缓存权威);缓存只存 raw;`front_adjust` / PIT 成分 / PIT SW 行业 / `ann_date` 财务对齐 / raw 涨跌停检查 / factor·alpha·portfolio·runtime 数学全在下游;`data-update` 只暖缓存不跑研究;data-quality + 并发是后续阶段(不声称已实现)。 - **token 去重**:`tushare_feed.py` 删掉重复的 module-level `_lookup_dotted` + 内联 json/Path 解析(`_read_token` 变 `read_token(...)` 一行 wrapper);`index_feed.py` 不再从 `tushare_feed` 导入私有 `_lookup_dotted`,`_client` 直接走 `read_token`。`_lookup_dotted` 全仓清零;6 个 tushare feed(feed/index/flags/fina/intraday/covariates)统一走 `secret.read_token`。构造签名 / `__repr__` token 安全 / fetch+cache 路径全不变;+2 窄测试锁定 index feed 真实 token 路径(fake config、不碰网络、不泄漏)。 @@ -241,6 +247,6 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri - **缓存并发**(`TushareCache(max_workers=)`):`==1` 串行字节级不变;`>1` 且多 symbol → **只有日频密集 per-symbol 取数**走有界 `ThreadPoolExecutor`,**store upsert + ledger 写仍在主线程按计划序**(成功 gap 先 durable 再抛首个失败,失败 gap 不记覆盖、可重试;store/ledger 内容与取数完成序无关)。snapshot / `index_weight` 90 天分页 / intraday 在 D5 仍串行(并发开启时仍共享同一限频器)。 - **updater 接线**:`run_data_update` 仅 `max_workers>1` 才建**一个** `GlobalRateLimiter`(用 `rate_limit_per_min`),经 `_build_feeds` 共享给全部 feed(6 个 feed 加 `scheduler=None` 默认不变参);`UpdateResult`+`format_summary` 暴露 `max_workers`/全局 `rate_limit_per_min`(非密)。 - **测试**(`tests/test_scheduler.py` + `tests/test_data_update_concurrency.py`,network-free,21):全局时隙在争用下逐次升 sleep(fake clock)/ **8 线程实测全局非按线程**(`next_allowed==N*interval`)/ 重试逐次 acquire / scheduler 模式不做 per-call sleep / 失败 secret-safe(仅异常类型)/ feed 转发其 scheduler / config 校验(`<1` 拒;默认 1)/ **serial==concurrent** 帧·ledger·请求计数 / 失败留 gap 未覆盖可重试而成功 durable / empty·not_ready 不变 / 单 symbol 仍串行。真实 token 扫描 **0 hits**;**未跑 live `data-update`**(network-free 验收)。 -- ✅ 质量门:`pytest` **677 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 / 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**);`ruff` clean;`validate-config`(全部 17 配置含 data_update + phase_i5a + phase_i5b + phase_i5c + phase_i5d)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 不变**)。 +- ✅ 质量门:`pytest` **678 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)/ 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**);`ruff` clean;`validate-config`(全部 18 配置含 data_update + phase_i5a + phase_i5b + phase_i5c + phase_i5d + phase_i5e)+ `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 起不再互覆盖)。 -- 路线图下一步:**I5d 独立泛化**(MMP 五分位单调性是项目首个正向 intraday 信号,但只一个重叠 5 年窗口/一个 universe → 在第二个 universe(CSI300/中证1000)和/或 disjoint 窗口上机器冻结复跑分组回测,使单调性可归因于因子而非该 regime,沿 P3-7/P3-8 独立确认先例);**I5b/执行 follow-up**(执行期 feasibility 可再扩 partial-fill / liquidity / volume cap,size-aware 读数前补);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / updater 加 stk_mins 历史回填 / 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 有界并发 + 全局限频器;剩余数据层 follow-up:**endpoint schema registry** 仍延后;**D6**=`PanelStore` append/partition / 可选物化派生面板存储,**仅当因子研究需要可复用派生面板时才启动**——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。 +- 路线图下一步:**MMP 暂缓推进(I5e 负结果)**(I5e 已在独立 universe CSI300 同窗口机器冻结复跑 → 单调性 **FAILS/反转**(Spearman −0.5,Q5 高 MMP 最差,合成 Q5−Q1 累计 −26.77%);I5d 的 CSI500 单调性疑 universe/regime 特异、**非稳健** → **在出现 disjoint 窗口 / 第三 universe 的正向证据前,不把 MMP 当稳健或可交易信号推进**;新 intraday 因子候选只作显式 EXPLORATORY 工作);**I5b/执行 follow-up**(执行期 feasibility 可再扩 partial-fill / liquidity / volume cap,size-aware 读数前补);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / updater 加 stk_mins 历史回填 / 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 有界并发 + 全局限频器;剩余数据层 follow-up:**endpoint schema registry** 仍延后;**D6**=`PanelStore` append/partition / 可选物化派生面板存储,**仅当因子研究需要可复用派生面板时才启动**——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。