程序员量化交易实战 43:命令响应对象
原创 · 约 11 分钟阅读 · 阅读 --
Last updated on

程序员量化交易实战 43:命令响应对象

作者: Alex Xiang


程序员量化交易实战 43:命令响应对象

古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。这个专栏会把一个 A 股量化平台从 0 到 1 拆开写:数据、策略、回测、模拟盘、提醒和生产化,尽量用真实代码和真实运行结果说话。更完整的更新也会同步到微信公众号「字与码」。

第 41 篇有摘要,第 42 篇有 artifact。接下来要考虑命令行入口。

命令行不应该直接暴露 DailyRunPlan 的所有字段。它需要一个更贴近执行环境的对象:状态是什么,给用户看的消息是什么,artifact 在哪里,进程应该用什么 exit code 退出。

ZiCode 工程师查看每日运行命令响应

命令响应对象

第 43 章新增 app/daily_run_command.py

@dataclass(frozen=True)
class DailyRunCommandResponse:
    status: str
    message: str
    artifact_path: Path
    exit_code: int

这层对象面向 CLI 和调度器,不面向策略逻辑。

字段谁会用
status人和调度系统都要看
message命令行 stdout 或日志
artifact_path排查时打开完整上下文
exit_codeshell、cron、CI 或任务平台判断成功失败

exit code 规则

本章先采用三档:

def daily_run_exit_code(plan: DailyRunPlan) -> int:
    if plan.result.status in {"ready", "dry_run_ready"}:
        return 0
    if plan.action_summary == "warning":
        return 2
    return 1

readydry_run_ready 都是命令成功完成。区别在于是否允许真实执行,这件事由后面的执行闸门判断。

warning 返回 2,是为了和 blocker 区分。这样调度系统可以选择“黄色告警”而不是直接按严重失败处理。

写 artifact 并返回响应

组合函数如下:

def write_daily_run_command_response(
    *,
    plan: DailyRunPlan,
    artifact_dir: Path,
) -> DailyRunCommandResponse:
    artifact = write_daily_run_artifact(plan, directory=artifact_dir)
    return build_daily_run_command_response(plan=plan, artifact=artifact)

命令层只要调用它,就能同时得到:

  • 一行摘要消息。
  • 一个已落盘的 JSON artifact。
  • 一个可用于进程退出的 exit code。

接到可运行示例

本章的命令响应可以通过章节示例命令直接复现:

uv run python -m scripts.chapter_examples paper-command

本章对应的输出如下:

每日运行命令响应输出

这次示例的 status=blocked,所以命令响应给出 exit_code=1。这点很关键:任务平台、cron、CI 或自研调度器通常不读 Python 对象,只看进程退出码和 stdout。命令响应对象把领域状态翻译成了执行环境能理解的结果。

同一行里还带着 artifact=daily-run-2026-03-07.json。这避免了一个常见问题:告警里只写“运行失败”,但没有告诉值班的人去哪里看完整上下文。

message=... executable=false 则保留了第 41 篇的一行摘要。也就是说,命令层不重新拼业务字段,只复用摘要层给出的稳定文本。

测试

本章测试覆盖:

  • ready 和 dry-run-ready 返回 exit code 0。
  • blocker 返回 1。
  • warning 返回 2。
  • command response 能指向真实 artifact 路径。

运行命令:

uv run pytest tests/test_daily_run_command.py tests/test_daily_run_artifacts.py tests/test_daily_run_summary.py tests/test_daily_run_plan.py

本批次补充 paper-command 后,全量测试通过:

276 passed, 2 warnings

本章更新与代码仓库

本章更新内容:

  • 新增 app/daily_run_command.py
  • 新增 DailyRunCommandResponse
  • 实现 daily_run_exit_code()
  • 实现 build_daily_run_command_response()
  • 实现 write_daily_run_command_response()
  • 新增 tests/test_daily_run_command.py,覆盖 exit code 和 artifact 路径。
  • scripts/chapter_examples.py 中接入命令响应输出,覆盖状态、exit code、artifact 和消息。

代码仓库:

https://github.com/ax2/zi-quant-platform

本章代码:

git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-41-45-paper-command
uv sync --extra dev
uv run python -m scripts.chapter_examples paper-command
uv run pytest tests/test_daily_run_command.py tests/test_daily_run_artifacts.py tests/test_daily_run_summary.py tests/test_daily_run_plan.py tests/test_chapter_examples.py

第 41-45 篇共用 tag chapter-41-45-paper-command。当前全量测试通过:276 passed,只有既有 FastAPI deprecation warning。

本篇小结

第 43 篇没有急着写 CLI 参数解析,而是先把命令响应对象补齐。

这个顺序更稳:先让领域层给出明确响应,再把它接到真正的入口。否则命令行代码很容易混进状态判断、文件写入和日志拼接。