Appearance
Paper Trading Stack (Phase 2g)
The forward-testing stack from Phase 2g: the same strategy code that ran the backtests, running on a paper account — first against replayed historical bars (deterministic, tested), then, with owner-provisioned credentials, against the Databento live feed. This page is the pre-registered record: what runs, since when, the adopt/kill criteria (written before the first fill, protocol 2), where the ledger lives, and how it's monitored.
Everything here is paper. Real capital, sizing beyond 1 contract, and any adoption decision are owner calls that happen after this phase reports (non-goals).
The stack
Declared in live/stack.py as a machine-readable manifest the runner and monitor share. Each stream runs at a fixed grid point — paper never re-fits (protocol 1).
| Stream | Candidate | Symbol(s) | Role | Config | Judge rank |
|---|---|---|---|---|---|
h1_core | pullback_reversion | MES, MNQ | core | N=5, M=3, 1 contract, via feature transport v2 | 1 |
stress_exit_shadow | pullback_stress_exit | MES | shadow (signal-only, virtual P&L) | N=5, M=3 | 1 |
overnight_mnq | overnight_drift | MNQ | sleeve | condition="always" | 2 |
fomc_sleeve | fomc_hourly | MES, MNQ | sleeve | K=1 | 3a |
Not in the stack, by design: the MES overnight_drift leg (fee-destroyed — a non-goal; papering a leg we know fails on costs invites motivated re-litigation); the CPI/NFP candidates (backtests, not paper); and the hourly_momentum third sleeve (queued behind a clean month of the above — an owner call).
The diagnostic-power asymmetry (frame every status report this way)
Paper does not test the four streams equally:
- H1 core — ~13 trades/yr/symbol. A year of paper is statistically non-diagnostic for the edge. What it validates is the plumbing: fills, feature transport, session handling, slippage vs the 1-tick prior. Frame it that way every time.
overnight_mnq— ~250 events/yr. The one sleeve where a 12-month paper record is genuinely informative, and the most exposed to fill-convention risk (16:00 / 10:00 ET closes) — exactly what paper measures well.fomc_sleeve— ~8 events/yr. Paper buys operational readiness and event accumulation, not near-term significance; the parent-hourly backfill settles significance far faster.stress_exit_shadow— diverges from H1 only on stress entries (a minority of ~13 trades/yr) → years to a verdict, but ~zero marginal cost beside H1.
Pre-registered expectations & adopt/kill criteria
Written before the first paper fill. No criterion may be revised after paper starts except by a disclosed, dated amendment (protocol 2).
h1_core (rank 1) — expectations, not an adoption test
Calibrated to the deep-history profile (regime-stress note), not the graduated micro numbers: ~0.6–0.75 Sharpe, a real ~5% drawdown in a sustained downtrend, low-beta conditional long equity. The burn-in is a plumbing validation, not an edge test:
- Consistent-with-backtest = realized slippage ≤ the 1-tick prior; fills at the intended daily-close bar; live signals reproduce the backtest's to the bar (the signal-parity check green); live daily returns inside the backtest CI at the burn-in horizon.
- Kill / triage = realized slippage > 2 ticks sustained; structural fill failures; any signal-parity divergence (a defect, per protocol 4).
stress_exit_shadow (rank 1) — adoption bar
Runs signal-only beside H1 on MES (logged intended entries/exits + virtual P&L). Adoption bar: the live delta vs H1 must be consistent with the backtest's +0.22 (MES 1.06 vs 0.84) before fleet-wide adoption of the VIX-latched exit is even discussed — and never on the strength of MNQ, where it degrades (stress-exit note). Expect years to a verdict; the value is that it rides along at ~zero cost.
overnight_mnq (rank 2) — the phase's real experiment
12-month burn-in (~250 events). It accumulates evidence ~20× faster than H1, so prioritize it once the core is stable.
- Adopt signal = realized slippage within the 2-tick sensitivity band the backtest already survives, and live blend behavior consistent with the 0.86 → 0.99 point-estimate's direction (H1 + this sleeve).
- Kill signal = sustained slippage beyond 2 ticks, or fills structurally missing the 16:00 / 10:00 ET closes (half-day handling is the sharp edge — the session scheduler skips an early-close 16:00 ET entry, mirroring the backtest).
fomc_sleeve (rank 3a) — operational readiness
~8 events/yr, ~7% exposure, fee cost ~0.02%/yr. Framed honestly: paper here buys operational readiness and event-count accumulation, not significance. Track events-observed / events-needed (see monitoring); let the parent-hourly backfill decide significance.
The ledger
Every order, fill, and daily mark appends to an append-only paper ledger (live/ledger.py), mirroring the runs.jsonl discipline. Paper metrics live entirely apart from the frozen candidate-ledger backtest rows — a paper result never edits a backtest record (protocol 3). Each fill records intended_px (the signal-bar reference) vs filled_px (reference plus realized slippage), so slippage vs the 1-tick prior is a first-class, queryable number. In replay, realized slippage is the pre-registered model (1 tick); live, filled_px is the broker's actual fill and the same schema records observed slippage.
Where it persists is an owner decision (a writable paper-ledger store, alongside the live Databento key). The runner is restart-safe: it resumes from the ledger's last mark per stream and only appends rows past it, so a re-run over the same or a longer window never duplicates history.
Monitoring
A daily job over the ledger (live/monitor.py, format_report) surfaces:
- Per-stream attribution — realized P&L, cycle count, realized slippage vs the 1-tick prior (flagged if outside the 2-tick band).
- Signal parity — re-runs the backtest per stream and compares entries/exits to the ledger; any divergence is a defect to triage, not a metric to average.
- Cross-sleeve correlation — each sleeve's daily returns vs H1's, so the diversification thesis is tracked, not assumed.
- Blend tracking — equity/Sharpe of the stacks the judge priced (H1 book → +FOMC → +overnight), so the forward test of the ~0.92 → ~1.14 stack has a running number from day one (
hourly_momentum's rung is tracked here once that sleeve is papered). - Event counters — events observed vs the power target per event sleeve, so "are we there yet" has a number.
The live path (workstream 0)
- Feature transport v2 (0a) — the daily features H1 needs (the 200-day trend gate and the stress-exit's VIX latch) are published as a custom Nautilus
Datatype on the message bus (feature_transport.py), so the same strategy code runs backtest and live. Acceptance (green): a gated backtest through the transport reproduces the date-map results exactly, to the bar (tests/test_feature_transport.py); the date-map path stays the tested fallback (default off). - Live data path (0b) — the Nautilus Databento adapter subscribed to GLBX.MDP3 for MES/MNQ daily + hourly bars, same Panama-adjusted continuous-contract semantics (
<root>.v.0, rolls in data) as the backtests. The consistency cross-check flags divergence between the live continuous stream and the weekly-refreshed research cache on bar-to-bar price changes (offset-invariant for Panama series). Needs owner-provisioned Databento live credentials — see below. - Session scheduling (0c) — fixed ET session times from
pandas_market_calendars(CME_Equity), half-day safe (an early close skips the 16:00 ET overnight entry, matching the backtest). Tested explicitly on the day after Thanksgiving, July 3, and Christmas Eve. - Paper execution + ledger (0d) and ops minimum (0e) — the runner above, plus a staleness guard (refuse to trade on a stale feature frame; exits never blocked) and a heartbeat the monitor can read.
Owner decisions (recommend, don't decide)
- Parent-hourly backfill (WS3b) — done ✅. Quoted at $1.90 total (
uv run python -m vibe_trader.data.cost_quote), approved, and ingested (ES/NQohlcv-1h, 2010→2026). Thefomc_hourlyre-run on the parents (~115 OOS events vs 42 on the micros) moved both bootstrap CIs off zero — ES 0.66 [0.29, 1.02], NQ 0.47 [0.10, 0.89], corr-to-H1 0.04/0.14, PF 2.48/1.99, slippage-robust — settling rank 3: the pre-FOMC drift is a CI-verified, low-correlation edge on deep history (see the ledger). The same backfill also strengthens any future hourly parent candidate. - Live credentials / venue (WS0 blocker). A Databento live key, the paper-account venue choice, and where the paper ledger persists (a writable store — this environment's R2 token may be read-only). Needed to point the tested replay stack at the live feed.
- Third sleeve (
hourly_momentumMNQ, rank 5). Cheap to add once the stack exists; recommended to hold until the two event/session sleeves have a clean month of paper, then the owner decides. - Warm-started test windows / slow commodity trend (rank 6). A protocol change; recommended as Phase 2h's opening review item, not bundled into this engineering phase.