量化代码的特殊性在于:三个月后你必须能精确复现某一天的信号——监管问询、客户问询、或仅仅是「为什么当时的仓位和现在不一样」。Git 是这个能力的地基,但量化场景的 Git 用法与软件开发有几个关键差异。
分支策略:研究分支是用来「敢于尝试」的
个人研究者的常见做法是复制 策略_v3_最终版_真最终版.py——三个月后没人知道哪个是活的。正确的最小工作流:
main分支永远保持「可直接实盘」状态:每次合并前必须通过回测复核(见策略上线流程 );- 每个研究假设开一个分支:
factor/reversal-20d、fix/stop-loss-queue——实验失败就删分支,零成本。分支命名的约定本身就值回票价:factor/前缀的分支 = 未验证假设,prod/前缀 = 在跑策略,一眼分清「想法」与「资产」; - 合并(merge/PR)即「上线决策」:合并记录 = 上线记录,回滚 =
git revert。这与灰度放量 衔接:分支可以合并了,资金百分比逐步放大; - 团队协作再加两条:PR 必须有第二人 review(QE 或另一位 QR,重点查前视与成本假设——代码评审在量化里的重心不是风格而是「这行会不会偷看未来」);
main打 tag 对应每个实盘版本(prod-2026-09-15),实盘异常时第一动作是核对生产进程跑的是哪个 tag。
Commit:写给三个月后的自己的研究日志
「fix bug」「update」式的 commit 信息在量化里的成本极高。推荐的格式是**「动机 + 口径 + 结果」**:
| |
这条记录三个月后就是现成的研究笔记 。回测结果写进 commit 的价值:绩效数字会随数据更新漂移,把「当时看到什么」钉死在时间轴上,是诚实研究的一部分——三个月后数据更新导致 IC 变成 0.028,你能精确定位变化发生在哪次数据或代码变更。
.gitignore:量化仓库的第一道安全门
必进 ignore 清单的东西比一般软件项目多:
| |
血泪教训两条:把几十 GB 的行情数据 push 进仓库拖垮所有人(git 对大二进制的历史是永久负担,即使后续删除,历史里还在);把 API key(券商接口、数据商账号)提交进公开仓库——密钥一旦入网即视为泄露,必须作废重置, gods and regulators 都帮不了你(见安全
)。配置管理用模板 + 本地覆盖:config.example.yaml 进仓库,真实配置本地放并 ignore。
Notebook 与实验的版本化
Jupyter Notebook 对 Git 不友好(diff 全是 JSON 噪声),三个实用妥协:
- Notebook 只做探索,成形逻辑落
.py(见研究复现 ),.py严格进 Git; - 确要进仓库的 Notebook,提交前清空输出(
nbstripout工具自动化); - 实验结果(指标表格、净值截图)不进 Git,进实验登记表(一行一个实验:分支名、参数、绩效、结论)——Git 管代码,表格管结果,两者用分支名关联。
数据版本:Git 之外的轻量方案
数据本身不适合 Git(体积大、二进制、更新频繁),但数据版本号必须被 Git 记录:因子计算脚本读取的每张表,在其旁边维护一个 manifest.json(行数、日期范围、生成时间、来源脚本版本);脚本启动时校验 manifest 与预期一致,不一致直接报错拒跑。
| |
这就是因子存储与版本管理 的最小实现——没有它,「同一个策略上周和今天回测结果不一样」将永远无法归因。这句话值得展开:99% 的「回测结果对不上」最终归因于三者之一——数据变了(manifest 能抓)、代码变了(git 能抓)、参数变了(配置 diff 能抓)。三样都版本化,神秘感消失。
关联阅读:代码质量 接管合并前的质量门禁;因子存储与版本管理 是数据层版本化的完整方案;DevOps 与 CI/CD 把本篇的手工流程自动化。