跳转到内容

复现性:版本、种子与环境

一次研究的复现性由四件事共同决定:数据版本、代码版本、随机种子、依赖环境——缺任何一件,半年后就无法重跑出同样的曲线。这也是 存储格式 一节强调"数据不可变"的原因:可复现的前提是数据本身可指认。

  1. 数据版本:不用"最新数据",用快照日期——每次回测记录"截至 2024-06-28 的数据",数据更新不覆盖旧快照(或用 DVC/数据版本工具管理);
  2. 代码版本:git commit 哈希写入回测输出,dirty 状态直接拒跑;
  3. 随机种子:bootstrap、ML 训练、任何带随机性的步骤固定种子并记录;
  4. 依赖环境:lock 文件(uv.lock / poetry.lock / conda env export)固定到补丁版本。
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.md
config.yaml
data_snapshot: "2024-06-28"
seed: 42
signal:
type: "ts_momentum"
lookback: 12
skip: 1
vol_target: 0.10
借口反驳
"数据天天更新,没法固定版本"快照日期就是版本;更新只写新快照
"就我自己用,不用那么正式"复现性不是给别人看的,是给半年后的你
"种子记了但结果还是不一样"检查多线程/浮点非确定性,固定线程数与算法版本
  • 每次回测自动记录:git commit、种子、数据快照日期(写入 run.log 或结果文件);
  • 数据更新只追加快照,不覆盖;
  • 研究代码与实盘代码共用信号定义,见研究到生产的一致性。
  • 每次回测记录数据快照日期与 git commit
  • 用 lock 文件固定依赖
  • 随机过程(bootstrap、ML 训练)固定种子并记录