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 ID | EXP-PARAM-SEARCH-OUTCOMES-001 |
| Parent experiment | EXP-BUILDER-TEMPLATE-BASELINE-001 |
| Source | ea-templates-manifest.js → bt.explored |
| Population | 8 recorded searches of the 53 measured templates |
| Symbol / timeframe | USDJPYm, M5 and H1 |
| Model | M1 OHLC (Model=1), Exness MT5, measured 2026-06-18 |
| Parameters varied | stop loss and take profit only |
| Last verified | 2026-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.
| Field | Where | What to set | Why |
|---|---|---|---|
| Optimisation | Settings tab | Slow complete algorithm for a small grid | The genetic mode samples the space; for 12–32 combinations you can afford to see all of it |
| Start / Step / Stop | Inputs tab, per input | Two parameters, coarse steps | Every input you tick multiplies the grid. Ours moved two |
| Forward | Settings tab | 1/2, 1/3 or 1/4 | Splits the interval so the tester scores the back half separately — this is the check you are running the search for |
| Optimisation criterion | Settings tab | Decide it before you look at the grid | It is the metric the tester ranks passes by, so it decides which row is the top row |
| Modelling | Settings tab | A coarse mode to scan, then re-run the survivor on real ticks | Scanning modes are for ranking candidates, never for a published figure |
| Period | Settings tab | Long enough to contain more than one regime | A 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.
- 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.
- On the Settings tab set Optimisation to a complete pass for a small grid, and set Forward to
1/3so the tester holds back the last third of the interval. - 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.
- 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.
- 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.
| Template | Grid searched | Best IS | OOS | Prior | Verdict |
|---|---|---|---|---|---|
ichimoku | 12 combos × 3 windows | 1.37 | 0.89 | 0.80 | no_robust_edge |
ma_crossover | 20 + 12 combos, two timeframes | 1.23 | 0.89–0.94 | 0.78 | no_robust_edge |
cci_level | 12 combos × 3 windows | 1.07 | 1.05 | 0.92 | no_robust_edge |
adx_trend | 12 combos × 3 windows | 1.04 | 0.91 | 0.80 | no_robust_edge |
breakout | 12 combos × 3 windows | 1.04 | 0.79–0.89 | 0.64–0.84 | no_robust_edge |
macd_signal | 12 combos × 3 windows | — | 1.14–1.15 | 0.74–0.77 | no_robust_edge |
rsi_reversal | 12 combos × 3 windows | 0.91 | — | — | no_robust_edge |
bb_bounce | 12 combos × 3 windows | 0.91 | — | — | no_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:
- 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.
- Then coarsen the steps, not fine-tune them. If a result only exists at
SL47, it does not exist. - 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.