程序员量化交易实战 36:收束每日运行请求
程序员量化交易实战 36:收束每日运行请求
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。
第 35 篇把运行时间窗、历史摘要、数据缺口和健康报告合成了运维检查清单。
第 36 篇开始把这些散落的输入收进一个每日运行请求。后面无论是命令行、定时任务还是 API 触发,都应该先构造同一个请求对象。

请求对象要包含什么
每日运行最少需要四类输入。
| 字段 | 作用 |
|---|---|
trade_date | 本次运行对应的交易日 |
generated_at | 请求生成时间,便于追查 |
required_symbols | 本次运行必须具备价格的股票列表 |
dry_run | 是否只演练、不执行真实动作 |
这些字段以前可以散传,但散传会让入口函数越来越难测。请求对象的价值不是复杂,而是把边界固定下来。
实现请求对象
第 36 章新增 app/run_request.py。
@dataclass(frozen=True)
class DailyRunRequest:
trade_date: date
generated_at: datetime
required_symbols: tuple[str, ...]
dry_run: bool = True
默认 dry_run=True 是刻意的。模拟盘进入生产化阶段时,默认行为应该更保守。
构造时做轻量清洗
请求构造函数会去掉空 symbol、去重并裁剪空格。
symbols = tuple(
symbol.strip()
for symbol in dict.fromkeys(required_symbols)
if symbol.strip()
)
这里没有检查股票代码格式。格式校验应该放在更靠近市场数据或股票池的模块里;请求对象只负责把调用方传入的 symbol 列表变成稳定输入。
当前联动运行结果
第 36-40 篇现在可以通过同一条命令运行:
uv run python -m scripts.chapter_examples paper-run-plan
这条命令会构造每日运行请求、生成报告索引、检查运行结果、映射失败动作,并组合每日运行计划。请求对象部分输出如下:

示例里传入了重复的 000001.SZ,最终请求中的 required_symbols 被清洗成 ('000001.SZ', '600519.SH')。这一步看起来小,但它能保证后续价格检查、数据缺口和日志输出都面对同一个稳定输入。
测试请求边界
运行本章测试:
uv run pytest tests/test_run_request.py
核心断言:
assert request.required_symbols == ("000001.SZ", "600000.SH")
assert request.dry_run is False
assert request_symbol_count(request) == 2
另一个测试确认不传 dry_run 时默认是演练模式。
本章更新与代码仓库
本章更新内容:
- 新增
app/run_request.py。 - 实现
DailyRunRequest。 - 实现
build_daily_run_request(),统一清洗必需股票列表。 - 实现
request_symbol_count(),便于后续展示和测试。 - 增加
paper-run-plan联动示例,展示每日运行请求在完整运行计划里的输入形态。 - 新增
tests/test_run_request.py,覆盖去重、裁剪和默认 dry-run。
代码仓库:
https://github.com/ax2/zi-quant-platform
本章代码:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-36
uv sync --extra dev
uv run pytest tests/test_run_request.py
第 36 章提交为 5ec835f,tag 为 chapter-36。
本篇小结
每日运行请求是后续入口层的第一块地基。
第 36 篇把交易日、生成时间、必需股票和 dry-run 标记收进一个对象。下一篇会把运维检查清单转换成运行结果,明确这次请求到底是 ready、dry-run-ready 还是 blocked。