用 Makefile 统一量化项目的命令入口
复盘系统写到第三个月,目录里已经躺着十几个脚本:fetch_minute.py、gen_report.py、backtest.py……每个都要带不同的参数,我自己都要靠翻 shell 历史才能回忆完整命令。后来学量化圈子里工程化程度高的团队,把所有入口统一收进一个 Makefile,敲三个字母就能跑全流程。这篇把我的写法分享出来。
一、最小骨架:目标即命令
Makefile 的核心思想是把「怎么跑」写死在文件里,把「跑什么」留给参数:
.PHONY: fetch report backtest all clean
fetch: ## 拉取当日行情入库
python scripts/fetch_daily.py --date $(D)
report: ## 生成盘后复盘报告
python scripts/gen_report.py --date $(D) --outdir reports/
backtest: ## 跑回测(区间可选)
python scripts/backtest.py --start $(S) --end $(E)
all: fetch report
clean:
rm -rf reports/*.tmp cache/*.pkl
用法就是 make fetch D=2026-11-06、make report D=2026-11-06。变量用 $(D) 引用,命令行 make report D=2026-11-06 传入,不传就走默认值——可以写成 D ?= $(shell date +%F),不传参自动用今天。
二、三个立刻见效的细节
1. .PHONY 别省。 如果你的目录里有个叫 report 的文件夹,不带 .PHONY 的 make report 会报「已是最新」什么都不执行。所有任务目标都声明成伪目标,一劳永逸。
2. 用依赖关系串流程。 报告依赖行情,回测依赖报告,这些顺序关系直接写在 Makefile 里,而不是靠人肉记住先后:
report: fetch
backtest: report
这样 make backtest 会自动先拉数据再生成报告,缺哪步补哪步。
3. 加一个 help 目标当文档。 Makefile 写多了会忘记每个目标干什么,用 grep 自动生成帮助:
help: ## 列出所有可用命令
@grep -E '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-12s\033[0m %s\n", $$1, $$2}'
make help 一敲,所有命令和注释一目了然。这份帮助永远和代码同步,因为它就是从 Makefile 自己提取的。
三、环境变量与敏感信息的边界
Makefile 里放路径、日期、输出目录都安全;但不要把 token、数据库密码写进去。约定从环境变量读:
export PG_DSN ?= $(if $(PG_DSN),$(PG_DSN),postgresql://localhost/quant)
或者干脆在 Python 侧用 os.environ 校验缺失直接报错,Makefile 只负责传通用的非敏感参数。
四、比 shell 脚本好在哪
和写一堆 run_all.sh 比,Make 的增量语义是白送的:配合文件依赖(reports/2026-11-06.html: data/2026-11-06.parquet),数据没更新时重跑 make 会直接跳过,盘后流水线一秒返回而不是重复算十分钟。刚开始别急着把依赖图建全,先从「统一入口」这个最小收益做起,等目标超过十个再回头补文件级依赖,性价比最高。
整个改造一小时搞定,换来的是以后每天盘后只需要一个肌肉记忆命令:make all。
- 点赞
- 收藏
- 关注作者
评论(0)