Skip to main content
scripts/sweep.py --target signal finds the optimal inference and execution parameters by running many OOS backtests across a parameter grid. No model retraining — it only changes config.json and ml_config.json values that affect signal filtering and risk sizing.
Developer/operator lane only. Regular users should run onboarding, select profile 1-5, pull approved model revisions from R2, and run trading.

Usage

# Sweep confidence threshold + min_probability_diff
python scripts/sweep.py --target signal --mode confidence

# Sweep TP/SL ATR multipliers
python scripts/sweep.py --target signal --mode sltp

# Sweep risk_percent + max_consecutive_losses
python scripts/sweep.py --target signal --mode risk

# All modes combined (~68 configs, ~20 min)
python scripts/sweep.py --target signal --mode full --output results/sweep_$(date +%Y%m%d).csv

# Single-axis custom sweep
python scripts/sweep.py --target signal --mode custom \
  --param dynamic_sltp.tp_atr_multiplier \
  --values 0.7 0.8 0.9 1.0 1.2

Sweep modes

confidence

Tests combinations of confidence_threshold (0.50–0.65) and min_probability_diff (0.05–0.15).
ParameterPath in configSweep range
confidence_thresholdml_config.json → prediction0.50, 0.52, 0.55, 0.58, 0.60, 0.62, 0.65
min_probability_diffml_config.json → prediction0.05, 0.08, 0.10, 0.12, 0.15

sltp

Tests ATR multiplier combinations for SL and TP.
ParameterPath in configSweep range
sl_atr_multiplierconfig.json → dynamic_sltp0.6, 0.7, 0.8, 0.9, 1.0
tp_atr_multiplierconfig.json → dynamic_sltp0.6, 0.7, 0.8, 1.0, 1.2, 1.5

risk

Tests risk sizing and circuit breaker combinations.
ParameterPath in configSweep range
risk_percentconfig.json → dynamic_position_sizing1, 2, 3, 4, 5, 6, 8
max_consecutive_lossesconfig.json3, 4, 5, 6, 8, 10

custom

Sweep any single parameter with explicit values:
python scripts/sweep.py --target signal --mode custom \
  --param ml_config.prediction.confidence_threshold \
  --values 0.55 0.58 0.60 0.62 0.65
The --param flag accepts dot-notation paths into config.json or ml_config.json.

CLI flags

FlagDefaultDescription
--moderequiredconfidence, sltp, risk, full, or custom
--paramDot-notation key for --mode custom
--valuesSpace-separated values for --mode custom
--outputautoCSV file path for results
--balance500Backtest starting balance ($)
--leverage500Backtest leverage
--spread16.95Spread in $ (16.95 = VT Markets, 3.0 = IC Markets)

Reading results

Results are printed as a ranked table and saved to CSV:
Rank  WR      PF     MaxDD   Sharpe  Score   conf   prob_diff
1     78.5%   2.43   1.8%    32.99   21.34   0.60   0.10
2     75.9%   2.19   2.2%    27.46   17.74   0.58   0.10
3     73.8%   2.05   2.5%    24.20   15.18   0.56   0.12
...
Score formula: Score = WR × PF / sqrt(MaxDD)
# View saved CSV
cat results/sweep_signal_*.csv | column -t -s ','

Applying the best result

The script does not automatically apply the best config. Apply manually:
# Edit ml_config.json
python3 -c "
import json
ml = json.load(open('ml_config.json'))
ml['prediction']['confidence_threshold'] = 0.60
ml['prediction']['min_probability_diff'] = 0.10
with open('ml_config.json', 'w') as f: json.dump(ml, f, indent=2)
print('Applied')
"

# Verify with a final OOS backtest
python backtest_config.py \
  --balance 500 --no-swap --leverage 500 \
  --spread 16.95 --oos-only --no-chart
Or use the risk-tuner Claude agent for fully automated sweeping + application.