Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 7 additions & 3 deletions AGENTS.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)、#37(P-I5c MMP 分钟因子端到端 opt-in alpha)、#39(P-I5d MMP 五分位分组回测 standalone,含 I5c plumbing)、#41(数据层 D1 契约文档 + token 解析去重)、#43(数据层 D2 TushareCache specs/parsers 拆分)均已 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 数据质量层)均已 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 @@ -220,6 +220,10 @@ data → universe → factors(特征) → alpha(合成/预测) → portfolio(+ri
- ✅ **数据层 D2 — TushareCache endpoint specs/parsers 拆分**(**PR #43 已 merge 到 `main`**,行为保持型内部重构,**公开缓存语义零变更**,非性能/并发/data-quality 层):把 814 行的 `data/cache/tushare_cache.py` 内部拆成小文件,让 endpoint 元数据与 raw 解析器可单独审阅,`TushareCache` 仍是公开门面。
- **拆分**(解析器逐字搬移,行为靠既有 cache 测试锁定):`tushare_specs.py`(89 行,endpoint ids/`ALL_ENDPOINTS`/`_GLOBAL_KEY`/列集+自然键/`FINA_FIELDS`/`_INDEX_WINDOW_DAYS`/rename maps,纯常量)、`tushare_parsers.py`(216 行,10 个 `_parse_*`)、`tushare_planning.py`(22 行,叶子 helper `_fields_hash`/`_compact`);`tushare_cache.py` **814→596 行**,保留 `TushareCache` 门面 + read-through 引擎(gap 规划 / index_weight 90 天分页 / snapshot staleness / `refresh_recent_days`·`recent_tail_overrides`·`not_ready_days`·`force_refresh` / ok·empty·not_ready·failed coverage / 逐自然键 upsert / `stats`·`update_summary`)+ `FetchOne`/`FetchSnapshot`。
- **向后兼容导入保持**:门面 re-export endpoint ids + `FINA_FIELDS` + `ALL_ENDPOINTS`,`from data.cache.tushare_cache import DAILY_BASIC/FINA_FIELDS/INDEX_WEIGHT/...`(被 `tushare_fina.py` + cache 测试用)全照常;新增 5 个窄测试锁定 re-export identity + 模块边界。**公开方法/签名/内部规划/coverage 语义全不变**;phase0 `0.9600/0.8408` 不变。**非目标(D3+)**:schema registry / data-quality / 并发 / `CoverageLedger` 存储 / `PanelStore` append·partition / intraday 缓存重构 / 限频重试,均未做。
- ✅ 质量门:`pytest` **584 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**);`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 不变**)。
- ✅ **数据层 D3 — report-only 数据质量层**(**PR #45 已 merge 到 `main`**,含 review 一修复;纯库 + 测试,**report-only 非 cleaning**):新增独立 `data/quality/` 包,在接入处附近**只报告**可疑上游数据,**绝不**过滤行/修复值/改 qfq/改 cache coverage/动 feed·factor·alpha·portfolio·runtime。
- **包**(纯函数,输入 DataFrame→findings,输入永不被改):`report.py`(`QualityFinding` + `make_finding`(样本限 5、清洗)+ `findings_to_frame`(稳定确定序)+ `render_report`(确定性 Markdown,clean→"No findings")+ secret redaction);`market.py`(日频:dup(date,symbol)/非正 OHLC/high<low/close 越界/负 volume·amount/非法 adj_factor=hard;极端日涨跌/缺日历日=warning);`intraday.py`(1min:dup bars/时间戳非单调/非正 OHLC/high<low/close 越界/负 volume·amount=hard;缺分钟=warning);`_frames.py`(纯 helper)。clean 面板→零 hard;"hard" 只是报告级别不抛异常。
- **secret-safe renderer 修复**(review):`sanitize_text` 把 `.config.json` 路径 / `tushare.token` / `token=...` 值 redact 成 `[REDACTED]`,应用于 `clean_value`(example 值)/`make_finding`(note)/`_format_examples`(渲染);存储 finding 与渲染报告双双不泄漏(benign symbol/日期仍渲染)。
- **范围克制**:scope-smell 扫描 0 hits(质量层不碰 runtime/alpha/portfolio/cache 内部);**可选 `data-update` 集成推迟到 D3b**(本阶段仅库 + 测试,零 config/命令行为变更);phase0 `0.9600/0.8408` 不变。
- ✅ 质量门:`pytest` **625 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**);`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 起不再互覆盖)。
- 路线图下一步:**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);**数据层 D3+**(D1+D2 已 merge:契约文档化 + token 解析收敛 + `TushareCache` specs/parsers 拆分;下一步 endpoint schema registry / data-quality validator / 并发——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。
- 路线图下一步:**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);**数据层 D3b / D4**(D1+D2+D3 已 merge:契约文档化 + token 解析收敛 + `TushareCache` specs/parsers 拆分 + report-only `data/quality/` 质量层;下一步 **D3b**=可选 default-off 的 `data-update` 质量报告钩子(把质量层接入运维,仅日志/小 artifact、不挂作业),或 **D4**=`CoverageLedger` 存储扩展 / batch 写入;之后再 endpoint schema registry / 并发——均尚未实现);研究侧:更长 holdout 滚动复检 / 成本模型细化。
Loading