复现性:版本、种子与环境
复现性的定义
Section titled “复现性的定义”一次研究的复现性由四件事共同决定:数据版本、代码版本、随机种子、依赖环境——缺任何一件,半年后就无法重跑出同样的曲线。这也是 存储格式 一节强调"数据不可变"的原因:可复现的前提是数据本身可指认。
四个版本,一个快照
Section titled “四个版本,一个快照”- 数据版本:不用"最新数据",用快照日期——每次回测记录"截至 2024-06-28 的数据",数据更新不覆盖旧快照(或用 DVC/数据版本工具管理);
- 代码版本:git commit 哈希写入回测输出,dirty 状态直接拒跑;
- 随机种子:bootstrap、ML 训练、任何带随机性的步骤固定种子并记录;
- 依赖环境:lock 文件(
uv.lock/poetry.lock/ conda env export)固定到补丁版本。
最小可复现研究项目
Section titled “最小可复现研究项目”research/ pyproject.toml + uv.lock # 依赖锁定 data/ snapshot_2024-06-28/ # 数据快照(或 DVC 指针) src/ signals.py # 信号定义(回测与实盘共用,见第十一卷) pipeline.py # 清洗与对齐 experiments/ 2024-06-28_mom12-1/ config.yaml # 全部参数 run.log # git commit + 种子 + 数据快照日期 result.parquet # 净值与持仓 README.mddata_snapshot: "2024-06-28"seed: 42signal: type: "ts_momentum" lookback: 12 skip: 1vol_target: 0.10常见借口与反驳
Section titled “常见借口与反驳”| 借口 | 反驳 |
|---|---|
| "数据天天更新,没法固定版本" | 快照日期就是版本;更新只写新快照 |
| "就我自己用,不用那么正式" | 复现性不是给别人看的,是给半年后的你 |
| "种子记了但结果还是不一样" | 检查多线程/浮点非确定性,固定线程数与算法版本 |
量化中的用法
Section titled “量化中的用法”- 每次回测自动记录:git commit、种子、数据快照日期(写入 run.log 或结果文件);
- 数据更新只追加快照,不覆盖;
- 研究代码与实盘代码共用信号定义,见研究到生产的一致性。
- 每次回测记录数据快照日期与 git commit
- 用 lock 文件固定依赖
- 随机过程(bootstrap、ML 训练)固定种子并记录