Quant Trading for Programmers 18: Paper Trading Needs Risk Checks Too
· 11 min read · Views --
Last updated on

Quant Trading for Programmers 18: Paper Trading Needs Risk Checks Too

Author: Alex Xiang


Quant Trading for Programmers 18: Paper Trading Needs Risk Checks Too

Paper trading does not place real orders, but it still needs risk controls.

The reason is simple: the point of paper trading is not to let a strategy run freely. It is to expose risky account-level behavior before real trading.

A ZiCode engineer checking paper-trading risk rules

First Risk Rules

Article 18 adds app/paper_risk.py and starts with three checks:

  • Whether total exposure is too high.
  • Whether the cash buffer is too low.
  • Whether a single-stock weight exceeds the limit.

Risk control here does not predict drawdowns. It constrains account behavior. Common risk metrics can start from three categories: exposure, concentration, and liquidity. This article implements exposure and concentration first. Liquidity is left for later when volume, turnover, and suspended-status data are connected.

Risk Report

The result is not a boolean. It is PaperRiskReport:

@dataclass(frozen=True)
class PaperRiskReport:
    passed: bool
    severity: str
    violations: tuple[PaperRiskViolation, ...]

severity currently has three values: ok, warning, and blocker. Later notifications can distinguish ordinary hints from risks that should block execution.

Why Keep Violations

Each violation contains code, message, value, limit, severity, and an optional symbol.

That means the risk check does not just say “failed.” It explains which rule failed, what the current value is, and what the limit is.

PaperRiskViolation(
    code="position_too_large",
    message="Single-stock position weight is too high",
    value=0.72,
    limit=0.35,
    severity="blocker",
    symbol="000001.SZ",
)

This structure can later go directly into daily reports, Lark messages, or a risk dashboard.

Current Mainline Integrated Run

The paper-flow example sends the snapshot from article 17 into risk checks:

uv run python -m scripts.chapter_examples paper-flow

Article 18 output:

Real paper-trading risk-check output for article 18

In this sample, the single-stock weight is 80.74%, exceeding the 35% limit, so the risk result is blocker. This does not mean 000001.SZ cannot be bought. It means the paper-trading account is too concentrated. Risk checks focus on account structure, not on an opinion about a single stock.

Chapter Update And Repository

This chapter adds:

  • app/paper_risk.py.
  • Total exposure, cash buffer, and single-stock weight checks.
  • PaperRiskReport and structured violations.
  • tests/test_paper_risk.py, covering passing checks, low cash, single-stock limit breaches, and total exposure breaches.
  • A real current-mainline screenshot for the integrated risk-check example.
  • Context for exposure, concentration, and liquidity as three risk-control categories.

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

Chapter 18 is commit 5b381f3, tagged as chapter-18.

Summary

Risk controls should not appear only right before real trading.

Article 18 connects paper-trading account snapshots to risk checks and outputs readable, testable violation reports. The next article turns target weights into rebalance plans, moving strategy suggestions into the planning layer before execution.