Parameter sweep: axes read from the script, combination cap

The parameter sweep is the "Parameters to sweep" block of the automatic backtest in Replay. Each axis is a parameter key with a comma-separated list of values; the engine expands them as a cartesian product, capped at 400 combinations, and the walk-forward picks the best configuration per slice.

Senzoukria · Documentation · Updated September 2026


Where to find it

Where
Replay → Automatic backtest → "Walk-forward — find the best configuration" → Parameters to sweep
Default axes
lookback 10, 20, 40 · stopTicks 20, 40, 80 · targetTicks 40, 80, 160 (27 combinations) until the script is read
Hard cap
400 combinations (MAX_COMBOS); above it the run is refused, not truncated
Selection criterion
SQN by default; Profit factor, Expectancy per trade or Sharpe per trade

What it does

A sweep turns one strategy into a grid of configurations. Every axis is a parameter key and a list of values typed as "10, 20, 40". The engine builds the cartesian product of all axes on top of the strategy's base parameters (expandSweep), then runs one backtest per combination on the same bars, sequentially, so the interface stays usable while it runs.

Inside the walk-forward, the grid is re-evaluated on the training part of each slice; the configuration with the best score is then tested on the part of the slice that took no part in the choice. The counter under the axes reads "{n} combinations × {folds} slices — about {duration}" so you know the cost before pressing Run.

Axes are proposed from the script itself. A static reader (parametresLus) scans the source for params.get("key", default), params["key"], params.key ?? default and one-line lambda or arrow aliases that wrap params. C++ scripts expose no params in the v1 ABI, so nothing is proposed for them. A key the script never reads shows the warning "This script never reads “{key}”: sweeping it would return identical results."

Settings

Controls of the Parameters to sweep block and the walk-forward row above it
SettingDefaultWhat it changes
Slices4 (input 2–12)Number of consecutive, non-overlapping folds; each fold trains on its start and tests on its end
Training share0.7 (0.5–0.9, step 0.05)Fraction of each slice used to choose the configuration; the rest is the out-of-sample test
Selection criterionSQNScore used to rank combinations: SQN, Profit factor, Expectancy per trade or Sharpe per trade. Gross P&L is deliberately absent
Axis key / valueslookback, stopTicks, targetTicks with three values eachOne row per parameter; empty or non-numeric entries are dropped silently
Add a parameterAdds the next parameter the script reads that no axis uses yet, with proposed values; otherwise an empty row
Explore every readable parameter (n)Replaces the axes with up to five parameters read from the script, values around their defaults
Remove this parameterDeletes the axis row
Minimum trades10 (engine constant)A configuration with fewer trades scores −∞ and can never be selected

How proposed values are built

  • An integer default ≥ 2 is treated as a window or a count: the proposal is half, the default and double (20 → 10, 20, 40).
  • A default in ]0, 1] is treated as a proportion: ±0.1, kept strictly between 0 and 1.
  • Any other number is treated as a factor: ±25 %, rounded to two decimals.
  • qty, color and colour are never proposed: quantity multiplies the result without changing a decision. You can still type them by hand.
  • Three axes are proposed by default, following the order in which the script reads them; the lightning button widens that to five.

Limits or pitfalls

The 400-combination cap is not a performance setting. The panel says it plainly: every extra combination is one more draw in the same data, and past that point you are measuring the luck of an overfit rather than a strategy. Narrow a range or sweep fewer parameters at once.

The reader is static. It cannot see a key built at runtime (params.get("hmm" + suffix)) or a loop over a dictionary; such parameters must be typed manually. Conversely, the axes stop following the script as soon as you edit them; a "re-read the script" action hands control back.

The number of trials passed to the deflated Sharpe is the number of combinations, not combinations × slices; validating cleanly is not counted against you. See the overfitting tests page for how that count feeds PSR, DSR and PBO.

This page in other languages

Frequently asked questions

Why is my sweep returning identical results for every combination?
The swept key is not read by the script. The panel now flags it ("This script never reads …"); replace it with one of the parameters proposed from the source, or add the params.get call to your script.
Can I sweep more than 400 combinations by running twice?
You can, but each run is another set of draws on the same bars, and the deflated Sharpe only knows the trials of the current run. The cap exists to keep the correction honest; prefer fewer axes with wider steps.
Does the sweep run in parallel?
No. The engine runs the combinations one after another and reports progress as it goes, so the panel stays readable while the grid is being worked through. The estimate shown next to the combination count is there to plan the run before starting it.

Keep reading