From 8addce4a683faa257e0e3983713bfb25be8822cd Mon Sep 17 00:00:00 2001 From: ao gong <41768719+ageorge156@users.noreply.github.com> Date: Fri, 21 Aug 2026 22:31:14 +0800 Subject: [PATCH] wip: hand off research artifact contract --- README.md | 23 ++++++++++++ docs/OPEN_SOURCE_REFERENCES.md | 11 ++++++ .../2026-08-21-research-artifact-contract.md | 37 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 docs/handoff/2026-08-21-research-artifact-contract.md diff --git a/README.md b/README.md index 2a3cf2d..4e8049e 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ - `backtest` — weight-based 多日仿真(rebalance_table / compute_nav / compare_to_benchmark) - `portfolio_construction` — 多期因子分数 → Top-K → 等权目标权重表 - `research_pipeline` — 因子日 → 下一真实交易日 → 显式执行价 → 日末估值 → 成本后绩效(防前视编排) +- `artifact` — 版本化、确定性、存储中立的完整 research run 事实表与 manifest - `attribution` — 基于实际成交后持仓的隔夜 / 日内 / 交易成本逐日收益归因与闭合审计 - `metrics` — 绝对绩效 + 严格日期对齐的 TE / IR / alpha / beta 基准相对绩效 - `factor_library` — 通用方法(turnover / winsorize / IC / OLS / jb_test) @@ -136,6 +137,28 @@ print(attribution.residual) # 应接近 0;否则说明贡献未闭合到账 # benchmark_returns 必须与成本后 factor_backtest.returns 使用完全相同的日期索引。 print(factor_backtest.benchmark_stats(benchmark_returns)) +# 下游稳定交付:显式提供代码版本、数据快照和时区,不在核心层写数据库。 +from quant_engine.artifact import build_research_run_artifact + +artifact = build_research_run_artifact( + factor_backtest, + run_id="research-run-001", + strategy_id="alpha-top20", + strategy_name="Alpha Top 20", + strategy_version="1.0.0", + engine_version="1.2.0", + code_revision="", + data_snapshot_id="", + calendar="CN-A", + timezone="Asia/Shanghai", + started_at="2026-08-21T10:00:00+08:00", + finished_at="2026-08-21T10:01:00+08:00", + parameters={"top_k": 20, "lag_sessions": 1}, + benchmark_id="000300.SH", + benchmark_returns=benchmark_returns, +) +print(artifact.manifest()) + # run_weight_backtest 是低层算子:只接受收益区间开始前已经生效的持仓权重。 # 不要把 signal-date 的 factor_scores/decision_weights 直接传给它。 backtest = run_weight_backtest( diff --git a/docs/OPEN_SOURCE_REFERENCES.md b/docs/OPEN_SOURCE_REFERENCES.md index fd2a6fa..a282955 100644 --- a/docs/OPEN_SOURCE_REFERENCES.md +++ b/docs/OPEN_SOURCE_REFERENCES.md @@ -16,6 +16,17 @@ 当前核心不新增依赖。逐日收益归因必须从实际换仓前后持仓、成交记录、执行价和 收盘估值推导;因子分数与目标权重只是意图,不能作为成交后归因事实源。 +## 2026-08-21:研究运行工件 + +- 借鉴 [Qlib Recorder / RecordTemplate](https://github.com/microsoft/qlib/blob/main/qlib/workflow/record_temp.py) + 将 signal、portfolio analysis 和 risk analysis 分成稳定事实,但不引入 Qlib 运行时; +- 借鉴 [MLflow Tracking](https://mlflow.org/docs/latest/tracking/) 的 run / params / + metrics / artifacts 分层,但 MLflow 只保留为未来可选 exporter; +- HTML、PNG 和 tearsheet 是可再生展示物,不能替代 NAV、成交、持仓、归因和绩效事实。 + +因此 `ResearchRunArtifact` 使用显式 `schema_version`、`config_hash`、代码版本和数据 +快照身份,并提供确定性 JSON / SHA-256 manifest;核心层仍不写数据库或 artifact store。 + ## hikyuu 的定位 [hikyuu](https://github.com/fasiondog/hikyuu) 的 SG / MM / CN / PG 部件化思想、 diff --git a/docs/handoff/2026-08-21-research-artifact-contract.md b/docs/handoff/2026-08-21-research-artifact-contract.md new file mode 100644 index 0000000..f982f99 --- /dev/null +++ b/docs/handoff/2026-08-21-research-artifact-contract.md @@ -0,0 +1,37 @@ +# Research artifact contract handoff + +## Goal + +把完整可信研究链固化成存储中立、版本化、确定性的 `ResearchRunArtifact`,供 +`research_results` 持久化和 `research_platform` 查询: + +- run identity / schema version / config hash / code revision / data snapshot; +- signal scores / decision weights / signal-to-execution mapping; +- NAV / returns / benchmark / costs; +- trades / realized positions / cash; +- asset and daily return attribution; +- performance including Sortino / TE / IR / alpha / beta; +- reserved risk snapshot table; +- canonical JSON / SHA-256 manifest。 + +## Branch stack + +- 当前:`codex/research-artifact-contract-20260821` +- 基线:`codex/ledger-attribution-20260821`(Draft PR #4) +- 下层:Draft PR #3 → Ready PR #2 → `main` + +不得绕过堆叠顺序直接合并到 `main`。 + +## Verification + +- `pytest -q --cov=src --cov-report=term-missing`: 520 passed,9 个既有 SciPy warning; +- total coverage 91%,`artifact.py` 91%; +- `mypy --strict src/`: 16 source files passed; +- changed-scope Ruff: passed; +- no runtime dependency added; +- no database, network, broker or filesystem write side effect in artifact builder。 + +## Next action + +在 `research_results` 新建独立分支,实现只接受 `ResearchRunArtifact.table_frames()` 的 +ClickHouse / artifact-store adapter;先以 mock writer 做契约测试,不接触真实数据库。