Quant Trading for Programmers 43: Command Response Object
Quant Trading for Programmers 43: Command Response Object
Article 41 gave the daily run a summary. Article 42 gave it an artifact. The next step is the command-line entry point.
A CLI should not expose every field of DailyRunPlan directly. It needs an object closer to the execution environment: what the status is, what message should be shown to users, where the artifact is, and which exit code the process should use.

Command Response Object
Article 43 adds app/daily_run_command.py.
@dataclass(frozen=True)
class DailyRunCommandResponse:
status: str
message: str
artifact_path: Path
exit_code: int
This layer is for CLI and schedulers, not for strategy logic.
| Field | Who uses it |
|---|---|
status | Humans and schedulers |
message | CLI stdout or logs |
artifact_path | Full context for debugging |
exit_code | shell, cron, CI, or job platform success/failure logic |
Exit-Code Rules
This article starts with three levels:
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
Both ready and dry_run_ready mean the command completed successfully. Whether real execution is allowed is decided later by the execution guard.
warning returns 2 so it can be distinguished from a blocker. A scheduler can treat it as a yellow alert instead of a severe failure.
Write Artifact And Return Response
The composition function is:
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)
The command layer can call this function and receive:
- one summary message;
- one persisted JSON artifact;
- one exit code for process termination.
Runnable Example
The command response can be reproduced with the chapter example:
uv run python -m scripts.chapter_examples paper-command
The output for this article is:

In this sample, status=blocked, so the command response returns exit_code=1. This is important: job platforms, cron, CI, and in-house schedulers usually do not read Python objects. They read process exit codes and stdout. The command response object translates domain status into something the execution environment understands.
The same line includes artifact=daily-run-2026-03-07.json. This avoids a common alerting problem: an alert says “run failed” but does not tell the on-call engineer where to inspect full context.
message=... executable=false reuses the one-line summary from article 41. The command layer does not rebuild business fields; it reuses the stable text produced by the summary layer.
Tests
The tests cover:
readyanddry_run_readyreturn exit code 0;- blocker returns 1;
- warning returns 2;
- command response points to a real artifact path.
Run:
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
After adding paper-command in this batch, the full test suite passed:
276 passed, 2 warnings
Repository
This article adds:
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, covering exit codes and artifact paths;- command-response output in
scripts/chapter_examples.py, covering status, exit code, artifact, and message.
Repository:
https://github.com/ax2/zi-quant-platform
Code for this chapter:
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
Articles 41-45 share the tag chapter-41-45-paper-command. The current full suite passes with 276 passed, with only existing FastAPI deprecation warnings.
Summary
Article 43 does not rush into CLI argument parsing. It first fills in the command response object.
That order is steadier: let the domain layer produce a clear response first, then connect it to the real entry point. Otherwise CLI code easily starts mixing status decisions, file writes, and log formatting.
Follow ZiCode on WeChat
If this post was useful, you can follow later updates on WeChat as well.
X / Twitter
Follow @ax2_zicode
Faster technical notes, short thoughts, and new-post alerts are posted on X.
More in this column
- What Programmers Need to Learn Before Building a Quant Platform
- Quant Trading for Programmers: Column Roadmap
- Quant Trading for Programmers 45: Daily Run Runbook
- Quant Trading for Programmers 44: Execution Guard
- Quant Trading for Programmers 42: Persist Daily Run Artifacts
- Quant Trading for Programmers 41: Summarize The Daily Run Plan
- Quant Trading for Programmers 40: Compose The Daily Run Plan
- Quant Trading for Programmers 39: Turn Failed Checks Into Actions