用 pre-commit 给量化脚本上「提交门禁」:ruff + pytest 的十分钟落地实践

举报
云上复盘笔记 发表于 2026/10/24 00:32:02 2026/10/24
【摘要】 数据流水线能自动跑,不代表代码能放心改。这篇文章记录我给本地量化复盘项目加提交门禁的过程:让每次 git commit 都自动跑一遍静态检查和核心测试。 一、为什么量化脚本特别需要门禁量化项目有个特点:代码量不大,但改动的破坏力不小。改一行指标计算的边界条件,可能让过去两年的回测结果全变,而且不会报任何错——它只会安静地给出一个不同的答案。我踩过的三个坑比较典型:调试代码混进仓库:回测时临时...

数据流水线能自动跑,不代表代码能放心改。这篇文章记录我给本地量化复盘项目加提交门禁的过程:让每次 git commit 都自动跑一遍静态检查和核心测试。

一、为什么量化脚本特别需要门禁

量化项目有个特点:代码量不大,但改动的破坏力不小。改一行指标计算的边界条件,可能让过去两年的回测结果全变,而且不会报任何错——它只会安静地给出一个不同的答案。

我踩过的三个坑比较典型:

  1. 调试代码混进仓库:回测时临时写的 print(df.head())、pd.set_option('display.max_rows', None) 忘记删,日志里全是噪声;
  2. 依赖顺序被破坏:数据清洗函数在指标计算之后调用,本地跑得通只是因为当时缓存了中间文件,换台机器直接崩;
  3. 改坏了没人发现:没有测试覆盖的情况下,一次「顺手优化」可能让某个因子的空值处理逻辑失效,几周后才在实盘数据上暴露。

这几类问题有个共同点:它们都能在提交之前被拦住。所以我把检查放进 Git 的 pre-commit 钩子,而不是等到 CI 报错再回头改。

二、十分钟落地:配置文件

先安装并启用:

pip install pre-commit ruff pytest
pre-commit install          # 写入 .git/hooks/pre-commit

核心是仓库根目录的 .pre-commit-config.yaml:

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.6.9
    hooks:
      - id: ruff
        args: [--fix]          # 自动修可修的问题
      - id: ruff-format        # 统一格式,替代 black

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: trailing-whitespace
      - id: check-added-large-files
        args: [--maxkb=512]    # 别把行情 CSV 提交进来

  - repo: local
    hooks:
      - id: pytest-core
        name: pytest core
        entry: pytest tests/core -q
        language: system
        pass_filenames: false
        stages: [pre-commit]

第一次跑建议全量扫一遍,之后每次提交只检查改动的文件:

pre-commit run --all-files

三、几个值得注意的细节

1. ruff --fix 改完文件不等于通过。 ruff 修完会直接改磁盘上的文件,然后返回非 0 让提交失败,这是故意的——它要你确认自动改动后再重新 git add。刚上手时容易误以为「怎么修了还报错」。

2. 测试钩子用 local + language: system。 这样 pre-commit 不会去建独立虚拟环境,直接复用你当前环境里的 pytest 和项目依赖。代价是换机器要自己保证依赖装好,换来的是执行速度和依赖一致性,本地项目我觉得划算。

3. pass_filenames: false 很关键。 默认 pre-commit 会把改动文件名作为参数传给钩子,pytest 会把它当成测试用例路径去匹配,结果要么报「file not found」,要么干脆一条都没跑。加上这个参数,钩子就只执行 entry 里那条命令。

4. check-added-large-files 对量化项目是刚需。 日线数据、因子快照这类文件动辄几十 MB,一旦提交进去,git clone 会变得极慢,后面清理历史也很麻烦。数据应该走对象存储或者干脆脚本重新生成,不要进仓库。

5. 紧急情况可以跳过,但要留痕。 git commit --no-verify 能绕过钩子,我的原则是只在改文档、改注释这类零风险操作上用,涉及计算逻辑一律不跳。宁可多等三十秒,也不要赌一次「应该没问题」。

四、小结

加了门禁之后最直接的变化不是「代码变漂亮了」,而是改核心逻辑时的心理负担小了很多。提交前自动跑一遍核心测试,相当于给每次改动垫了一层安全网,出问题也能立刻定位到是哪次提交引入的。

整套配置写下来不到十分钟,之后基本零维护,只需要在 rev 里偶尔升级一下版本号。如果你的项目也是「小代码、高风险」的类型——量化脚本、数据处理流水线、运维工具都算——强烈建议试一试。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。