Gate 4

Review & go live

Code never promotes itself to live. It produces the evidence — a divergence analysis of paper versus backtest — and a checklist. A human reads it, signs off, and only then does the strategy trade real capital, at the smallest viable size.

In plain terms

Before risking real money, Cerebro compares the paper results to what the backtest promised. If they diverge in an important way, it flags it. A person must review and approve — the software cannot flip the switch itself.

Technically

gate_review.py loads a paper-session record, runs a backtest baseline, and compute_divergence() compares Sharpe, drawdown, win-rate, slippage, and fill-rate. It writes a git-tracked, unchecked review doc to docs/reviews/. No code path approves live.

The Gate 4 review

Paper meets backtest one last time. Material divergence on any comparable metric is flagged for investigation; the output is a review document with an unchecked six-item checklist and a blank sign-off block for a human.

flowchart TD PS["paper session record<br/>data/sessions/*.json"] --> DIV["compute_divergence<br/>paper vs backtest baseline"] BT["backtest baseline<br/>run_backtest_and_extract"] --> DIV DIV --> MAT{"material divergence?<br/>Sharpe / DD / slippage / fill-rate"} MAT -->|yes| FLAG["flag for investigation"] MAT -->|no| OK["within tolerance"] FLAG --> DOC["generate_review_markdown<br/>docs/reviews/*.md (unchecked)"] OK --> DOC DOC --> HUMAN["human sign-off<br/>6-item GATE4_CHECKLIST"] HUMAN --> LIVE(["Live · minimum size"])
Divergence is judged per metric: Sharpe collapse >50%, drawdown beyond a 20% floor, realized slippage >2× the modeled 3 bps, or fill rate <90%. The document is generated unchecked — a person must tick every box.
Gate 4 checklist (human)
Paper results reviewed by a human
Material divergence from backtest investigated & explained
Position sizing set to minimum viable (1× or fractional)
Emergency flatten command tested
IP-restricted API keys configured
Separate state store from the paper environment

Emergency flatten

At any stage, one command cancels every order and closes every position, on a separate client ID so it can run alongside — or instead of — the main node. It confirms the book is actually flat, or fails loudly.

sequenceDiagram autonumber participant U as Operator participant FS as FlattenStrategy participant O as OMS participant A as IBKR (client_id 2) U->>FS: python -m src.runners.flatten FS->>O: cancel all open orders FS->>O: close all positions (market) O->>A: route cancels + closes loop every 5s until flat or 60s deadline FS->>FS: _check_flat end FS-->>U: confirmed flat (exit 0) or timed_out (non-zero)
The flatten runner validates paper mode, uses client_id = 2, and exits non-zero if it can't confirm a flat book within the 60-second deadline — so an operator (or a script) knows the true outcome.
zsh — review & emergency stop
$ python -m src.runners.gate_review --strategy cross_sectional_momentum --sample
wrote docs/reviews/gate4_review_cross_sectional_momentum_2026-01-01.md
$ python -m src.runners.flatten            # cancel all orders + close all positions
Going live is deliberate and reversible

Live starts at minimum size, with IP-restricted keys and a state store separate from paper. Position sizing, the kill-switch, and the flatten command all carry over unchanged — the safety layer that ran in every backtest is the same one now standing between the strategy and real capital.

References