Quant Trading for Programmers 36: Shape The Daily Run Request
· 12 min read · Views --
Last updated on

Quant Trading for Programmers 36: Shape The Daily Run Request

Author: Alex Xiang


Quant Trading for Programmers 36: Shape The Daily Run Request

Article 35 combined the run window, historical summary, data gaps, and health report into an operations checklist.

Article 36 starts collecting scattered inputs into one daily run request. Later, whether the run is triggered by CLI, scheduled job, or API, it should first construct the same request object.

ZiCode engineer wrapping a daily run request

What The Request Needs

A daily run needs at least four kinds of input.

FieldPurpose
trade_dateThe trading day for this run
generated_atRequest generation time, useful for tracing
required_symbolsSymbols whose prices must exist for this run
dry_runWhether this is rehearsal only, without real actions

These fields could be passed separately, but scattered parameters make entry functions harder to test over time. The value of a request object is not complexity. It fixes the boundary.

Implement The Request Object

Article 36 adds app/run_request.py.

@dataclass(frozen=True)
class DailyRunRequest:
    trade_date: date
    generated_at: datetime
    required_symbols: tuple[str, ...]
    dry_run: bool = True

The default dry_run=True is deliberate. When a paper-trading system moves toward productionization, the default behavior should remain conservative.

Lightweight Cleanup During Construction

The request builder removes empty symbols, deduplicates values, and trims spaces.

symbols = tuple(
    symbol.strip()
    for symbol in dict.fromkeys(required_symbols)
    if symbol.strip()
)

It does not validate stock-code format. Format validation should live closer to the market-data or stock-universe module. The request object only turns the caller’s symbol list into stable input.

Current Linked Output

Articles 36-40 can now be run through the same command:

uv run python -m scripts.chapter_examples paper-run-plan

This command constructs a daily run request, builds a report index, checks the run result, maps failure actions, and composes the daily run plan. The request-object part prints:

Daily run request generated by paper-run-plan

The sample passes duplicate 000001.SZ. The final request cleans required_symbols into ('000001.SZ', '600519.SH'). This looks small, but it ensures later price checks, data-gap checks, and log output all operate on one stable input.

Test The Request Boundary

Run:

uv run pytest tests/test_run_request.py

Core assertions:

assert request.required_symbols == ("000001.SZ", "600000.SH")
assert request.dry_run is False
assert request_symbol_count(request) == 2

Another test confirms that when dry_run is not passed, the default mode is rehearsal.

Repository

This article adds:

  • app/run_request.py;
  • DailyRunRequest;
  • build_daily_run_request(), which normalizes the required-symbol list;
  • request_symbol_count(), useful for display and tests;
  • a linked paper-run-plan example showing the request shape inside the full run plan;
  • tests/test_run_request.py, covering deduplication, trimming, and default dry-run.

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-36
uv sync --extra dev
uv run pytest tests/test_run_request.py

The article 36 commit is 5ec835f, and the tag is chapter-36.

Summary

The daily run request is the first foundation block for the later entry layer.

Article 36 collects trade date, generation time, required symbols, and dry-run flag into one object. The next article turns the operations checklist into a run result, making it clear whether this request is ready, dry-run-ready, or blocked.