Quant Trading for Programmers 39: Turn Failed Checks Into Actions
Quant Trading for Programmers 39: Turn Failed Checks Into Actions
Article 37 can already keep failed checks in DailyRunResult.failed_checks.
Article 39 continues by turning failures into actions. The system should not only say “failed.” It should also tell the operator whether to wait, repair data, or inspect health reports.

Failure Actions Are Not Automatic Repair
The actions here do not directly repair production issues.
The first version only performs routing: it maps failed checks to remediation suggestions and severity.
| Failed check | Action | Severity |
|---|---|---|
run_window | wait_next_window | info |
history_ready | inspect_archive | warning |
data_gaps | repair_market_data | blocker |
run_health | inspect_run_health | blocker |
| Unknown check | manual_review | warning |
This table is small, but it lets daily reports, CLI output, and later automation speak the same language.
Failure Action Object
Article 39 adds app/failure_policy.py.
@dataclass(frozen=True)
class FailureAction:
check_name: str
action: str
severity: str
check_name keeps the original check. action gives the handling direction. severity determines the summary status.
Mapping Policy
The policy table is written as a constant.
_ACTION_BY_CHECK = {
"run_window": ("wait_next_window", "info"),
"history_ready": ("inspect_archive", "warning"),
"data_gaps": ("repair_market_data", "blocker"),
"run_health": ("inspect_run_health", "blocker"),
}
Unknown checks fall back to manual review.
action, severity = _ACTION_BY_CHECK.get(
check_name,
("manual_review", "warning"),
)
That way, if a new check is added and the policy is not updated yet, the system does not crash.
Action Summary
The summary rule stays simple:
if not actions:
return "no_action_required"
if any(action.severity == "blocker" for action in actions):
return "blocker"
return "warning"
If any blocker exists, the whole failure-action summary is blocker. No actions means nothing needs handling.
Runnable Example
paper-run-plan deliberately makes the price source miss 600519.SH, so the run result has data_gaps as the failed check:
uv run python -m scripts.chapter_examples paper-run-plan

The system maps data_gaps to repair_market_data, with severity blocker. This is more useful than only printing “blocked,” because the operator can immediately tell that the next step is repairing market data, not checking the run window or notification channel.
Test Action Mapping
Run:
uv run pytest tests/test_failure_policy.py tests/test_run_result.py
Key assertions:
assert [(item.check_name, item.action, item.severity) for item in actions] == [
("run_window", "wait_next_window", "info"),
("data_gaps", "repair_market_data", "blocker"),
("run_health", "inspect_run_health", "blocker"),
]
assert failure_action_summary(actions) == "blocker"
Repository
This article adds:
app/failure_policy.py;FailureAction;- mapping from failed checks to remediation actions;
- fallback manual review for unknown checks;
failure_action_summary();paper-run-planlinked example, showingdata_gapsmapped torepair_market_data;- explanation of the difference between blocked status and handling actions;
tests/test_failure_policy.py, covering known checks, unknown checks, and empty actions.
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-39
uv sync --extra dev
uv run pytest tests/test_failure_policy.py tests/test_run_result.py
The article 39 commit is c05f77f, and the tag is chapter-39.
Summary
Failure actions make a blocked state operational.
Article 39 converts failed checks into remediation suggestions and severity. The next article combines request, checklist, run result, and failure actions into a daily run plan, closing this group of work.
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
- Quant Trading for Programmers 43: Command Response Object
- 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 38: Index Daily Report Archives
- Quant Trading for Programmers 37: Generate Daily Run Results
- Quant Trading for Programmers 36: Shape The Daily Run Request
- Quant Trading for Programmers 35: Generate An Operations Checklist