Many EA developers rely on the built-in optimization metrics in MetaTrader 4. However, standard metrics like `MAX_BALANCE` or `SHARPE_RATIO` often fail to guide the Genetic Algorithm (GA) toward truly robust parameter sets. This article explores a more advanced approach: constructing custom optimization criteria using mathematical activate functions, transforming how you perform EA optimization in MT4.
The Problem with Standard Optimization
The default GA in MT4 is powerful, but it is only as good as its fitness function. Relying on a single metric like "Profit" often leads to overfitting. Conversely, using a multi-criteria score via a crude `return(0)` can mislead the GA, causing it to discard potentially valuable parameter combinations that perform poorly in early generations but excel later .
Forum experts have noted cases where a parameter set losing 6000 units scored higher than a profitable set simply due to poor weighting logic . We need a mathematical framework that normalizes metrics and balances their influence.
Introducing Activate Functions for Optimization
Activate functions, commonly used in neural networks, provide a mathematical way to map raw metric values (e.g., Recovery Factor from 0 to 100) into a normalized score (e.g., 0 to 1). This prevents "gradient explosion" where one metric dominates the score .
#### 1. Sigmoid Function (Soft Constraints)
The Sigmoid function is ideal for creating a "soft" target. It returns a value between 0 and 1, making it perfect for normalizing metrics.
Formula: `f(x) = 1 / (1 + e^-x)`
MQL4 Implementation:
```cpp
// Calculate the Custom Score for the Recovery Factor
double CalculateScore() {
double rf = TesterStatistics(STAT_RECOVERY_FACTOR);
double target_rf = 2.0;
double x = rf - target_rf; // Shift the curve
// Sigmoid function: returns a value between 0 and 1
double score = 1 / (1 + MathExp(-x));
return score;
}
```
Logic: If `rf` equals `target_rf` (2.0), `x` is 0, and the score is 0.5. If `rf` is much higher (e.g., 5.0), the score approaches 1.0. This gracefully rewards higher values without letting a single metric skyrocket the total score .
#### 2. ReLU Function (Hard Constraints)
The Rectified Linear Unit (ReLU) sets a hard minimum threshold. If a condition is not met, the score is zero, automatically disqualifying the parameter set.
Formula: `f(x) = max(0, x)`
MQL4 Implementation:
```cpp
double CheckMaxDrawdown() {
double dd = TesterStatistics(STAT_MAX_DRAWDOWN);
double max_allowed_dd = 30.0; // 30% max drawdown
double tolerance = 5.0; // Soft boundary buffer
double x = (max_allowed_dd - dd) / tolerance;
// ReLU: If Drawdown > 30, x is negative -> Score 0
return MathMax(0, x);
}
```
Building a Composite Criterion (Code Template)
To effectively guide the GA, combine multiple metrics into a weighted score. The key is normalization.
```cpp
//+------------------------------------------------------------------+
//| Custom optimization criterion |
//+------------------------------------------------------------------+
double OnTester() {
// 1. Fetch raw statistics
double profit = TesterStatistics(STAT_PROFIT);
double dd = TesterStatistics(STAT_MAX_DRAWDOWN);
double sharpe = TesterStatistics(STAT_SHARPE_RATIO);
double trades = TesterStatistics(STAT_TRADES);
double rf = TesterStatistics(STAT_RECOVERY_FACTOR);
// 2. Apply Activate Functions for Normalization
// Target Profit: $10,000 using Sigmoid (Soft)
double x_profit = (profit - 10000.0) / 5000.0;
double score_profit = 1 / (1 + MathExp(-x_profit));
// Max Drawdown Target: <20% using ReLU (Hard)
double x_dd = (20.0 - dd) / 5.0;
double score_dd = MathMax(0, x_dd);
if(score_dd <= 0) return 0.0; // Immediate rejection
// Minimum Trades (Stability): >100 trades
double x_trades = (trades - 100) / 50.0;
double score_trades = 1 / (1 + MathExp(-x_trades));
// 3. Weighted Sum (Weights add up to 100)
double w_profit = 40.0;
double w_dd = 40.0;
double w_trades = 20.0;
double total_score = (w_profit * score_profit) +
(w_dd * score_dd) +
(w_trades * score_trades);
Print("Custom Score: ", total_score);
return total_score;
}
```
CAUTION: Genetic Algorithm Mechanics
When you enable the GA in the MT4 Strategy Tester, it does not brute-force every combination. It uses "survival of the fittest." If you use `return(0)` to discard sets with high drawdown, the GA loses genetic diversity. The Sigmoid approach is superior because it keeps "average" sets in the population, allowing the algorithm to cross-breed and find local maxima that would otherwise be unreachable .
Summary
Upgrading your EA optimization from simple `return(profit)` to a custom, normalized score using activate functions (Sigmoid, ReLU) is a hallmark of advanced MQL4 development. This method respects the mechanics of the genetic algorithm, minimizes overfitting, and statistically guides the search toward parameters with real-world robustness.
---
References:
1. MQL5 Articles. (2025). *New Methods of Custom Criteria in Optimization (Part 1)*
2. MQL5 Forum. (2024). *Beginner Questions MQL4 MT4*
3. MQL4 Documentation. (2025). *TesterStatistics*