Files
foxhunt/config/ml/sweep_threshold_tuning.yaml
jgrusewski 9d4fda36ab feat(ml-backtesting): batched-cell sweep schema + 140-variant runner (P6)
Sweep YAML now supports the batched flow per spec §3.3 + Task 6:
- SweepBase.sim_variants: Vec<SimVariant> — list of (cost, latency,
  threshold, ...) variants. When non-empty, each cell runs ONE harness
  at n_parallel=variants.len() with BatchedSimConfig::from_grid instead
  of the legacy one-harness-per-cell fan-out.
- SweepBase.data_template: Option<String> — when set with `{window}`
  placeholder, each cell's `window` field interpolates the per-cell
  data path. Replaces single scalar `data` for the windowed flow.
- SweepCell.window: Option<String> — window identifier (e.g., "2025-Q2").
- SimVariant: threshold + cost_per_lot_per_side required (the spec's
  primary axes); other fields optional overrides on top of SweepBase
  scalars.

New runner pieces:
- BatchedSimConfig::from_grid(&[ResolvedSimVariant]) in
  crates/ml-backtesting/src/sim/batched_config.rs.
- ResolvedSimVariant — per-variant fully-resolved sim params.
- resolve_sim_variants(&SweepBase) in main.rs — layers per-variant
  overrides over base scalars.
- run_batched_cell() in main.rs — builds the harness with
  sim_config_override + variant_names plumbed through. Writes per-
  backtest artifacts to sim_<variant_name>/ subdirs (spec §3.3).

Harness side:
- BacktestHarnessConfig gains variant_names + sim_config_override
  Option fields. When sim_config_override is Some, harness uses that
  directly instead of building from_uniform off scalar cfg. When
  variant_names is Some, write_artifacts uses sim_<name>/ instead of
  cell_NNNN/ subdirs. Both None preserve legacy single-cell behaviour
  (smoke, fixtures unchanged).

YAML configs:
- config/ml/sweep_threshold_tuning.yaml: 1 cell (W0) × 8 sim_variants
  (p60-p95 in 5pt steps) with cost=0.125 (1-tick anchor). Threshold
  pre-registration pass.
- config/ml/sweep_deployability.yaml: 4 cells (W1-W4) × 140 variants
  each (7 costs × 4 latencies × 5 thresholds). Generated by
  scripts/generate_sweep_variants.py — placeholder threshold values
  (p60-p95) until threshold-tuning publishes calibrated absolutes to
  config/ml/v2_prod_thresholds.json.

Deferred to P7 (operational glue):
- argo-lob-sweep.sh adaptation for the batched flow (cells = windows,
  not sim-variants; one Argo task per window invokes `fxt-backtest sweep`
  end-to-end inside the pod rather than `fxt-backtest run`).

Regression: all 7 existing CUDA tests pass through the new harness
construction path (sim_config_override = None → from_uniform fallback).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:41:20 +02:00

38 lines
1.9 KiB
YAML

# P6 batched flow — threshold pre-registration on W0 only.
# Single-cell, 8 sim variants (one per threshold) sharing one forward pass
# on the validation window. Selects the production threshold value by
# maximising in-sample Sharpe; selected value is persisted to
# config/ml/v2_prod_thresholds.json and committed before the deployability
# sweep runs.
base:
# P6 batched flow: data_template + cell.window interpolation produces the per-cell data path.
data_template: /mnt/training-data/futures-baseline-mbp10/ES.FUT/ES.FUT_{window}.dbn.zst
predecoded_dir: /feature-cache/predecoded
n_parallel: 1 # legacy default; overridden by variants.len() per cell
decision_stride: 4
latency_ns: 200000000 # anchor (Scaleway PAR → IBKR realistic RTT)
target_annual_vol_units: 50.0
annualisation_factor: 825.0
max_lots: 5
max_events: 0 # exhaust loader (full quarter)
seed: 12648430
# __SHA__ is replaced by argo-lob-sweep.sh / the operator at submission time
# with the post-trunk-grows training short-SHA (9 chars).
checkpoint: /feature-cache/alpha-perception-runs/__SHA__/trunk_best_h6000.bin
# 8 thresholds spanning p60-p95 (5pt steps). Cost held at the realistic
# anchor (1 tick = 0.125 price units) so threshold-tuning Sharpe reflects
# what the deployability sweep will see at that cost.
sim_variants:
- { name: t60, threshold: 0.60, cost_per_lot_per_side: 0.125 }
- { name: t65, threshold: 0.65, cost_per_lot_per_side: 0.125 }
- { name: t70, threshold: 0.70, cost_per_lot_per_side: 0.125 }
- { name: t75, threshold: 0.75, cost_per_lot_per_side: 0.125 }
- { name: t80, threshold: 0.80, cost_per_lot_per_side: 0.125 }
- { name: t85, threshold: 0.85, cost_per_lot_per_side: 0.125 }
- { name: t90, threshold: 0.90, cost_per_lot_per_side: 0.125 }
- { name: t95, threshold: 0.95, cost_per_lot_per_side: 0.125 }
cells:
- { name: W0, window: 2025-Q1 }