Parameter optimization is the most dangerous step in EA development—overfitting to past data destroys forward performance. Genetic algorithms (GA) offer a probabilistic search, but improper use amplifies overfitting. This guide focuses on robust GA design for MT4/MT5.
1. Core GA Components for EA Optimization
A GA operates on a population of parameter sets (chromosomes). Standard workflow:
2. Fitness Function Design – Avoid Single Metrics
Using only net profit leads to curve-fitting. Combine multiple objectives:
``
Fitness = w1 ProfitFactor + w2 (AverageTrade / Drawdown) - w3 TradesCount
`
Better: Use Sharpe ratio or Calmar ratio. Example fitness calculation in MQL5:
`cpp
double CalculateFitness(double profitFactor, double sharpeRatio, double maxDrawdownPct) {
if(maxDrawdownPct <= 0) return 0;
double score = profitFactor 0.4 + sharpeRatio 0.4 - (maxDrawdownPct / 100.0) 0.2;
return MathMax(0, score);
}
`
Never optimize purely on total net profit.
3. Mutation & Crossover Formulas
For continuous parameters (e.g., StopLoss = 20-200 pips):
Uniform crossover: childParam = alpha parent1 + (1-alpha) parent2, alpha in [0,1]
Gaussian mutation: newValue = oldValue + N(0, sigma), sigma decreasing over generations
Sigma decay: sigma(t) = sigma_initial * exp(-t / tau) where tau is decay constant (e.g., 20 generations)
MQL5 implementation snippet:
`cpp
double Mutate(double value, double minVal, double maxVal, double sigma) {
double mutation = MathRandNormal(0, sigma);
double newVal = value + mutation;
if(newVal < minVal) newVal = minVal + (minVal - newVal);
if(newVal > maxVal) newVal = maxVal - (newVal - maxVal);
return MathMax(minVal, MathMin(maxVal, newVal));
}
`
MathRandNormal requires Box-Muller transform implementation.
4. Avoiding Overfitting – Walk-Forward Validation
GA must be validated out-of-sample. Standard protocol:
Split data: 70% in-sample (IS), 30% out-of-sample (OOS)
Run GA on IS period only
Test best 5-10 parameter sets on OOS
Accept only if OOS performance > 80% of IS performance
Formula for robustness score:
`
Robustness = min(1.0, OOS_ProfitFactor / IS_ProfitFactor) * (1 - OOS_DD_increase)
`
Accept robustness > 0.7.
5. Multi-Objective Pareto Optimization
Single fitness score hides trade-offs. Pareto front contains parameter sets where no objective can improve without worsening another. Common objectives: profit, Sharpe, max drawdown, trade count.
In MQL5, implement non-dominated sorting:
`cpp
bool IsDominated(double obj1[], double obj2[]) {
bool betterInAny = false;
for(int i = 0; i < ArraySize(obj1); i++) {
if(obj1[i] > obj2[i]) return false; // Assuming maximization
if(obj1[i] < obj2[i]) betterInAny = true;
}
return betterInAny;
}
`
Export Pareto frontier sets, not just the single “best”.
6. MT4 vs MT5 GA Capabilities
MT5 Strategy Tester includes native GA optimization with configurable population size, crossover probability (0.7-0.9), and mutation rate (0.01-0.1). MT4 requires external GA wrappers (e.g., using DLL or exporting parameters to Python). For MT4 users, recommended workflow: export tick data, optimize via Python’s DEAP` library, then import best parameters.Reference