4. 策略代码打包与版本控制:Git工作流、Python项目打包(setup.py/Poetry)
说实话,很多做量化的人,策略代码写得挺漂亮,但一说到「工程化」就头疼。我见过太多人直接在服务器上改代码,改完也不记版本,出问题了只能靠回忆找回去。嗯,这其实挺危险的。
这一章,我们就聊聊怎么把策略代码管起来。说白了就两件事:版本控制和项目打包。这两件事做好了,你的策略才能从「实验品」变成「产品」。
4.1 为什么需要版本控制?
你想想看,一个策略从想法到实盘,中间要改多少次参数?调多少次逻辑?我自己的经验是,一个策略平均要迭代 20-30 个版本才能稳定上线。如果没有版本控制,你根本不知道哪个版本是「能赚钱的」,哪个版本是「改崩了的」。
Git 就是干这个的。它帮你记录每一次修改,还能让你随时回到任意一个历史状态。更重要的是,多人协作时,Git 能避免「你的代码覆盖了我的代码」这种惨剧。
核心原则:所有策略代码必须进 Git 仓库。哪怕是你一个人写的,也要用 Git 管理。
4.2 Git 工作流:我推荐的分支策略
Git 本身只是个工具,真正重要的是你怎么用它。我见过有人把所有代码都往 master 分支上推,结果一乱就全乱。我个人习惯用 Git Flow 的简化版,适合量化策略开发。
下面这张图是我常用的分支结构:
具体怎么用?我一般这样操作:
- master 分支:只放线上运行的代码。每次合并前必须经过严格测试。
- develop 分支:日常开发的主战场。新功能从这里拉分支,开发完再合并回来。
- feature/* 分支:每个新功能或策略修改,都开一个独立分支。比如
feature/add_momentum_filter。 - release/* 分支:准备上线前,从 develop 拉一个 release 分支,做最后的测试和修复。
我的习惯:每次提交代码前,先跑一遍单元测试。如果测试没过,坚决不提交。这个习惯帮我避免过至少 5 次线上事故。
4.3 Python 项目打包:从 setup.py 到 Poetry
代码写好了,怎么部署到服务器上?总不能每次都手动复制粘贴吧?
Python 项目打包,就是把你的策略代码变成一个「可安装的包」。这样在服务器上一条命令就能装好所有依赖。
4.3.1 传统方式:setup.py
这是 Python 最经典的打包方式。你需要在项目根目录下创建一个 setup.py 文件:
from setuptools import setup, find_packages
setup(
name="quant-strategy",
version="1.0.0",
packages=find_packages(),
install_requires=[
"pandas>=1.3.0",
"numpy>=1.21.0",
"ccxt>=1.80.0",
"redis>=4.0.0",
],
entry_points={
"console_scripts": [
"run_strategy=strategy.main:main",
],
},
)
然后运行 python setup.py install 就能安装。但说实话,这种方式有个坑——它不会自动管理依赖的版本冲突。我曾经因为一个依赖版本不对,在服务器上折腾了整整一个下午。
4.3.2 现代方式:Poetry
后来我改用 Poetry 了。它比 setup.py 好用太多,尤其是依赖管理这块。
先安装 Poetry:
curl -sSL https://install.python-poetry.org | python3 -
然后在项目目录初始化:
poetry init
它会生成一个 pyproject.toml 文件,像这样:
[tool.poetry]
name = "quant-strategy"
version = "1.0.0"
description = "我的量化交易策略"
authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies]
python = "^3.9"
pandas = "^1.3.0"
numpy = "^1.21.0"
ccxt = "^1.80.0"
redis = "^4.0.0"
[tool.poetry.dev-dependencies]
pytest = "^6.2.0"
black = "^21.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Poetry 最大的好处是:它会生成一个 poetry.lock 文件,锁定所有依赖的精确版本。这样你在任何机器上安装,得到的依赖版本都是一模一样的。
注意:一定要把 poetry.lock 提交到 Git 仓库里。这样团队其他人拉下来后,运行 poetry install 就能得到完全一致的环境。
4.4 我的项目结构模板
下面是我常用的量化策略项目结构,你可以直接拿来用:
quant-strategy/
├── strategy/ # 策略代码
│ ├── __init__.py
│ ├── main.py # 入口文件
│ ├── signals.py # 信号生成
│ ├── risk.py # 风控模块
│ └── utils.py # 工具函数
├── tests/ # 测试代码
│ ├── __init__.py
│ ├── test_signals.py
│ └── test_risk.py
├── config/ # 配置文件
│ ├── config.yaml
│ └── secrets.yaml
├── data/ # 数据文件(不提交到 Git)
│ └── .gitkeep
├── logs/ # 日志文件(不提交到 Git)
│ └── .gitkeep
├── pyproject.toml # Poetry 配置
├── poetry.lock # 依赖锁定文件
├── README.md # 项目说明
└── .gitignore # Git 忽略规则
这个结构我用了好几年,基本没出过问题。核心思路是:代码和配置分离,数据和日志不提交。
4.5 避坑指南
最后分享几个我踩过的坑:
- 不要把 API Key 提交到 Git。我见过有人把交易所的密钥直接写在代码里,然后 push 到 GitHub 上。结果第二天账户就被盗了。用环境变量或配置文件管理密钥。
- 不要用
pip freeze > requirements.txt。这个命令会把所有依赖都列出来,包括那些你根本不需要的。用 Poetry 或 Pipenv 管理依赖更靠谱。 - 每次上线前打 Tag。比如
git tag v1.2.0,这样万一线上出问题,可以快速回滚到上一个 Tag。
总结一下:Git 管版本,Poetry 管依赖。这两件事做好了,你的策略代码就能稳定、可复现地运行在任何机器上。别嫌麻烦,这些「工程化」的功夫,迟早会帮你省下大把时间。