Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)均已 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)均已 merge 到 `main`**。commit 用 conventional 格式,**无 attribution**(不加 Co-Authored-By)。
- **不过度设计**:按路线图 MVP 先打通一条端到端链路,再加层(architecture.html §11,Phase 0→3)。
- **secrets** 一律走外部 `.config.json`;repo `.gitignore` 已排除数据产物(`*.parquet`等)、缓存、`tmp/`(仅留架构文档)。
- 文件小而专(<800 行),immutable 优先。
Expand Down Expand Up @@ -205,6 +205,14 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri
- **接线**:`IntradayCfg.{price_limit_check(默认 false)/require_price_limit_coverage/limit_tolerance(≥0 校验)}` + `OutputCfg.intraday_report_name`(I5b 报告独立成文件,不覆盖已验收 I5a artifact,沿 baseline_report_name 先例);runner 经 `TushareFlagsFeed(cache=cache).limits()` 走既有 P4 read-through 缓存取 raw 限价(**不加新端点**),报告 H1/intro 按 check 自报 I5b(修同类 stale-title)。
- **不变量守住**:`BacktestEngine`/`BacktestDriver`/`DailyCloseEventModel`/`fills`/`execution` **零改动**(限价 map 仅 check 开时构建,默认 false → `feasibility()` 逐字退回 I5a bar-exists 规则);日频 close-to-close 不漂移。
- **真实 smoke(SSE50 2026-03-03→06-12,3 次跑 NAV 全 `0.976448` 确定性)**:`covered=58/58 / stk_mins_live_calls=0`;限价覆盖 **174/174**;**1 笔涨停挡买 / 0 笔跌停挡卖** → NAV 由 I5a 的 0.952207 变到 **0.976448**(2026-04-30 一只 14:51 封涨停的票被正确挡买,该期只持 9 只——I5a 只查 bar 存在会「买」进涨停板,**这正是 I5b 补的执行真实性,非业绩声明**);`stk_limit` gap-fetches=58(冷暖都 58:窗口尾端距今 3 天落在 `refresh_recent_days=14` 内,P4 按策略重抓 tail,据实报告,非 minute fetch);secret scan 报告+日志+58 缓存 parquet **0 处**。
- ✅ 质量门:`pytest` **538 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**);`ruff` clean;`validate-config`(全部 15 配置含 data_update + phase_i5a + phase_i5b)+ `run-phase0`(demo)均 OK(**ic 0.9600 / annual 0.8408 不变**)。
- ✅ **P-I5c MMP 分钟因子端到端 opt-in alpha**(**PR #37 已 merge 到 `main`**,**EXPLORATORY**,非业绩声明):把首个 EXPLORATORY 分钟因子作为真实 opt-in alpha 端到端接 I2→I3→I4→event engine,日频回归不破。
- **MMP(Minute Microstructure Pressure)**(`data/clean/intraday_aggregate.py`,公式/PIT/前导 NaN/跨 symbol 隔离全测试锁定):逐 1min bar `mid=(high+low)/2`、`S=(close−mid)/mid`、`V=√(volume/median(vol[t-20:t]))`、`B=|close−open|/(high−low+eps)`、`R=(high−low)/(mean(hl[t-20:t])+eps)`、`MMP_t=S·V·B·R`(eps=1e-6);日频分数 = 在场 bar `[session_open, decision_time]` 等权均值,rolling baseline 用前 20 个在场 bar(首 20 NaN)。**先 `available_time≤cutoff` 过滤再聚合**(PIT-safe,绝不先归零)。
- **可配置 `intraday.score_feature`**(默认沿用,`mmp_ew` opt-in)+ 可配置报告标题(修同类 stale-title);`config/phase_i5c_mmp_minute_factor.yaml`。decision feature→alpha→portfolio→event engine 全程复用既有机器,报告披露 cutoff/lag/execution_model/window。**日频 close-to-close 零漂移**(phase0 `0.9600/0.8408` 不变)。
- ✅ **P-I5d MMP 五分位分组回测**(**PR #39 已 merge 到 `main`**,**standalone against `main`**,**EXPLORATORY,非业绩声明、非调参**):把 I5c MMP 日频分数 `intraday_mmp20_ew_0930_1450` 做 5 等额分位分组回测——每月调仓日按 PIT-safe 分数横截面排名切 `analytics.quantiles=5` 等数桶(Q1 最低 / Q5 最高),每组作独立 long-only 等权组合走**同一** `BacktestEngine`+`IntradayTailEventModel`+`SimExecution(fee_rate=0.001)`,I5b raw `stk_limit` 执行期涨跌停 ON。引擎/执行可行性/MMP 因子数学全不变,仅新增分组 + per-group 编排。本地验收:`tmp/context/session_handoff_20260615/stage_i5d_acceptance.md`。
- **新增**(机器零改动复用 I5a/I5b/I5c):`qt/intraday_groups.py`(等额 rank 桶 / `GroupScores` / `EqualWeightAll`)、`qt/intraday_group_backtest.py`(cache-only anchor-date-sliced 分钟加载、一份共享 exec-price 矩阵跨 N 个 fresh per-group 模型、QN−Q1 合成 spread)、`qt/intraday_group_figures.py`/`intraday_group_report.py`(NAV/spread/metric 图 + 报告)、`config/phase_i5d_mmp_quintile_5y.yaml`;唯一 runtime 改动 `IntradayTailEventModel` 可选 `precomputed_prices`(默认 None → I5a/I5b 逐字节不变)。
- **真实 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 待清理**(未获显式授权关闭)。
- ✅ 质量门:`pytest` **577 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**);`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 不变**)。
- ⚠️ 剩余(已显式披露):日线 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 起不再互覆盖)。
- 路线图下一步:**分钟级轨道 I5c**(执行真实性已就位:I5a 事件框架 + I5b raw `stk_limit` 执行期涨跌停把 1~2 个 EXPLORATORY 分钟因子作为真实 opt-in alpha 端到端接 decision feature→alpha→portfolio→event engine,报告披露 cutoff/lag/execution_model/window,日频回归不破;首个分钟因子研究不会被后续可行性修复推翻);**I5b follow-up**(执行期 feasibility 可再扩 partial-fill / liquidity / volume cap);**P4-3 follow-up**(fina 按 ann_date 建披露日历 ledger 以去掉启发式 tail / updater 加 stk_mins 历史回填 / data-update summary 落 cache-stats artifact);研究侧:更长 holdout 滚动复检 / 中证1000 / 成本模型细化。
- 路线图下一步:**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);**数据层 D1+**(cache/store 契约已文档化,token 解析已收敛,后续 D2+ 再做 cache 内部拆分/schema registry/data-quality/并发);研究侧:更长 holdout 滚动复检 / 成本模型细化。