In this third and final part of the MT4 strategy development guide, we’ll attempt to improve our basic moving average crossover strategy. Entry and exit parameters will first be optimized. An intraday time filter will then be implemented to help avoid false breakouts.
Part 1 can be found here.
Part 2 can be found here.
The complete trading strategy can be downloaded here.
Optimization is the process of customizing your strategy’s logic and/or parameters to suit a particular market. The assumption is that the market’s historical behaviour will be repeated in future, allowing your strategy to remain profitable.
When it comes to optimization, the old adage ‘less is more’ certainly rings true. Some level of optimization is often required to help your strategy adapt to the market in consideration. However, excessive optimization (curve fitting) overly constrains your strategy to historical data, and your strategy’s real-time performance will deteriorate significantly should market conditions change.
We will now selectively optimize some of the parameters in our moving average crossover strategy developed for the 30-minute USDJPY.
What Parameters Should Be Optimized?
To minimize the risk of curve fitting, most authors seem to agree that a strategy should contain no more than 4 optimizable parameters. So how do we pick these parameters?
I suggest starting with the most important parameters. Usually these would be the ones controlling trade entries. For our moving average crossover strategy, we have two parameters: the fast and slow lookback periods.
It is generally a good practice to avoid simultaneous parameter optimizations, since this is both time-consuming and a fast track towards a curve fit strategy. However, for our case, the interaction between both moving averages is pivotal to the success of the strategy.
Let’s optimize them simultaneously in the following ranges:
- Fast moving average: 1 – 20, in steps of 1.
- Slow moving average: 21 – 80, in steps of 1.
We will have 1200 optimization runs in total. The rest of the strategy parameters will use their default values.
Optimizing The Entry’s Lookback Period
Setting Up MT4’s Strategy Tester
We will set up the Strategy Tester in a similar manner to Part 2, with the following changes:
- Uncheck the Visual mode.
- Check the Optimization box.
- Open the Expert properties.
Here we will configure the optimization settings.
- Access the Testing tab.
- Specify a sufficiently large number for the Initial deposit. The backtester will stop opening trades if you run out of funds midway through a backtest. A large deposit thus ensures that the backtest will cover the entire date range. Since we are opening 0.1 lots per trade, $10000 should suffice.
- I usually don’t use MT4’s Genetic algorithm since I want to view the entire optimization profile across all 1200 runs. The genetic algorithm attempts to obtain the parameter set that maximizes the Optimized parameter (Balance in this case). By focusing on profitable parameters, it minimizes the total number of optimization runs. This reduces computation time, usually at the expense of accuracy.
Next, head over to the Inputs tab.
- Check the optimization box beside each moving average parameter.
- Input the optimization range and step for each parameter. Since we are optimizing these parameters, the Value column will be ignored.
The MagicNumber is a unique order identifier that every EA requires. If your EA opens multiples orders simultaneously, or you trade several EAs in a single MT4 instance, you need to ensure every order has a unique number.
That’s it for settings. Click Start to begin the optimization.
Selecting Optimal Parameters For The Entry
After all 1200 optimization runs have concluded, you can check the Journals tab to ensure there are no errors. You should see something like this:
The Optimization Results tab will show the results of each run.
If you have fewer than 1200 runs, and your Journal mentions that certain results have been discarded, you need to right-click on the results and uncheck Skip Useless Results. You then need to rerun the optimization.
For further analysis, I often open the report in Excel using Save as Report. It may be helpful to arrange your results in ascending/descending order by clicking on the column heading.
Since we are optimizing two parameters simultaneously, a 3-D surface is required to show the optimization profile. The following plots shows the strategy’s net profit as a function of the two moving average periods.
Once again, but a top view:
A few observations:
- Of the 1200 runs, only 52% are profitable. I consider 70% to be a decent number; this is a little concerning.
- The strategy performs the worst when both moving averages have very short lookbacks. Since these parameters also produce the most trades, this is likely due to a large number of ‘whipsaw’ entries.
- The optimal lookback period for the fast moving average is about 20. For the slow moving average, it is in the 35-55 range.
I will select 20 and 43 for the fast and slow moving average periods, respectively. This is in the middle of the profitable plateau (red box).
Now that the entry has been optimized, what’s next? I usually proceed to optimize some of the trade management parameters. We have the stop loss, profit target, and time stop. To minimize curve fitting, I will only optimize the parameter I consider the most important – the stop loss.
Optimizing The Stop Loss Distance
By default, our strategy’s catastrophic stop loss is placed 3 ATR from the entry price. I find that 3 ATR does a good job at risk control, while giving the trade sufficient breathing space.
But can it be improved? Let’s optimize the ATR multiple from 0.5 – 5.0, in steps of 0.05. Since stop losses are for risk control, let’s use a risk-adjusted returns metric to evaluate strategy performance. The graph below shows the strategy’s net profit / maximum drawdown as a function of the stop loss distance.
There is a clear high plateau in the 3.0 – 3.4 ATR region, although the drop-off in performance outside this range is quite disconcerting. The unoptimized net profit / maximum drawdown ratio of 3.40 is close to the maximum of 3.71, so there is little room for improvement.
Usually when optimization results in little improvement, I prefer to leave the parameter unoptimized. However, for this case I’ll bump the stop distance to 3.2 ATR since this sits in the middle of the high plateau. Ideally, you want to select parameters that are in the middle of a profitable region. This maximizes the likelihood of your strategy remaining profitable when market conditions change.
Before wrapping up our optimizations, let’s investigate the effect of time filters.
Adding a Time Filter
When you export a strategy programmed using AlgoWizard, two time-based exits are automatically included.
These allow you to exit your trades at the end of each trading day, or at the end of the week. You can specify the exact exit time. However, these rigid exits would likely inhibit us from capturing long-term trends, which contribute significantly to the strategy’s bottom line. Let’s not include these.
You also have the option of including a time-based entry filter.
This filter only allows entries during the time range specified.
Why Does Entry Time Matter?
Although forex markets are open 24/5, trading volumes vary significantly throughout the day. The London and New York sessions account for most of the day’s trading volume, with the overlap of these sessions being the busiest period.
Volume is often used to confirm price action. If a particular move is accompanied by high volume, there is a greater likelihood that the move is a result of a genuine impetus, rather than random noise. Thus by opening trades during periods of increased volume, we minimize the risk of capturing false breakouts.
Configuring a Time Filter
The forex market hours are shown below.
Since forex is decentralized, there is no official opening/closing of the markets. The hours above correspond to the approximate business hours for each region.
Before configuring the EA inputs, be sure to find out your broker’s time zone. Since the broker in this case, Alpari, operates in the GMT +2/+3 time zone, the hours above will have to be adjusted accordingly.
For our strategy, let’s limit the entry to these four periods. Hours shown are adjusted to fit Alpari’s time zone.
- London: 10:00 – 19:00
- New York: 15:00 – 00:00
- London & New York: 10:00 – 00:00
- London & New York overlap: 15:00 – 19:00
These filters can be configured in the EA as follows:
- Change the LimitTimeRange field from False to True.
- Enter the start and end of the trading time range, using the SignalTimeRangeFrom and SignalTimeRangeTo fields, respectively. The London session is shown here.
Separate backtests will be run for each of these four time filter settings. Results will be compared against the baseline without time filters.
My preference is to limit the entries to the London and New York sessions (yellow). The net profit / maximum drawdown is about the same, but profit factor and expectancy increase. The 27% reduction in number of trades is still acceptable to me.
The Optimized Strategy
After three rounds of optimizations, the strategy performance is below:
Unfortunately, even with the optimizations and entry filtering, we still have a long stagnation in the middle of the backtest. Finding profitable and robust strategies is difficult. Most of the time I end up with something like this – potentially useful but certainly not great.
I won’t recommend trading this strategy in isolation, but it could be useful as part of a diversified portfolio. Trading uncorrelated strategies is a great way to minimize stagnation periods and improve overall risk-adjusted returns. I discuss portfolio composition in detail here.
If you decide to trade a strategy live, its historical backtest also serves as a performance benchmark. When evaluating your live performance, this benchmark will help you determine whether the strategy should be removed, or have its position sizes amended.
Resist the temptation to continue optimizing in an attempt to obtain a fantastic backtest. The backtest above is average, but is more likely to be robust because optimizations were done sparingly. The entry filter was added using knowledge of intraday trading volumes; it was not a result of rigorous optimization.
More examples of strategy optimizations using MT4 are linked below:
- Entries: Bollinger Bands, Donchian channels and Commodity Channel Index
- Exits: Stop losses, trailing stops, profit targets and time stops
- Filters: Time, trend and volatility filters
Detecting Curve Fitting
It is very easy to unknowingly curve fit a strategy during development. It usually takes months of unsuccessful live trading before you realize your development process needs tweaking. To shorten the development cycle, robustness tests are often used during strategy development to detect curve fitting.
Out of sample (OOS) testing is the most common form of robustness testing. It involves backtesting your strategy using data that hasn’t been previously used for development. You can obtain your strategy’s OOS performance by backtesting it on different markets, or running walk-forward optimizations. Monte Carlo simulations are another popular form of robustness testing. These make use of random sampling to alter the sequence of trades in your backtest.
This 3-part article has shown you how to program your own trading algorithm, verify its logic and finally optimize its parameters using MT4’s backtester. All this can be done for free!
Of course, past performance is no guarantee of future results. Nonetheless, if your strategy can’t even demonstrate historical profitability, its best to discard it. A good way to ensure your backtest performance is representative of future results is to keep curve fitting to a minimum, and include numerous robustness tests in development.
With some practice and perseverance, you will be well on your way to accumulating a basket of profitable strategies.
Feel free to download the complete strategy and optimize it to suit your market.