Creating a Reliable EA with Custom Optimization in Metatrader 5


Hi everyone,
Lately, I’ve been working on building an Expert Advisor that I can trust enough to manage my money hands-off — ideally for an entire year without constant intervention.
To get there, the EA needs to meet a few important conditions that I set:
Low maximum equity drawdown
A good profit factor and Sharpe ratio
A healthy win rate
And a reasonable number of trades per year
Why Customization
My goal was simple: find the most promising combinations of SL and TP that works well with my EA before running full in-sample and out-of-sample tests. MetaTrader 5’s optimization tool is actually pretty powerful — it allows you to backtest and optimize your EA at the same time without going to a third-party app.
But here’s the catch: while MT5 lets you optimize by basic metrics like profit or drawdown, it doesn’t allow you to optimize by a combination of metrics — unless you build a custom criterion yourself.
Building a Custom Criterion
As I'm quite a beginner in building EA with MQL5, I started searching online and asking LLMs on how to create a custom criterion in EA. They explain the way to achieve it really well and even direct me to the MQL5 documentation about it and how it works.
I'm using onTester
to create my custom criterion and create my own scoring system since what I need is a mix of a few criteria combined together (Sharpe ratio, drawdown, profit factor, win rate, etc). Those criteria will be scored and combined into a single value for the optimizer to work with.
For Those Who Want to Try it
If you’re also running into this limitation in MT5, I'm sharing my code below as an example. You can adjust the code according to your needs.
double OnTester(void)
{
double drawdown = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
double sharpe = TesterStatistics(STAT_SHARPE_RATIO);
double profitFactor = TesterStatistics(STAT_PROFIT_FACTOR);
double trades = TesterStatistics(STAT_TRADES);
double winrate = (TesterStatistics(STAT_TRADES_PROFIT) / trades) * 100.0;
if (drawdown > 20 || trades < 100 || sharpe < 1 || winrate < 50) {
return 0;
}
double score =
(sharpe * 1) +
(profitFactor * 1) +
(winrate * 0.2) +
(trades / 100) -
(drawdown * 0.5); // penalty for risky strategies
return score;
}
You can modify the code above by adding or removing metrics as needed. Additionally, you can adjust the criteria to accept input parameters. For example, if you want to set a minimum drawdown of 10%, you can allow the user to input “10” as a parameter, which will then be used in the conditional check.
Please let me know if you have any alternative to the solution that I build. Would love to discuss it!
Subscribe to my newsletter
Read articles from James Tedy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
