Quant Trading for Programmers 41: Summarize The Daily Run Plan
· 16 min read · Views --
Last updated on

Quant Trading for Programmers 41: Summarize The Daily Run Plan

Author: Alex Xiang


Quant Trading for Programmers 41: Summarize The Daily Run Plan

Article 40 already introduced DailyRunPlan, which contains the request, result, failure actions, and action summary.

But a plan object is not suitable for direct logging. In production logs, the first thing we usually need is one sentence: can today’s run proceed, which trade date is it for, how many symbols are involved, and how many checks failed?

ZiCode engineer reading a daily-run summary

Summary Object

Article 41 adds app/daily_run_summary.py.

@dataclass(frozen=True)
class DailyRunSummary:
    trade_date: str
    status: str
    dry_run: bool
    symbol_count: int
    failed_check_count: int
    action_summary: str
    executable: bool

It does not replace DailyRunPlan. It extracts the information humans need at first glance.

FieldPurpose
trade_dateConfirm which trading day this run belongs to
statusQuickly distinguish ready, dry-run-ready, or blocked
symbol_countNotice whether the symbol coverage looks abnormal
failed_check_countKnow the failure scale without expanding details
action_summaryJudge whether it is warning, blocker, or no action needed
executableWhether real execution is allowed

Build Summary From Plan

The summary function only reads DailyRunPlan; it does not recompute business rules.

def build_daily_run_summary(plan: DailyRunPlan) -> DailyRunSummary:
    return DailyRunSummary(
        trade_date=plan.result.trade_date,
        status=plan.result.status,
        dry_run=plan.result.dry_run,
        symbol_count=len(plan.request.required_symbols),
        failed_check_count=len(plan.result.failed_checks),
        action_summary=plan.action_summary,
        executable=plan_can_execute(plan),
    )

It reuses plan_can_execute(). If execution criteria change later, the summary layer does not need to duplicate judgment logic.

One Log Line

Logs become hard to scan when structure is scattered. Article 41 adds a stable format:

def format_daily_run_summary(summary: DailyRunSummary) -> str:
    return (
        f"{summary.trade_date} "
        f"status={summary.status} "
        f"symbols={summary.symbol_count} "
        f"failed_checks={summary.failed_check_count} "
        f"actions={summary.action_summary} "
        f"executable={str(summary.executable).lower()}"
    )

A blocked example prints:

2026-02-11 status=blocked symbols=1 failed_checks=1 actions=blocker executable=false

This line can go directly into CLI output, scheduled-job logs, or alert messages. It does not explain every detail. It tells people whether they need to open the artifact next.

Runnable Example

The summary object is connected to the chapter example command. To let articles 41-45 share one real scenario, the sample deliberately constructs a daily run where data_gaps fails: the run window is normal, historical archive is normal, run health is normal, and only market-data checking blocks execution.

Run:

uv run python -m scripts.chapter_examples paper-command

The output for this article is:

Daily-run summary command output

Two parts matter most.

The first is the one-line summary: status=blocked, failed_checks=1, actions=blocker, executable=false. It fits logs and alert titles, letting people know without expanding JSON that today’s run cannot execute for real.

The second is structured fields: dry_run=False, symbol_count=2, failed_check_count=1. These fields can be split later when integrating with a CLI, job platform, or monitoring system instead of parsing strings.

The summary is not an audit record. It is only the “status title” at the entry layer. To debug why a run is blocked, the next article persists the full artifact.

Tests

The tests cover two things:

  • ready plan correctly counts deduplicated symbols;
  • blocked plan outputs a stable one-line summary.

Run:

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

After adding paper-command in this batch, the full suite passed:

276 passed, 2 warnings

Repository

This article adds:

  • app/daily_run_summary.py;
  • DailyRunSummary;
  • build_daily_run_summary();
  • format_daily_run_summary();
  • tests/test_daily_run_summary.py, covering ready and blocked summaries;
  • paper-command in scripts/chapter_examples.py, which reproduces the run chain for articles 41-45.

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_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

Production work is not only about writing core logic. Runtime state must also be easy to understand quickly.

Article 41 compresses the daily-run plan into a summary. The next step is to persist the full context beyond the summary so failures can be replayed with the original request, failed checks, and remediation actions.