End-to-end testing loop
Formerly the reproduction backtest format / six-stage pipeline. The same six stages, in this exact order, for every trader — no skipping. A finished run writes a scorecard and hands it to Hermes so the next trader does not start from zero. Dev site only.
Current version: v1.6 (18 Oct 2026) — shared A+ library gate; see v1.6, v1.5 and the gated sequence.
Fully autonomous: one command starts the farm and the loop runs to the end with no human checkpoints. It runs ingest, baseline, forensic, then Level 1 (default instruments: matrix plus in-loop self-learning), then Level 2 (all instrument groups), then locked OOS/HO, then scorecard + Hermes. It stops only on a hard fail. Nothing goes live automatically: a promote result is a candidate for David.
v1.6 · 18 Oct 2026 — Shared A+ setup library (before any A+ ships)
/workspace/nitro-setups/top_traders/_setup_library/ (LIBRARY_RULES.md, VERSION, INDEX.csv, CHANGELOG.md). There is never a private or forked copy. If a second Playbook Builder is added, both use this same library.VERSION and the check is logged in CHANGELOG.md (date, builder, trader, version checked, what changed). Conflicts that cannot be resolved are marked NEEDS-REVIEW for David; never overwrite silently.v1.5 · 18 Oct 2026 — Loop first: nothing runs until this is in place
Stage One: testing instruments and timeframes · power loop
7 instruments × 4 timeframes = 28-combination grid, Hunter 7 sifted by Guardian, in the farm context.
| Instruments | Timeframes |
|---|---|
| ES · YM · MGC · Global Prime gold (XAUUSD) · Silver (XAGUSD) · BTCUSD · GP US30 CFD | 1 · 3 · 5 · 15 minute |
Note: US30 and YM are both the Dow — keep both or drop one is pending David.
Flag — timeframes: the stage-one matrix below lists 1m · 5m · 15m · 1h · daily, but the Stage One grid is 1 · 3 · 5 · 15 minute. David to confirm.
Flag — test periods not locked: lanes use IS 2025 / OOS Jan–Jun 2026 / HO Jul–5 Oct 2026; older doc text said Jan–Apr / May–Jul / Aug–9 Oct; guardian.py splits on 1 Jun 2026; the scheduler spec proposes OOS 1 Apr–5 Oct 2026. David to confirm one split.
- Bias combos: B1–B5.
- Regime tagging: method TBD (pending David).
- Session mix: results split and compared by session.
Core cycle (David, 18 Oct 2026)
Test → Test more → Optimise → Backtest → Review the features summary (what to add, what's missing, how to perfect results) → back to Test. This cycle repeats inside the six-stage flow below.
The testing loop (v1.5 order)
- Data readiness + gap check — the day's data download confirmed complete, quality-checked, known gaps excluded. Incomplete data = no tests start that day.
- Python grid — fast parameter/instrument/timeframe grid, real fees applied.
- Validation on farm data — rerun survivors on the farm's NinjaTrader data.
- Hunter 7 + Guardian hybrid — Hunter 7 entries sifted by Guardian.
- MT5 real-tick tester — straight tester confirmation, real ticks.
- Forward demo — demo only, never live.
Daily top 10 / top 20 per playbook, net of real fees, each with its curve. A new version becomes a candidate only after beating the current one twice; nothing swaps until David says “promote”.
Pre-test protocols checklist
- Real broker fees only, stated on every result: NinjaTrader Lifetime ES/NQ $4.34 RT, MES/MNQ $1.28 RT · IBKR MGC $1.92 RT, GC $5.02 RT · Global Prime XAUUSD $7/lot RT ($3.50/side). No placeholder fees.
- Every stat shown with its equity curve.
- Known data gaps excluded.
- In-sample / out-of-sample split defined before the run.
- Minimum trade floor met (value pending David).
- Both halves (IS and OOS) profitable.
- Overfit checks: random-entry comparison and neighbour-setting stability.
- Every job logged on the Queued Jobs page when it starts and marked when it ends.
- Research only until David says “promote”.
- Back up before any page edit.
- Shared A+ library (v1.6): every A+ definition checked against
/workspace/nitro-setups/top_traders/_setup_library/currentVERSIONbefore publish / entry-contract handoff / preset change / test lane; check logged inCHANGELOG.md. One library for all builders — never a separate copy.
Standing rules (every stage)
/workspace/farm_fees/ (FEES.md · fees.json · fee_rt(root, broker), which refuses unverified roots). Futures default NinjaTrader Lifetime all-in; GC/MGC IBKR; forex Global Prime Raw. The $5 / $25 / $35 placeholders are retired; older runs must be re-costed./workspace/ceo/known_gaps_futures_crypto.json and, for forex, /workspace/data_pull/ticks_secbars_fx/GAPS.md.Data gaps: none found with file + date range).FILLED (not stated by trader): basis = ….net_usd only. A net table without the curve is incomplete.Testing sequence and matrix for Stage One: testing instruments and timeframes (v1.5 · David, 18 Oct 2026)
extract · verify · test first
2a within-trader · 2b cross-trader
7 instruments
| # | Step | What it is | Done when (gate into next step) |
|---|---|---|---|
| 1 | Default playbook | Each trader's own default A+ playbook (Scarface, Jdub, Chad, Garland, Faiz SMC, Market Architect): A+ setup definitions plus the full mechanical spec in the trader-pack format, ready for Roman / ZZ entry contracts. Every A+ check is verified against its source and confirmed coded the same way in Hunter 7 (NinjaTrader preset and Python mirror). Unstated values are marked not stated / OUR DEFAULT. Then each playbook is tested on its own. | Every playbook verified (source cited per rule, NT ↔ Python match) and its own test written with real fees, gaps excluded, an equity curve and the top-20 ranking. Checks needing data we don't hold are listed as skipped, not guessed. |
| 2 | Advanced Hunter 7 | 2a: each trader's own A+ checks stacked 2 and 3 at a time. 2b (after 2a): cross-trader combos, such as Scarface break-retest plus Market Architect or Faiz SMC conditions. Never before step 1 is verified. | Every combo reported: trades, net P&L after real fees, win rate, drawdown, trade count and an equity curve. Combos with fewer than 5 trades are listed as too restrictive. |
| 3 | Stage one on multiple instruments | The verified playbooks and surviving combos run across the stage-one instrument list (step 4) through the full stage-one matrix. | Every listed instrument has been run, or skipped with a logged gap, and the top 20 per timeframe is written. |
| 4 | Stage-one instrument list | The single definitive list for stage one. Every stage-one run is scoped to exactly these instruments and no others. | Recorded on Testing Processes (seven instruments); US30 vs YM pending David. |
Matrix for Stage One: testing instruments and timeframes
This layers on the instrument levels below (Stage 1 = trader defaults, normally NQ + GC · Level 1 = same defaults with matrix + in-loop self-learning · Level 2 = futures → forex → crypto → stocks, missing data skipped and logged). The dimensions are crossed together:
| Dimension | What varies | Rule |
|---|---|---|
| Instruments | The stage-one instrument list | Exactly those seven instruments, no others (see Testing Processes). |
| Sessions | A variety of sessions | The trader's stated session first. Any others are tagged OUR DEFAULT. Each session is reported separately. |
| Timeframes | 1m · 5m · 15m · 1h · daily, where data allows (differs from Stage One grid 1/3/5/15m — David to confirm) | Built from the 1m data. A timeframe without enough data is skipped with a logged reason. |
| Features | Multiple features / A+ checks, individually and in combos | Features needing data we don't hold are skipped and listed (MISSING_DATA_39). |
| Parameters | Multiple parameter values per feature | Declared search space only. Tune on IS only, with OOS / HO locked. |
/workspace/farm_fees/ stated with the result · known gaps excluded · equity curve beside every stat · IS/OOS/HO splits unchanged · no promotion unless David says so.The sequence at a glance
+ 2b forensic
3a Level 1 · 3b Level 2
↺ Stage 6 feeds back: the next trader's Stage 1 starts from the updated A+ candidates and farm memory.
Instrument levels (David lock, 6 Oct 2026)
| Level | When | Instruments | Stages |
|---|---|---|---|
| Stage 1 ingest | Always first | Trader default instruments only: whatever the trader's verified trades / stated market use. Not known → farm default NQ + GC. | 1 |
| Level 1 — default instruments | After the strategy is refined and the forensic pass (2b) shows it does what it is meant to | The same default instruments (normally NQ + GC) | 2 · 2b · 3a · 4 |
| Level 2 — all instrument groups | Once Level 1 is solid | Futures, Forex, Crypto, Stocks, using the farm's selected instruments in each group | 3b · 4 · locked eval |
Level 1 is solid (automatic, no human call) when forensic 2b = PASS, the learner stopped cleanly on a stall guard, and the best config has IS net > 0 and locked OOS net > 0 with ≥ 60 trades across IS+OOS. If it is not solid, Level 2 is skipped with that reason and the run closes DO NOT PROMOTE.
Level 2: the Level-1 locked configs carry over unchanged to every selected symbol, with an optional per-group IS-only re-tune. Level-2 results are cross-instrument robustness evidence and never change the Level-1 promote call.
Instrument coverage, data and costs
| Group | Symbol | 1m data | Tick / $ per pt | Session (ET) | Commission | Rolls / gaps | Status |
|---|---|---|---|---|---|---|---|
| Futures | NQ | ml_models/out/nq_m1_clean_et.parquet (2025-06-30 → 2026-09-14) | 0.25 / $20 | Globex 18:00–17:00; signal 09:35–11:30; flatten 15:55 | $5 RT / contract | Roll weeks dropped (Mar 11–13, Jun 11–12) | Ready |
| Futures | ES | ml_models/r2/out/clean/ES_m1_clean_et.parquet (2025-09-10 → 2026-09-11) | 0.25 / $50 | Same | $5 RT / contract | Roll weeks dropped (Mar 11–16, Jun 8–15) | Ready |
| Futures | GC | smt-python/data/nitro_rotation/GC_m1_clean_et.csv (2025-12-31 → 2026-09-11) | 0.10 / $100 | Globex (COMEX); same NY window | $5 RT / contract | Roll days not yet verified/dropped; < 21-day warm-up before IS | Usable, gap logged |
| Futures | SI · CL · YM · RTY | NT-clock raw only (setuphunter_py/data/*_front_month_m1_ntclock.csv) | 0.005/$5,000 · 0.01/$1,000 · 1/$5 · 0.10/$50 | Globex | $5 RT / contract | Needs clean-ET conversion + roll drop | Skipped until converted |
| Forex | 6E · 6B (futures, proxy, not spot) | NT-clock raw only | 0.00005/$125,000 · 0.0001/$62,500 | Globex | $5 RT / contract | Quarterly roll; needs conversion | Skipped until converted |
| Forex | EURUSD · GBPUSD · USDJPY · AUDUSD | None on box | Pip 0.0001 (JPY 0.01); $10/pip/100k | Sun 17:00 – Fri 17:00 | $5 RT per 100k FILLED | Weekend gap | Missing: skip + gap log |
| Crypto | BTCUSD · ETHUSD · MBT · MET | None on box | Spot 0.01 (coin qty); MBT 5 × 0.1 BTC; MET 0.5 × 0.1 ETH | 24/7 spot; Globex micros; NY window for parity | Spot $5 RT/leg FILLED; micros $5 RT/contract | Micros monthly roll | Missing: skip + gap log |
| Stocks | Nitro ten | smt-python/data/stocks_clean_2026-09-29/{SYM}_1m.csv (2026-03-12 → 2026-09-11) | 0.01 / shares | RTH 09:30–16:00 (RTH-only FILLED) | $5 RT per leg order FILLED; per-share $0.005 (min $1/side) shown as an alternative | No rolls; half-days / halts logged | Ready |
The six stages
- Ingest rules and code (NinjaTrader + Python).
Done when: the trader's locked rules template and entry plugin / preset exist on both sides, for the trader's default instruments only (normally NQ + GC). The other groups are only inventoried for Level 2; their bars are not loaded. A smoke failure is a hard fail.
- Locked rules template, versioned and named for the trader's main setup (e.g. CRT / ORM / iFVG).
- Verified trade list beside the master rules (video ID@timestamp, instrument, date, entry time ET, price, direction; stop/target only if stated).
- Python preset + entry plugin under
smt-python; defaults match the locked template; new switches default OFF. - NinjaTrader: same parameters in the current All-in-One NT file; backup before edit (
.bak_pre_<trader>). - Port map / FILLED tags updated; smoke test — both sides load, the default-off path does not change other traders.
.cspath, Python preset/plugin paths, verified-trades file. - Baseline reproduction (in-range set).
Done when: every in-range verified trade is classified, with a blocking rule on misses. Default instruments only. No verified trades → research mode (figures labelled RESEARCH; promote forced to DO NOT PROMOTE).
- Run code as-is (locked defaults, judgement OFF) on clean data for each trade date (ET, tick-rounded, roll weeks handled). No tuning.
- Match each trade on entry time (within one bar), entry price (stated tick tolerance) and direction.
- Classify:
REPRODUCED·PARTIAL(say which of time/price/dir is off) ·MISS(name the gate) ·DATA_GAP/ untestable. - Report
reproduced / in-range, the full trade table and the data-gap note. - 2b Forensic pass (gate into Level 1, automatic): every lineup component fires on ≥ 1% of IS days; entry = next 1m open; no trade outside the window or after 15:55; SL/TP1/TP2 = stop-ref / 1R / 2R; no fills on roll-drop or missing-bar days; ET clock sanity;
net_usd = gross − $5 RT; day cap respected. If it fails, Level 1 is NOT SOLID, Level 2 is skipped, and the run still finishes.
REPRO_<TRADER>.md,repro_<trader>_trades.csv, baseline run JSONs (signals + closed trades withnet_usd). - Parameter / judgement sweeps + in-loop self-learning.
Done when: try-all and per-switch results are recorded, the self-learning loop stopped on a named stall guard (3a), and Level 2 ran or was skipped with its reason (3b).
- 3a Level 1 (default instruments): round 0 = FILLED trigger matrix (76 lineups, or a named focused set) × default instruments, with static CDX exits (TP1 1R / TP2 2R, 1+1, no BE, no trail, same-bar = stop first, flatten 15:55, $5 RT). Then self-learning rounds use IS only (see Self-learning). Then the top-5 configs get locked OOS + HO once.
- 3b Level 2 (after Level 1 solid): futures → forex → crypto → stocks, farm-selected symbols; Level-1 configs carried unchanged; optional per-group IS re-tune; missing data = logged skip.
- Identify judgement / contradiction switches (default OFF).
- Run try-all ON, then each switch alone to attribute unlocks and regressions.
- Table: switch → unlocked trade IDs → regressions → keep default OFF? yes/no.
- Never promote a switch that raises one trade but regresses a locked reproduce without an explicit David decision. Data-gap note on the sweep report.
*_JUDGEMENT_TRYALL_*.md, per-tag run JSONs, score JSON (repro/partial IDs per tag). - Dollar PnL from run logs.
Done when: dollars are attached to hits, partials and any standalone profitable engine trades — not score alone.
- From each run JSON read closed trades:
opened_at,entry,exit,reason(stop / target / be_stop),net_usd(already net of $5 RT). - Map scorecard signal bars to closed trades (±1–2 min); note signal-only with no closed trade.
- Report whole-run book (count, total
net_usd, winners vs losers), per REPRODUCED and per PARTIAL net USD, and any standalone profitable engine trades. - Never invent PnL for a miss from an unrelated same-day fill.
- Equity curve (mandatory — every result): running equity, max DD from peak, longest losing streak, win clusters, largest trade $ and % of total, top-2 winners' share, date range — labelled smooth vs lumpy. Deliver in the same report as the nets. Baseline, every sweep, matrix cell, OOS/HO, experiment.
- From each run JSON read closed trades:
- Scorecard package (paths ready).
Done when: one folder holds everything Stage 6 will consume.
- Collect baseline repro report + CSV, try-all / per-switch report, PnL extract, data-gap notes, NT/Python commit or Drive paths.
- Confirm in-range count and ID lists (repro / partial / miss / gap) agree across files.
- Name the promote candidate config tag (usually baseline locked defaults; sweeps are diagnostic unless David locks a switch ON).
scorecard_inputs/(or dated lane folder) with a shortMANIFEST.mdlisting paths. - Scorecard + Hermes.
Done when: the scorecard is written with a promote call and Hermes has run on it and its revisions are committed to the A+ setup library and entry-plugin lane.
- 6a Scorecard: trader, date, template version, NT + Python paths; baseline score; sweep unlocks/regressions; dollar PnL; equity curve; data gaps; instrument levels (Level 1 solid? Level 2 groups run/skipped); automatic promote call
PROMOTE_CANDIDATE(a candidate file for David, never live) ·DO NOT PROMOTE, with a one-line reason. “HOLD — needs David” is now a non-blocking open question. - 6b Hermes (inside this stage, never a "stage 7"): reads the scorecard, PnL, per-switch results and rule-match details; returns revised A+ definitions, entry-param suggestions, a do-not-enable list and open questions for David — as concrete artifacts.
- Autonomous form: the loop runs the local Hermes learner, autocommits candidates (
a_plus_gallery/_hermes/<run_id>/,A_PLUS_LIBRARY_candidates/,presets/hermes_candidates/,farm_memory/), and sends the Hermie agent an async copy without waiting. Live presets, the A+ library v1 andgate.yamlare never auto-edited. - Commit accepted A+ updates (
/workspace/nitro-setups/a_plus_gallery/) and entry-param updates before the next trader is ingested. FILLED switches stay default OFF unless David locks one ON. Record the Hermes run id + artifact paths on the scorecard footer.
SCORECARD_<TRADER>_<DATE>.md, Hermes return bundle path, updated A+ defs, updated entry-plugin params, footer link on the trader Dev page (Dev only). - 6a Scorecard: trader, date, template version, NT + Python paths; baseline score; sweep unlocks/regressions; dollar PnL; equity curve; data gaps; instrument levels (Level 1 solid? Level 2 groups run/skipped); automatic promote call
Self-learning loop (in-loop, no manual step)
- Round 0. Every lineup × every ready symbol at locked defaults gives an IS objective per config, pooled across the level's symbols.
- Rounds 1…N. The Hermes-local proposer reads IS results only and proposes new variants: lineup beam (add one component to the top IS lineups, max 5), parameter mutation (window bars/start/end, CISD series/look-ahead, iFVG age, SL buffer, gap and risk-cap scale, trades/day), and a surrogate model that ranks about 10× the candidates and keeps the best 24 per round. Each variant runs and is scored automatically.
- Objective (
FILLED, farm judgement): IS net $ − 0.5 × IS max DD; ≥ 30 IS trades; bonus if both IS halves are positive. Exits stay fixed at the CDX standard. - Locked evaluation. The top-5 configs get OOS and HO once. The KEEP gate mirrors
hermie_loop/gate.yaml: IS beats base; OOS and HO net > 0; avg trade ≥ base − 10%; ≥ 100 trades; ≥ 90 days; max DD ≤ 1.2 × base. Locked numbers never reach the proposer. - Permanent memory. Every trial key and IS score goes to
farm_memory/trials.jsonl, so later runs never repeat a config and warm-start from the best priors.
Stall guards: what stops it from stalling
| Guard | Default |
|---|---|
| Max rounds | 8 |
| Max trials (books) | 2,000 |
| No-improvement patience | 2 rounds without ≥ 2% gain in best IS objective |
| Wall-clock budget | 8 h per level |
| Per-book timeout | 600 s → TIMEOUT, not retried |
| Duplicate-config detection | sha1(trader, symbol, lineup, params, exits, data fingerprint) checked against this run + farm memory; 200 duplicates in a row = proposer exhausted → stop |
| Promote / do-not-promote stop | Every run ends with a written call, never “waiting” |
Thorough result set complete = round-0 matrix on every ready Level-1 symbol × every lineup; learner stopped on a named guard; top-K locked-evaluated once; every book has trades + equity curve + summary; Level 2 run for every ready selected symbol (or skipped with reason); every skipped symbol listed with its gap; ranked report, scorecard, Hermes input/return and manifest written.
How the stages chain (autonomous loop)
# end-to-end testing loop — one command, no human checkpoints
run_e2e_loop.py --config config.json --execute
for trader in build_order:
Stage1 ingest # trader DEFAULT instruments only (normally NQ + GC)
Stage2 baseline repro # default instruments; research mode if no verified trades
Stage2b forensic # automatic; PASS gates Level 1
LEVEL 1:
Stage3a matrix round 0 -> self-learning rounds (IS only) -> stall-guard stop
Stage4 PnL + equity curve every book
locked OOS + HO once for top-K -> KEEP / REJECT
if Level1 solid:
LEVEL 2: Stage3b futures -> forex -> crypto -> stocks (farm-selected; gaps skipped + logged)
Stage5 package
Stage6 scorecard (auto promote call) + Hermes (local learner, candidate autocommit, async Hermie copy)
# next trader Stage1 starts from updated A+ candidates + farm_memory priors
Stops only on a hard fail:
Proceedings — what gets written at each stage
| Stage | Outputs on disk |
|---|---|
| 1 · Ingest | Locked template path · NT .cs path · Python preset/plugin paths · verified-trades file |
| 2 · Baseline | REPRO_<TRADER>.md · repro_<trader>_trades.csv · baseline run JSONs |
| 2b · Forensic | stage2b_forensic/forensic.json (PASS / FAIL + failures) |
| 3 · Sweeps + self-learning | *_JUDGEMENT_TRYALL_*.md · per-tag run JSONs · score JSON · stage3_level1/ + stage3_level2_<group>/ books · ledger.jsonl · RANKED_REPORT.md · farm_memory/trials.jsonl |
| 4 · Dollar PnL | PnL extract (md/CSV) · equity-curve table/JSON · run JSON paths |
| 5 · Package | scorecard_inputs/ + MANIFEST.md |
| 6 · Scorecard + Hermes | SCORECARD_<TRADER>_<DATE>.md · Hermes return bundle · updated A+ defs · updated entry params · Dev page footer link |