Backtesting & verification intermediate 12 min read

MT5 Parameter Optimisation: 116 Combinations, 252 Runs, 0 Settings We Shipped

We ran parameter searches on eight of our own strategy templates and adopted none of them. The useful part is how each one failed: the biggest in-sample winner fell the furthest, one design passed a single out-of-sample check and still collapsed, and two never beat 1.0 even on the period they were fitted to. Here is the procedure, and the reading that stops you shipping the top row.

Published · Reviewed

Parameter optimisation in MetaTrader 5 is a search: you declare a range for each input, the Strategy Tester runs every combination, and it hands you a table sorted by whichever metric you chose. The hard part is not running it. The hard part is that the table always has a top row, and the top row is almost always wrong.

What you get out of this article is a procedure that produces a decision rather than a number: a search you can defend, a reading of the pass grid that survives contact with a second period, and a stopping rule.

Test conditions
Experiment IDEXP-PARAM-SEARCH-OUTCOMES-001
Parent experimentEXP-BUILDER-TEMPLATE-BASELINE-001
Sourceea-templates-manifest.jsbt.explored
Population8 recorded searches of the 53 measured templates
Symbol / timeframeUSDJPYm, M5 and H1
ModelM1 OHLC (Model=1), Exness MT5, measured 2026-06-18
Parameters variedstop loss and take profit only
Last verified2026-08-25

Setup: the grid, the split and the data

Three settings decide whether the search is worth running at all. Get them wrong and the pass grid is a very expensive random number generator.

FieldWhereWhat to setWhy
OptimisationSettings tabSlow complete algorithm for a small gridThe genetic mode samples the space; for 12–32 combinations you can afford to see all of it
Start / Step / StopInputs tab, per inputTwo parameters, coarse stepsEvery input you tick multiplies the grid. Ours moved two
ForwardSettings tab1/2, 1/3 or 1/4Splits the interval so the tester scores the back half separately — this is the check you are running the search for
Optimisation criterionSettings tabDecide it before you look at the gridIt is the metric the tester ranks passes by, so it decides which row is the top row
ModellingSettings tabA coarse mode to scan, then re-run the survivor on real ticksScanning modes are for ranking candidates, never for a published figure
PeriodSettings tabLong enough to contain more than one regimeA search inside one trend finds the setting that rode it

The criterion deserves a decision rather than a default. Ranking by net profit rewards whichever pass took the most risk, and ranking by a drawdown-based measure rewards whichever one traded least — the recovery factor exists because those two answers disagree. Our own searches were not judged by the tester’s ranking at all: each survivor was scored on profit factor across three separate windows, and the ranking inside any one of them never decided anything.

Data quality comes first: a search over bad ticks optimises the gaps. The short version is that modelling quality below 90% makes intraday pass grids unusable, and that a run built from interpolated tick data cannot resolve a stop that sits inside a bar.

  1. Run a single backtest first, at the defaults, and keep the report. Without a baseline the pass grid has nothing to beat — run a backtest covers that pass end to end.
  2. On the Settings tab set Optimisation to a complete pass for a small grid, and set Forward to 1/3 so the tester holds back the last third of the interval.
  3. On the Inputs tab tick only the parameters you are actually testing, and give each a Start, Step and Stop. Two inputs with coarse steps beats four with fine ones.
  4. Press Start and let it finish. Read the Optimisation Results tab as a table, and the Optimisation Graph as a shape — a single spike is a warning, a plateau is a finding.
  5. Take the survivors — not the winner — and re-run each one as a single backtest on a period before the optimisation window. This is the step that produced every negative verdict in our set, and it is the one people skip.

Reading the results: three periods, not one

Here is the whole of our recorded set, sorted by the best in-sample profit factor each search reached. IS is the period the setting was fitted on, OOS the hold-out, and prior an earlier window that the search never saw.

TemplateGrid searchedBest ISOOSPriorVerdict
ichimoku12 combos × 3 windows1.370.890.80no_robust_edge
ma_crossover20 + 12 combos, two timeframes1.230.89–0.940.78no_robust_edge
cci_level12 combos × 3 windows1.071.050.92no_robust_edge
adx_trend12 combos × 3 windows1.040.910.80no_robust_edge
breakout12 combos × 3 windows1.040.79–0.890.64–0.84no_robust_edge
macd_signal12 combos × 3 windows1.14–1.150.74–0.77no_robust_edge
rsi_reversal12 combos × 3 windows0.91no_robust_edge
bb_bounce12 combos × 3 windows0.91no_robust_edge

Read down the first numeric column, then across. The largest in-sample result in the set produced the largest collapse: ichimoku’s 1.37 fell to 0.89 and then 0.80. That ordering is not a coincidence — the setting that fits a window best is by construction the one that has absorbed the most of that window’s noise.

Now read the setting that actually came closest. It is not in the table above, because it was never the top row of anything: on the same ichimoku grid, SL50/TP150 scored 1.18 in sample, 0.99 out of sample and 1.00 on the prior window. Three periods, all roughly flat. It was recorded as the closest candidate and still not adopted, because breakeven across three windows is not an edge — it is the absence of one, measured carefully.

Against that, the baselines these searches were trying to beat sit between 0.92 and 1.03. Not one search moved a shipped default.

Pitfalls to avoid

The failure mode underneath all five is the same one. Overfitting is not a mistake you make at the end of a search — it is the default outcome of running one, and the three-period discipline exists to make it visible before you act on it.

Improve and iterate: what to change, and when to stop

Change one thing, re-run, compare against the baseline you kept. The order that wastes least time:

  1. Widen the period before you widen the grid. More regimes beats more combinations. A search that covers one trend will find the setting that rode it, whatever the resolution.
  2. Then coarsen the steps, not fine-tune them. If a result only exists at SL47, it does not exist.
  3. Then, and only then, add a parameter. Ours never got this far, because two parameters already failed the three-period bar.

Stop when one of these is true, and write down which:

  • A survivor clears all three periods. Ship it, and record the whole grid you searched — not just the pass you kept.
  • The best in-sample result is below 1.0. You have a real answer: two of our eight searches ended here, and ending here after 36 evaluations is cheap.
  • Survivors keep passing one window and failing another. The rule is regime-dependent. More searching produces more regime-dependent settings.
  • You have started explaining why the prior window “does not count”. That is the moment the search stopped being a test.

The honest record of a search is the range you covered and the verdict, together. Every one of our eight is stored that way, which is why this article could be written from them at all — a stored winner alone would have proved nothing.

Next steps: forward test, then decide

Optimisation is the second step of four. The sequence is backtest → optimise → walk-forward → demo, and each one removes a different way of being wrong.

  • Practise the loop on something you control: build a strategy in the Builder and search its stop and target yourself, because a grid you declared is far easier to read honestly than one you inherited.
  • The formal version of the three-period check is walk-forward analysis, which rolls the split forward instead of fixing it in one place.
  • Whatever the search hands back, the report it hands it back in still has to be read: reading an MT5 backtest report covers which population each headline figure is actually a claim about.
  • To see what a finished record looks like when the numbers did survive, the published EAs each carry their complete closed-trade list and run manifest.
  • How we test, score and record all of this is set out in our testing methodology.

Frequently asked questions

How many parameters should I optimise at once?
Fewer than the tester will let you. Every search in our own recorded set moved exactly two — the stop loss and the take profit — across 12 to 32 combinations, and not one of the eight produced a setting we were willing to ship. Adding a third and fourth parameter does not fix that; it multiplies the grid and makes it far easier to find a combination that fits the noise in your test window. If two parameters cannot produce a result that survives three periods, the problem is the rule, not the resolution of the search.
What profit factor should I look for in an optimisation pass?
Look at three numbers, not one. In our set the best in-sample profit factor reached 1.37 on the ichimoku template — and the same setting scored 0.89 out of sample and 0.80 on the earlier window. The setting that came closest to being usable was much less impressive in-sample: 1.18, holding 0.99 and 1.00 across the other two periods. It was still not adopted, because breakeven on two of three windows is not an edge. A high in-sample number is the least informative figure on the screen.
Is one out-of-sample test enough to validate an optimised setting?
No, and we have a case that shows why. The macd_signal template produced a setting that reached 1.14 to 1.15 out of sample — a clean pass on a single hold-out — and then scored 0.74 to 0.77 on the window before the test period. A second design, cci_level, went further: 1.07 in sample, 1.05 out of sample, and 0.92 on the prior window. Two periods were not enough either. Both would have shipped under the usual single-hold-out rule.
What does it mean if optimisation cannot find a profitable setting at all?
It means you have your answer early and cheaply, which is the good outcome. Two of our eight searches — rsi_reversal and bb_bounce — never produced a profit factor above 1.0 even on the period they were fitted to; their best in-sample result was 0.91. A rule that cannot be made to work on the data it was tuned on will not be rescued by a wider grid or a longer run. Record the range you searched and the verdict, and move to the next idea.