Skip to content

Genome Selection Reference

Version: 1.0.0 — 2026-09-27 Source of truth for: how a genome is evaluated, filtered, scored, and promoted to Champion status. Verified against: backtest.py v3.30.0 · engine/scoring.py SCORE_VERSION 2.2.0 · champion_vault.py v1.4.0


1. What Is a Genome?

A genome is a fixed parameter set that defines a complete trading strategy configuration — entry/exit logic, session windows, risk limits, and indicator thresholds. The GA (Genetic Algorithm) evolves genomes over multiple generations to find optimal configurations for a given instrument, dataset, and target objective.

Each genome is uniquely identified by a UID (hash of its active parameter values via _uid_signature_keys_for()). Duplicate UIDs across runs are collapsed to their highest-generation, highest-score representative during pool pruning.


2. Fitness Targets (Training Objective)

The GA evolves genomes to maximise a fitness score computed at the end of the training window. The target determines what the GA optimises for. Each run is assigned exactly one target.

Target Objective Formula Summary
LOW_RISK Minimise drawdown while staying profitable (net / max(dd, 50)) × 1000 × exp(−dd / 722) — continuous exponential penalty; 50% reduction at dd = 500 ticks
EFFICIENCY Calmar ratio with ceiling (net / dd) × 1000; exponential decay beyond DD_CEIL ticks
STEADY_GAIN / SMOOTHNESS Equity curve consistency K-Ratio^1.5 × net^0.5 × EV^0.5 (ev_tilt default)
HIGH_PROFIT / TOTAL_YIELD Maximum profitable velocity (K × net/sess / eff_dd) × 1000 with ATR-scaled DD brake
CONSISTENCY EV per trade, Calmar-weighted (net/trades) × (net/dd)
DAILY_YIELD Mean daily PnL × day-win-rate quality mean_daily × (day_wr)² × daily_ratio
DAILY_SHARPE_FULL / DAILY_SHARPE_OOS Risk-adjusted daily return (μ²/σ) × min(1, √(n/252)) — length-normalised
ROBUSTNESS Equity smoothness (1−Gini)^1.5 × net^0.5 × EV^0.5
ACCURACY Win rate × scaled net WR × (net/1000)
STABILITY Net net-of-2×DD net − (dd × 2)

All targets share a mandatory minimum-trade floor (max(2, dataset_bars/2000)) and a negative-net hard floor (net ≤ 0 always scores below zero, regardless of target).

Fitness Versioning

FITNESS_VERSION is stamped on every GA row in Sel_Config as fv=<N>. Current: fv=3 (v3.30.0 continuous LOW_RISK decay).


3. Train / OOS Split

Each GA run divides the dataset into a training window and an out-of-sample (OOS) window:

Window Purpose
Train The GA optimises fitness on this window. Genes mutate, cross over, and selection pressure acts here.
OOS Held out during training. Evaluated at the end of each generation to measure genuine generalisation.
Anchor A recent forward-holdout period computed after the run finishes. Independent of the Train/OOS split. Measures current-regime performance.
Lifetime Full dataset, no split. Measures total historical performance across all regimes.

The OOS retention ratio (c_ret) = OOS_Net/Sess ÷ Train_Net/Sess. A ratio ≥ 1.0 means the genome performs at least as well out-of-sample as in-sample — genuine edge, not in-sample overfitting.


4. Champion Qualification Filters

A genome must pass all of the following to be called a Champion. This is the minimum bar for deployment consideration.

Is_Champion = 1   iff   train > 0  AND  oos > 0  AND  anchor > 0
Condition What it proves
train > 0 Profitable in the training window (Net Ticks > 0)
oos > 0 Profitable in the held-out OOS window (OOS_Net/Sess > 0)
anchor > 0 Profitable in the recent anchor holdout (Anchor_Net > 0) — current regime viability

Champion Tiers

Label Is_Champion World_Champion Additional condition
🌍🏆 World Champion 1 1 Also lifetime > 0 — profitable across entire multi-year history
🏆 Champion 1 0 Anchor + OOS + train positive; lifetime may be negative/neutral (regime specialist)
🔴 Disqualified 0 0 Fails at least one of train/oos/anchor conditions

Rules that must never be violated: - World Champion is always a strict subset of Champion. World_Champion count ≤ Is_Champion count. - Negative lifetime does NOT disqualify a Champion — it simply means the genome hasn't been world-champion-grade across all historical regimes. It is still deployable. - 🏆 Champions Only button shows ALL Is_Champion = 1 (both tiers combined). - 🌍 World Champions Only button shows only World_Champion = 1.

Legacy Runs (no Anchor_Net column)

Runs without an anchor holdout use OOS as the proxy: oos > 0 AND train > 0 = Champion. Same logic: additionally lifetime > 0 = World Champion.


5. Score v2.2.0 — Ranking Within Champions

Once a genome qualifies as a Champion, it is ranked by Score_v21 — a composite of two independent axes:

Score_v21 = √(Opp_v21 × Risk_v21)

Opportunity Axis (Opp_v21)

Equal-weight mean of 6 components — measures edge quality and out-of-sample reliability:

Component Measures
c_ret OOS/Train nps retention ratio — genuine out-of-sample edge
c_tstat EV/trade × √N — statistical significance of edge
c_risk nps / |MaxDD| × 10 — reward-to-pain ratio
c_hh_w Weekday Herfindahl diversity — profits distributed across days (not day-specific)
c_fitpct Within-file fitness percentile — relative rank among same-run peers
c_wrz Win-rate binomial significance — WR above chance

Risk Axis (Risk_v21)

Single component — measures drawdown acceptability:

Component Measures
c_ddinv 100 − sat(dd, 8000) — inverse MaxDD; higher = smaller drawdown

Why the axes are separate: Opportunity and Risk measure orthogonal properties. A genome can have high opportunity (great edge) but high risk (large drawdown), or low opportunity (weaker edge) but very tight risk. The geometric mean √(Opp × Risk) rewards balance — neither axis can dominate by itself.

Why c_ddinv is NOT in Opp (v2.2.0 fix): Before v2.2.0, c_ddinv appeared in BOTH Opp and Risk, double-penalising drawdown. The fix replaces it in Opp with c_ret (OOS retention), making Opp a genuine forward-edge measure.

Score Components Not in Ranking

c_pace, c_line, c_r2, c_trades, c_wr, c_posd, c_gini, c_hh_s, c_cons — computed but not part of the frozen equal-weight set. Available for diagnostic inspection.


6. Robustness Probing

After scoring, the top-3 distinct genomes per criterion are subjected to robustness probing — a parameter sensitivity sweep:

  1. Each active parameter is perturbed ±N steps (default N=3) from its best value.
  2. All variants are evaluated in one parallel ProcessPoolExecutor pass.
  3. A parameter is on the plateau if fitness(variant) ≥ 0.85 × peak_fitness across the perturbation range. Plateau = the genome is not knife-edged on that parameter.
  4. The robustness score (rob_score) = number of parameters on the plateau.

Vault Seed Selection (4-Tier Ladder)

When seeding the next GA generation from the champion pool (champion_vault.py), candidates are filtered by robustness in priority order:

Tier Filter Meaning
1 rob_score > 30 AND Conf_Pct > 0 Strongly robust and confident
2 rob_score > 0 AND Conf_Pct > 0 Any robustness + positive confidence
3 Conf_Pct > 0 Confidence only (no robustness data)
4 Unfiltered (df_lb) Last resort — prevents vault starvation

Output Files

  • Rank 1 (primary): _ROBUSTNESS_<Criterion>.json (backwards-compatible)
  • Ranks 2–3 (sidecars): _ROBUSTNESS_<Criterion>_rank2.json, _rank3.json
  • The overview table in the dashboard always shows rank 1 only.

7. Genome Identity & Deduplication

UID Computation

genome_uid = SHA-256 hash of the genome's active parameter values in canonical key order. "Active" means parameters not silenced by dead-gene logic (gene_activity.py). Inactive parameters are excluded from the hash so that two genomes with different dead-gene values but identical active genes produce the same UID.

Pool Pruning

When multiple CSV files contain the same UID, the representative is selected by: 1. New-run preference: rows from files that are NOT suffixed _rank2/_rank3 preferred. 2. Highest generation (most evolved). 3. Highest Score_v21.

_poolarchive CSVs are excluded from the dashboard scan entirely.


8. Decision-Matrix Criteria (Console Output)

The post-evolve console prints a decision matrix with 4 recommended genomes. Each uses ROBUSTNESS_PASS_THRESHOLD = 0.85 as the pass/fail gate:

Label Selection basis
[FOCUS MODEL] Highest fitness in training
[MAX PROFIT] Maximum Net Ticks
[MOST STABLE] Best robustness score
[BEST RISK-ADJUSTED] Best Score_v21

9. Glossary

Term Definition
Anchor A recent forward-holdout period (independent of the Train/OOS split). Measures whether the genome works in the current market regime. Anchor_Net > 0 is the primary Champion qualification gate.
Calmar Ratio net / max_drawdown — profit per unit of maximum adverse excursion.
Champion A genome with train > 0, oos > 0, and anchor > 0. Minimum bar for deployment.
World Champion A Champion that also has lifetime > 0 — profitable across the entire historical dataset.
c_ddinv Score component: 100 − sat(dd, 8000). Inverse MaxDD — higher score for smaller drawdown. Lives exclusively on the Risk axis in v2.2.0.
c_ret Score component: sat((oos_nps / train_nps) × 60, 60). OOS/Train retention ratio — measures out-of-sample faithfulness to training performance. Lives on the Opp axis in v2.2.0.
c_risk Score component: sat(nps / dd × 10, 60). Reward-to-pain ratio using session-net and MaxDD.
DD_DECAY_SCALE 722.0 ticks = 500 / ln(2). The exponential decay constant for LOW_RISK fitness; at dd = 500 ticks the fitness factor is exactly 0.5 (50% penalty).
dd_eff max(dd, 50.0) — the effective drawdown used in LOW_RISK fitness. Floor of 50 prevents the score from exploding when drawdown is near zero.
Disqualified A genome that fails any of the Champion conditions. Not deployable; remains visible in the Explorer for research.
EV/Trade Expected Value per trade = net / trades.
FITNESS_VERSION Integer version of the fitness formula layer. Current: 3 (v3.30.0 LOW_RISK decay). Stamped in Sel_Config as fv=3. Never read back by math — audit/lineage only.
Genome A fixed parameter set defining one complete strategy configuration. Identified by genome_uid.
Genome UID SHA-256 hash of the genome's active parameter values. Two genomes with identical active genes (dead genes excluded) produce the same UID.
Gini Profit concentration coefficient. Gini = 0 = all trades contribute equally; Gini = 1 = one trade dominates. 1 − Gini (smoothness) is used in scoring.
Is_Champion Binary column: 1 if train > 0 AND oos > 0 AND anchor > 0, else 0. Covers both Champion and World Champion tiers.
K-Ratio Lars Kestner's equity curve quality measure: slope / standard error of the regression line through the equity curve. Higher = more statistically reliable growth. Formula: sqrt(252) × slope / (stderr × √n).
Lifetime Full-dataset net performance (no train/OOS split). Used to distinguish World Champions (lifetime > 0) from regime specialists (lifetime ≤ 0).
OOS Out-of-Sample window — the held-out portion of the dataset not seen during GA training.
OOS Retention OOS_Net/Sess ÷ Train_Net/Sess. Ratio ≥ 1.0 = as good or better OOS than in-sample. Stored as OOS_Retention column.
Opp_v21 Opportunity axis of Score_v21. Equal-weight mean of 6 components measuring edge quality and OOS reliability.
Plateau A parameter is "on the plateau" when perturbing it ±N steps keeps fitness ≥ 85% of peak. Wide plateau = the strategy is not knife-edged on that parameter.
Risk_v21 Risk axis of Score_v21. Single component: c_ddinv (inverse MaxDD).
rob_score Count of parameters on the robustness plateau. Higher = more robust strategy.
ROBUSTNESS_PASS_THRESHOLD 0.85 — the fitness retention fraction required for a perturbation to count as "on the plateau". Applied in backtest.py (4 console sites) and run_robustness.py.
SCORE_VERSION Semantic version of the scoring formula. Current: 2.2.0 (c_ret in Opp). Any component-set change requires bumping to 2.3.0 + new calibration study.
Score_v21 √(Opp_v21 × Risk_v21) — the primary genome ranking metric. Geometric mean rewards balance between opportunity and risk.
Sel_Config Provenance stamp on each GA row: encodes the engine version, fitness version, and session protocol used to generate that row.
Train Training window — the portion of the dataset used by the GA for fitness evaluation and evolution.
UID See Genome UID.
Vault champion_vault.py — the registry of historical champions used to seed new GA runs. Seeds = exact champion genomes + ±1 step mutants injected into Generation 1.
World_Champion Binary column: 1 if genome is a Champion AND lifetime > 0, else 0. Always ≤ Is_Champion.