Summary: Implement genetic algorithm for EA parameter optimization in MQL5. Covers fitness scoring, overfitting metrics, population diversity formula, and walk-forward validation with code.




Parameter optimization is where most EAs fail in live trading due to overfitting. Genetic algorithm (GA) in MQL5 Strategy Tester provides a robust search, but without proper validation, you curve-fit to historical noise.

1. GA Core Mechanics in MQL5
MQL5's built-in GA uses selection, crossover (uniform or single-point), and mutation. The default fitness is profit-based, which is dangerous. Custom fitness should include stability metrics.

Fitness formula with overfitting penalty:
```
F = (NetProfit * RiskAdjustment) - (MaxDrawdown * 0.5) - (TradesCount < 100 ? 1000 : 0)
```

To implement custom fitness, you cannot directly modify MQL5 optimizer but can post-process using `OnTester()` return value:
```cpp
double OnTester() {
double profit = TesterStatistics(STAT_PROFIT);
double dd = TesterStatistics(STAT_MAX_DRAWDOWN);
int trades = TesterStatistics(STAT_TRADES);
double fitness = profit - dd * 0.5;
if(trades < 100) fitness -= 1000;
return(fitness);
}
```
Return value drives GA selection. Higher fitness = higher reproduction probability.

2. Population Diversity Preservation
Premature convergence happens when diversity drops below threshold. Diversity formula:
```
D = 1 - (1/N) * Σ|Pi - Pmean| / range
```
where Pi is parameter value. MQL5 GA uses default crossover rate 0.9 and mutation rate 0.01. For 100 population size, optimal mutation rate = 1/L (L=parameter bits). Adjust via `OptimizationSetMutationProbability()` in custom tester.

3. Walk-Forward Validation Protocol
Single optimization is never enough. Implement IS/OOS split:
  • In-Sample (IS): first 70% of data for GA optimization

  • Out-of-Sample (OOS): remaining 30% for validation


  • If IS fitness > OOS fitness by 30%+, overfitting exists. Use forward walk: optimize every 6 months, test next 3 months, slide window.

    MQL5 code for walk-forward via custom frames:
    ```cpp
    input datetime forwardStart = D'2024.01.01';
    input datetime forwardEnd = D'2024.04.01';

    double OnTester() {
    datetime testStart = forwardStart, testEnd = forwardEnd;
    // Calculate fitness only on OOS period
    double oosProfit = TesterStatistics(STAT_PROFIT);
    return(oosProfit);
    }
    ```
    Run optimization with IS date range, then test with `forwardStart` without re-optimization.

    4. Overfitting Detection Metrics
    Use Sharpe ratio instead of raw profit:
    ```
    Sharpe = (MeanReturn - RiskFree) / StdDev(Return)
    ```
    Sharpe > 2 is acceptable. Monte Carlo permutation test: shuffle trade sequence 100 times, if original fitness > 95% of shuffled results → overfitted.

    Implement via:
    ```cpp
    double SharpeRatio() {
    double returns[];
    // fill returns from equity array
    double avg = returns.Mean();
    double std = returns.StdDev();
    return(avg / std);
    }
    ```

    5. Practical GA Settings for Forex EAs
  • Population: 200-500 (higher for >10 parameters)

  • Generation limit: 30-50 (diminishing returns after)

  • Mutation probability: 0.02-0.05

  • Crossover: uniform with 0.7 rate

  • Elitism: keep top 5% unchanged


  • Reference
  • MQL5 Documentation: "Strategy Tester Genetic Algorithm" (www.mql5.com/en/docs/tester/ga)

  • "Quantitative Trading Systems" by Dr. Howard B. Bandy, Chapter 6-7.