程序员量化交易实战 35:生成运维检查清单
程序员量化交易实战 35:生成运维检查清单
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。
第 31-34 篇分别补了运行时间窗、日报归档、历史摘要和数据缺口计划。
第 35 篇把这些状态合起来,生成一张最小运维检查清单。每日流程真正执行前,先看这张清单,而不是靠人脑记住所有前置条件。

检查清单应该少而准
检查项不是越多越好。
早期模拟盘最需要盯住四件事:
| 检查项 | 输入 | 失败含义 |
|---|---|---|
run_window | RunWindowStatus | 当前不在允许运行时间窗 |
history_ready | RunHistorySummary | 没有可参考的历史归档 |
data_gaps | DataGapPlan | 必需行情价格缺失 |
run_health | RunHealthReport | 最近运行健康状态是 blocker |
这四项不讨论策略收益,只讨论系统今天能不能可信地运行。
清单对象
第 35 章新增 app/ops_checklist.py。
@dataclass(frozen=True)
class OpsChecklistItem:
name: str
passed: bool
detail: str
@dataclass(frozen=True)
class OpsChecklist:
passed: bool
items: tuple[OpsChecklistItem, ...]
detail 不做复杂结构,先保留一个简短字符串。对于日报、命令行和测试断言来说,这已经足够。
组合四类状态
构造函数只做组合,不重新计算业务状态。
items = (
OpsChecklistItem("run_window", window_status.allowed, window_status.reason),
OpsChecklistItem("history_ready", history_summary.report_count > 0, history_summary.latest_status),
OpsChecklistItem("data_gaps", not gap_plan.gaps, gap_plan.severity),
OpsChecklistItem("run_health", health_report.status != "blocker", health_report.status),
)
最后用所有检查项决定总结果:
return OpsChecklist(
passed=all(item.passed for item in items),
items=items,
)
这里故意不做“部分通过”的复杂状态。模拟盘运行前,第一版只需要一个清楚的 go/no-go 结果。
go/no-go 是运维里很常见的叫法。go 表示前置条件足够,可以继续执行;no-go 表示至少有一个关键条件失败,应该暂停、补数据或人工确认。它不回答策略是否优秀,只回答这次运行能不能可信地开始。
当前联动运行结果
第 35 篇收口同一条命令:
uv run python -m scripts.chapter_examples paper-ops-check
命令输出里,时间窗、历史摘要和运行健康都通过,但数据缺口没有通过:

最终 passed=False。这正是检查清单的价值:不是所有模块都成功就放行,而是只要关键前置条件失败,就给出明确的 no-go 结果。
测试通过和失败
测试覆盖两类输入。
健康输入下,清单整体通过,并且检查项顺序稳定:
assert checklist.passed is True
assert [item.name for item in checklist.items] == [
"run_window",
"history_ready",
"data_gaps",
"run_health",
]
失败输入下,测试确认失败项是时间窗、历史和健康报告:
failed = {item.name for item in checklist.items if not item.passed}
assert failed == {"run_window", "history_ready", "run_health"}
运行命令:
uv run pytest tests/test_ops_checklist.py tests/test_run_window.py tests/test_run_history.py tests/test_run_health.py
本章更新与代码仓库
本章更新内容:
- 新增
app/ops_checklist.py。 - 实现
OpsChecklistItem和OpsChecklist。 - 汇总运行时间窗、历史摘要、数据缺口和运行健康状态。
- 输出稳定的 go/no-go 检查结果。
- 增加
paper-ops-check联动示例,展示真实 no-go 检查结果。 - 补充 go/no-go 在每日模拟盘运行前的工程语义。
- 新增
tests/test_ops_checklist.py,覆盖健康输入和失败输入。 - 完成第 31-35 篇阶段 review。
代码仓库:
https://github.com/ax2/zi-quant-platform
本章代码:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-35
uv sync --extra dev
uv run pytest tests/test_ops_checklist.py tests/test_run_window.py tests/test_run_history.py tests/test_run_health.py
第 35 章提交为 fc242ec,tag 为 chapter-35。
第 31-35 篇阶段 review
第七组五篇把模拟盘从“能生成单日报告”推进到“能被日常运维”。
第 31 篇给每日任务加运行时间窗,避免在错误时间运行。
第 32 篇把提醒、健康报告和复盘记录归档成稳定 JSON,让每日运行有证据。
第 33 篇读取归档目录,汇总运行历史、阻断次数和通知成功率。
第 34 篇识别行情数据缺口,把缺失价格变成 blocker 级别的结构化结果。
第 35 篇把前面几类状态合并成运维检查清单,给每日流程一个清楚的 go/no-go 判断。
这一组没有追求更复杂的策略,而是继续加固系统边界。运行时间、历史证据、行情完整性和健康状态都能被检查以后,后面接真实调度或更多数据源时,出问题更容易定位。
当前主线代码也补了一个跨章节命令:
uv run python -m scripts.chapter_examples paper-ops-check
它把第 31-35 篇串成一次可运行演示:先判断运行时间窗,再写入日报归档,随后汇总运行历史,识别价格缺口,最后生成运维检查清单。下一组文章如果接真实每日命令,就可以先调用这张清单决定是否继续执行。
本篇小结
运维检查清单是模拟盘运行前的一道门。
第 35 篇让系统在执行前先回答四个问题:现在能不能跑、历史是否存在、行情是否完整、最近健康状态是否阻断。下一步可以把这张清单接入真实每日命令,把模拟盘流程从函数组合推进到可执行任务。