Expert Advisor Strategy Design: How to Setup an EA
Trend trading strategies have been the favorite of all serious traders, and the king of the trend trading indicators has always been the moving average. There is probably more money being traded today using moving averages than with all other technical indicators combined. They have enjoyed such popularity because they provide the clearest method to identify a trend. They show the direction of the trend and then smooth out or dampen its volatility.
It is thus to the moving average that we turn our attention to, as an example indicator for how to work up into a moving average strategy for automation.
In this article you can learn how to design an Expert Advisor strategy and setup the automated trading using different types of Moving Averages crosses.
As with any indicator-based strategy, you have to test the robustness of the moving average indicator as a possible strategy in its absolute raw state. What this means is that you are trying to restrict as much as possible the number of possible outside options and internal parameters. Once we have restricted outside options and internal parameters, we can focus on the best moving average in terms of length and method for our predefined time frame, and how to construct a simple moving average crossover strategy.
Let us provide some context for these two concepts:
- restricting outside options;
- restricting internal parameters.
Restricting Outside Options
Restricting outside options means, as we begin to test the robustness of the indicator, we do not dress it up with any possible additives common to strategies:
- No combination with other indicators.
- No additional entry techniques.
- No additional exit techniques
(no stops, take profits, break-evens, trailing stops…
just the plain stop and reverse direction at opposite signal).
- No additional filtering techniques (no hourly or daily filters, no volume, trend or counter trend filters).
- No additional order management techniques.
- No additional money management techniques.
The reason why we are keeping it raw and naked for now is that each additional additive or combination of indicators, entry and exit techniques, filters, money management formulas increases the chances of curve-fitting and indicator pollution.
Over-optimization (curve fitting) is a process of adjusting the indicators’ parameters to the concrete data, over-optimizing a trading system to produce something that looks good. The more parts and parameters a system has the more numerous the parameter values that a computer can optimize upon in order to find the exact numbers that make the system “profitable” in back testing, not in the real world.
Indicator pollution is a term i am just now inventing to describe how the addition of outside indicators and techniques to any one indicator can obscure and distort the true nature of that indicator. For instance, adding a take profit or trailing stop to an indicator-based strategy can force it to exit with profit too early, preventing the strategy developer from seeing how it would perform from start to finish, entering on the buy and reversing direction on the sell. Similarly, adding a second indicator as a confirmation indicator can force it to enter too late, preventing the strategy developer from seeing how it would perform from start to finish. Instead, I advocate that the indicator-based strategy should remain pure and unpolluted, so that the strategy developer can get a true picture of the intrinsic value of that indicator. I am not against adding other indicators and techniques to a strategy; I just recommend keeping it clean at the beginning for the sake of transparency.
Once we have figured if the indicator by itself can be made into a profitable stop and reverse strategy can we look to see if adding these extras can improve it.
Restricting Internal Parameters
Restricting internal parameters means as we begin to test the robustness of the indicator, we focus on its core parameters for possible optimization, defaulting the others to common values.
For instance, with the moving average indicator, outside of deciding if we want to trade it as a single, dual or triple crossover system, there is a number of internal parameters that we must decide upon:
- What is the best currency pair (EURUSD or GBPUSD or USDCHF or AUDUSD, etc.)?
- What is the best time frame (from M1 to MN1)?
- What is the best price (open, high, low, close)?
- What is the best method (simple, exponential, linear weighted, etc.)?
- What is the best length or period (from 2 to 2000)?
Most of these parameters show up in the moving average indicator that is native to MT4 and which has its own particular syntax:
I like to imagine the structure in parenthesis that follows the iMA indentifier as a bus with a number of designated seats. Each seat in the bus is separated by a comma and is called a parameter. The iMA indicator has seven parameters. Each parameter in turn holds a default value that can be customized (or personalized, to keep with the bus metaphor). It is useful to know what the function of each parameter, the default values taking up each parameter, how they can be customized, and what parameters really drive the bus.
Below is table for describing each of the parameters of the Moving Average:
|Symbol||Symbol for trading, such as EURUSD. NULL or Symbol() represents the currency pair of the chart the indicator is placed upon.|
|TimeFrame||The time period of the chart to apply moving average, usually set to 0, meaning the symbol of the chart EA is attached to.|
|MAPeriod||The look-back period of the moving average. This is the most important variable.|
|MAShift||The forward shift of the moving average line, in bars, usually set to 0.|
|MAMethod||The calculation method of the moving average, with choices including simple, exponential, smoothed or linear weighted. The second most important variable.|
|MAPrice||The price array to use when calculating the moving average, either close, open, high, low or some type of average. Usually the default of 0, or close, is used.|
|Shift||The backward shift of the bar to return the calculation for. A value of 0 returns the indicator value of the current bar, and a value of 3 will return the indicator value from 3 bars ago. This is the third most important variable, as we shall see.|
A handy quick reference to MA parameters (as well as the parameters to all 20 native indicators) can be found here: https://docs.mql4.com/indicators/iMA
Now that we have taken a look at all the possible parameters, I would like to offer a suggestion. Only seek to optimize two of them: Length and Mode. If you are entering the crossover at the end of the bar, you may also need to optimize the time frame. Keep all the rest at the their default values.
Delimited Parameters: Currency Pair, Time Frame, Price.
When trading with trending indicators, such as the moving average, it is best to test first on EURUSD, for two reasons. First, most of the majors are highly correlated given that they are all paired against the dollar, and thus it is best to choose the most liquid pair of them all to get the lowest spread and fastest execution. Second, because the EURUSD is the most traded pair it has the best potential for indicator success, given that most indicators rely to large degree on the self-fulfilling prophecy of their popularity. Thus you want to test the most popular indicators on the most popular of currency pairs to get the best chance of success. Given that the moving average is the most popular indicator and the EURUSD is the most popular currency pair, the combination makes the most logical sense. Once finished with EURUSD, next would be to test GBPUSD, AUDUSD and USDCHF to see if your strategy can work on these correlated pairs.
There is a common misconception as to how time frame matters for the formation of the moving average itself. Many novice strategy developers develop and optimize a moving average crossover on one time frame, and then think that if they develop it on a different time frame, it is a new strategy. But is it really? I would argue instead that length is more important and it can replace many seeming advantages that time frame offers. You just increase / decrease the length by the multiple of the time frame difference to account for the different time frame. For instance, if you find that your 100 period moving average works best on H1 time frame, then it should work more or less the same as a 200 period moving average on the M30 time frame (M30 is half H1, thus 100X2=200), or 25 period moving average on the H4 time frame (H4 is 4 times larger than H1, thus 100 / 4 = 25).
However, if you want your strategy to wait to enter at the close of the bar that had made the crossover, instead of the moment of crossover itself, time frame does indeed matter. You are then delaying the entry to the close of bar, which makes the bar’s time frame now more relevant. How does trading on the close of the bar make the time frames more relevant? Let us take an example of 100 period MA crossover strategy built on H1 time frame and a 200 period MA built on a M30 time frame. Both are set to enter/exit at end of bar. As explained above, the two strategies would cross over at the same point, somewhere within each of their respective bars. However, the time entry/exit would be have to adjust for the different time frames. If I set my strategy to wait for the crossover of a 200 period moving average on a M30 chart, then the strategy would enter/exit the same crossover point as the 100-H1 chart, but with the difference being that it would enter/ exit at the close of M30 bar that crossed over/under the moving average instead of the later H1 bar. The M30 time frame would thus give you a crossover opportunity 30 minutes earlier than the same strategy built on the H1 bar. Sometimes you want the the strategy to be fast to jump in and out and sometimes you want the extra lag time, to avoid the noise. Sometimes you might want the lag of a H4 or D1 bar instead of the quickness of a M15 or M30 bar, and vice versa. Why wait for the close? First, it is easier to back test your strategy if you wait for the close. Second, for whatever reason, it sometimes produces better results.
Thus, if you decide to construct your crossover strategy using the closing bar, you might have to test on the H1 time frame as the initial time frame, and then test the time frames below (M15 and M30) to see if quickness could be more favorable, and test time frames above (H4 and D1) to see if lag or slowness could be more advantageous.
If the time frame is critical to your strategy, it is good idea to make time frame an external parameter in order to optimize it.
Price should remain defaulted at 0, which is close price. I do think of any good reason to change the price to high, low or open. Actually there might be good reasons for other prices, but if your moving average strategy does not work with close, it won’t work with the others.
Length: the King of the Indicator parameters
Length is the most important ingredient to any moving average. It is the first variable one should seek to optimize.
If you are working a dual moving average, it is the slow moving average that really works to define the trend. The fast moving average is generally 1/4 to 1/10 fraction of the length of the slow one and it is not as much of a concern to get right.
Generally speaking, the longer the length, the more smoother and slower it is to respond to price action. This is what you want in order to find the larger and mid-sized trends. For instance, the 200-Day SMA (Simple Moving Average) crossed by the faster 20-Day SMA or 50-Day SMA is the basis for the famous “Golden Cross” that the traders the world over have used to identify the larger trend:
Below is the 20-Day SMA crossovers above/below 200-day SMA for AUDUSD:
Notice when the 20-Day SMA crossed under the 200-Day SMA in 2008 it managed to pick up 1600 pips on the downtrend of that crisis, and then when crossed over in 2009 it managed to capture 2700 pips or so on the uptrend recovery from Mar-2009 to Jul-2011. This golden cross strategy is indeed very powerful for capturing long term forex trends. Because of the fractal nature of the markets, it can be also a powerful combination to use on smaller time frames.
The downside to the longer period moving average is that it is slower to respond to price change and trend reversals. You might be delayed too long from enter entering into the new trend, missing out on a good price entry or the trade altogether. The longer period extends the time it takes for the price to eventually cross over the moving average, and by the time it does, the move may be over.
Shortening the lengths of the moving average can get you into a trend and its reversals much earlier. This can be a good thing as you want to be able to capture as many pips as possible. But watch out. Shortening the length too much can create a more jagged, close-hugging moving average that inevitably gets chopped up and faked out in sideways, volatile markets. For instance, I have found it exceedingly difficult to get a moving average of less than 25 period to work on time frames of H1 or lower because the shorter length gets one into too many false trends and fake outs.
The crux of the matter in regards to length, then, is to find the right balance between smoothness and speed. One wants the length to be long enough to be smooth and avoid choppiness and yet short enough to be fast to get you into trends early on. Strategy developers thus attempt to optimize the length in order to find the right balance between smoothness and speed. Traders also experiment with different methods in order to help with this problem, as we shall see.
Optimization Tip #1: It is a good idea to make length an extern parameter of any indicator based strategy in order to optimize it.
// place in extern variables area
extern int MALength = 200;
// place after start() function
double ma_current = iMA (NULL,0,MALength,0,0,0,0);
Optimization Tip #2: I generally start with a well-educated guess as to a reliable length for a particular time frame, and then I optimize it by steps of 5 or 10 or 25, depending on my variable range. For instance, if I were to test the moving average on a H1 time frame, and I wanted to test the range from 25 to 600, I would test in steps of 25. Bear in mind that with optimal length should profitable upon all neighboring parameter values. For instance, if you discovered that the optimal length is 200, then the parameter values before (150, 175) and after (225, 250) should also be profitable.
Method: the Queen of the Indicator Parameters (with the Real choice between Simple and Exponential).
As we have seen, changing the length is the foremost way in which to find the right balance between smoothness and speed. Changing the method can also help with this problem.
In the moving average indicator, there are four built-in methods: simple, exponential, smoothed and weighted.
|MODE_SMA||0||Simple Moving Average||Equal weight is given to each price over the calculation period.|
|MODE_EMA||1||Exponential Moving Average||More weight is given to recent prices in attempt to reduce lag.|
|MODE_SMMA||2||Smoothed Moving Average||Similar to a SMA; however, rather than subtracting the oldest value, the previous smoothed average value is subtracted.|
|MODE_LWMA||3||Linear Weighted Moving Average||Designed to put more weight on recent data and less weight on past data.|
I am not going to get into the math of these modes, as they are covered in other articles on the net.
In practice, you will see there are two alliances between the 4 modes, which reduces the number of real choices to two:
The Smooth Alliance: Simple + Smoothed
The SMA and SMMA both emphasize smoothness. You will find that the SMMA is more smooth than the SMA when using the same length.
For example, here is the 50 SMMA versus the 50 SMA on a GBPUSD H1 chart:
As you can see the SMMA (50) is slower to move in response to price change than its SMA (50) counterpart. We are told this is so because the SMMA provides a smoother calculation than the SMA.
However, if the length of the SMMA is halved, it will look much the same as the EMA, a visual fact that takes away from its distinction.
Here is the 50 EMA versus the 25 SMMA on a GBPUSD H1 chart:
As you can see there is virtually no difference between a 50 EMA and a halved value of SMMA (25). The lines completely overlap.
Thus, if the real difference between the EMA and SMMA lies in the length, it is better to work with SMA as the true representative of smoothness. The advantage of working with the simple is that it is popular and intends to be smooth, that is, it intends (given a long enough length) to provide more reliable trend signals.
However, there are those who do not like the fact that the SMA lags behind the latest data point by nature of its smoothing, and they prefer to give more weight to more recent data points, as in the weighted and exponential moving averages.
The Speed Alliance: Exponential + Linear Weighted
The exponential and linear weighted moving averages both seek to overcome price lag by assigning more meaning to recent prices and less to older prices. In doing so, they both react to price change faster. However, in practice, you will see that although they have different ways of assigning more meaning to recent prices, they often travel the same path.
For example, here is the 50 EMA versus 50 LWMA on a GBPUSD H1 chart:
Though it is not an exact match most of the trend reversals happen at the same spot. You not going to find an entirely different strategy between the crossover of a 50 period EMA versus the crossover of a 50 period LMMA.
Thus, if there is no significant difference between the two, it is better to work with the exponential as it is far more popular.
The advantage of working with the exponential versus the simple is that it is adapts to market price much faster than the simple. It reduces the lag, and gets you into a trend reversal much earlier. The disadvantage is that it can be overly sensitive, negating the original purpose of the moving average: to smooth out price action. The EMA tends to be more vulnerable to choppy markets.
The Real Choice: Between SMA and EMA
While it is much easier to know beforehand that the real choice in method is between the simple and exponential, it is much hard to know beforehand which is going to be the better method. While one may have a bias for the simple for its smoothness, or the exponential for its speed, but in the end, one can never know which will be the real queen of the game until both are given a fair trial.
Optimization Tip#1: It is a good idea to make method an extern parameter of any indicator based strategy in order to optimize it.
// place in extern variables area
extern int MATime = 0;
extern int MALength = 200;
extern int MAMethod = 0; // 0 = SMA; 1 = EMA; 2 = SMMA; 4= SWMA
// place in start() function
double ma_current = iMA (NULL,MATime,MALength,0,MAMethod,0,0);
Optimization Tip #2: Only optimize between SMA and EMA.
Because I have shown that the SMMA is a redundant version of SMA, and that the LWMA is a redundant version of the EMA, you really do not need to optimize on these two as well. It is much smarter and easier to just optimize between SMA and EMA, between 0 and 1, with a step of 1.
The Crossover: Start with Dual Moving Average Crossover
When the trader comes and attempts to build the moving average crossover system, he will often asks himself if he should make a single, dual or triple moving average crossover. See my article on moving averages for the differences.
The answer is easy: the dual moving average crossover is the best.
There are those that will argue that the single moving average crossover holds the advantage of being the simplest. You go long or short when the closing price crosses over / under the moving average. But the dual moving average can be just as simple: you go long or short when the fast moving average crosses over / under the slow moving average. The single MA holds an advantage in being faster at the cross, but the dual MA can also be fast at the cross if the fast MA is short enough. In fact, if you build a dual moving average crossover system, you can test for the single moving average cross as a potential strategy by setting the fast MA to 1. Setting the fast MA to 1 basically reduces the fast MA to the function of a closing bar, making it perform as as it were a single moving average cross system.
The triple moving average can be problematic. The entry mechanism is basically the same as the dual moving average, entering when the fast moving average crosses the slow moving average. The difference lies in the exit mechanism, which calls for a faster approach, exiting when a third, faster MA cross over/under the slow MA. But this introduction of the third MA risks indicator pollution. If it exits when the faster MA crosses over / under the slow MA, it is cutting short the potential life span of the moving average in the same way a take profit or trailing stop would. Adding this third MA forces th MA strategy to exit too early, preventing the strategy developer from seeing how it would perform from start to finish, exiting and reversing on opposite signal.
Thus, we will start with the dual crossover.
Forming Entry/Exit Conditions for Stop and Reverse Dual MA Crossover
Having from the outset restricted a number of outside options and internal parameters, it is now time to get down and dirty with a dual moving average strategy that only seeks to optimize the slow MA length and only two methods, SMA and EMA.
Our initial idea, then, is to code the entry conditions of the 20-200 period MACross, but instead of testing it on the higher daily timeframe, as it was originally intended, we are going to test on the H4 time frame. Given the fractal nature of the markets, it should work just as as well on this lower time frame, and it should give us a larger trade sample size than the daily time frame. We will convert opposite entries into exits in order to make it a simple stop and reverse system–which is the best method for testing the strength of the entry method. A good entry method, flipped around so that opposite entries become exits, should also work sufficiently well as an exit method. Later on we will change the time frame, lengths and methods of the moving averages to see if such changes gives us better possibilities.
- If the short SMA line crosses above the long SMA, buy (long).
- If the short SMA line crosses below the long SMA, sell (short).
We will only open one trade order at any given time.
- If the short SMA line crosses below the long SMA, Close (Buy)
- If the short SMA line crosses above the long SMA, Close (Short)
With MT4, there is often more than way of creating an EA for the exact same conditions, but for now I will stick to the most basic version.
The standard way of coding a moving average crossover is to indicate two sets of variables and conditions:
The FastMA’s relationship (greater than/less than) to SlowMA on the current bar and the FastMA’s relationship to the SlowMA on previous bar.
Example of variable definitions:
// Place in extern variables section
extern int MATime = 0;
extern int MAFastLen = 20;
extern int MASlowLen = 200;
extern int MAMethod = 0;
// Place in global variables section, just under extern variables
// Place within Start() function, before entry conditions
FastMACurrent = iMA (NULL, MATime, MAFastLen, 0, MAMethod, 0, 0);
FastMAPrevious = iMA (NULL, MATime, MAFastLen, 0, MAMethod, 0, 1);
SlowMACurrent = iMA (NULL, MATime, MASlowLen, 0, MAMethod, 0, 0);
SlowMAPrevious = iMA (NULL, MATime, MASlowLen, 0, MAMethod, 0, 1);
Note: for a handy reference on the parameters of the iMA (Moving Average), please go here: https://docs.mql4.com/indicators/iMA
What differentiates a FastMACurrent from the FastMAPrevious is not the variable name I assigned to each (I just chose these names to help me remember which moving averages I am dealing with); it is the last parameter of the iMA. This last parameter called “shift” indicates the current bar with 0, the previous bar with 1, two bars back from current with 2, etc.
In my setup, I will reference these variables thus for the entry conditions:
OpenBuy = false,
OpenSell = false,
CloseBuy = false,
CloseSell = false;
if (FastMACurrent > SlowMACurrent && FastMAPrevious < SlowMAPrevious)
OpenBuy = true; // Buy
CloseSell = true;
if (FastMACurrent < SlowMACurrent && FastMAPrevious > SlowMAPrevious)
OpenSell = true; // Sell
For the buy signal, you can see that I needed to indicate that the fast moving average of the current bar had to be greater than the slow moving average of the current bar. That condition with current bars makes sense.
Why, then, did I also have to indicate that the second condition, that the fast moving average of previous bar had to be less than the slow moving average of previous bar?
If I did not indicate the second condition, and used only the current MA relationship for a buy signal — example, if ( FastMACurrent > SlowMACurrent), I would be buying positions continuously after every stop loss or take profit, because the code is telling the program that that new orders need to be placed because the current fast moving average is still above the slow moving average. However, I do not want continuous entry. I want to enter on the moment of crossover. Since there is no native crossover function in MT4, I have to create a workaround: I had to create a second condition that states that I cannot enter when fast MA is currently above the slow MA unless fast MA was previously below the slow MA.
All we need now to do is insert our setup parameters into an EA, and you can see how I have done so in the EA called:
Download the EA and pop open the hood to see what it looks like.
Preliminary Backtests with MA Crossover EA
I am planning to test my newly minted 20-200 SMA Crossover on the H4 time frame of EURUSD using 0.1 mini lot on a 10K demo account. Because this is a MA Crossover, the best signals are often generated from the longer lengths on the higher frames. The shorter lengths on the shorter timeframes can generate too many false signals. I am choosing three periods for back testing.
Using FXPro, I am going to backtest the EURUSD for the 28 year period from 1971 to Jan-1999, before the official adoption of the Euro. How did FXPro get EURUSD data before Jan-1999 if the Euro did not exist? There could be two ways: FXPro could be taking the data of the German Mark, the strongest representation of the Euro, or it could be using a merged historical basket of the 11 legacy currencies that comprised the Euro when it was started in Jan-1999. Next, I am going to backtest the EURUSD for the 10 years from Jan-1999 to Jan-2009, which should see how the strategy works out in over the ups and downs of its official first 10 years of life. Lastly, I am going to backtest on the last three years, from 2009-2012, so see how the strategy works during this most recent period, beset by the sovereign debt crisis.
Backest#1: 28 year period from Jan-1971 to Jan-1999 (click on pic to see detailed report):
This EA produced $7690 / 7690 pips / 76% return over 49 trades (16 Win) and 28 years (2.8% per annum return), while suffering through a $3786 / 3780 pip / 37% draw down if you happened to start at the wrong time. If you can stomach the draw down, these are decent results, because over 28 years most EAs would seriously degrade in performance whereas this one kept its head above the water and produced results.
Ok, lets see what it it did in the inaugural first ten years of the Euro’s life.
Backtest#2: 10 years period from Jan-1999 to Jan-2009 (click on pic to see detailed report):
The EA is still managing to keep its head above the water in this next 10 years. Here you have $4996 / 4996 pips / 49% return over 10 years (4.9% per annum), and the maximal drawdown is $2088 / 2088 pips / 20%, numbers which suggest better than the last 28 years; however, its profit factor has fallen from 1.8 down to 1.48, suggesting that there were more drawdown periods. This looks to be the case when you compare the two equity charts; the first one looks like a steady upward rise whereas the second has a a bit more jagged rise.
Ok, now let’s see how it did in the last three years.
Backtest#3: 3 year period from Jan-2009 to Jan-2012 (click on pic to see detailed result):
As you can see, the EA looks promising. It returned $2152 / 2152 pips / 21% over 3 years (7% per annum) and 41 trades (11 Win), while suffering through a $1978 / 1978 pip / 19% draw down. I like to see that the per annum performance has doubled and that the overrall stats are much the same as they have been in the last 38 years. Remember, the longer in time a strategy has been back tested, the greater the liklihood of degredation. Few EA strategy developers / vendors will show more than 3 years backtest on their EA, and even smaller fraction can show more than 10 years. They do not show because they have curve-fitted their strategy to the most recent data period and it simply does not work in prior periods. The EA I have created above is a bare bones system without optimization and curve-fitting that has shown to be reliably decent over 41 years in picking up the larger trends.
So far we delimited most outside options and delimited all internal parameters to create a very raw, bare-bones stop and reverse 20-200 Dual Moving Average Crossover. As we have seen, in the last 41 years of backesting on EURUSD H4, it has held up surpisngly well, generating over $15000 / 15000 pips a 10K account, without money management. I believe it has done well precisely because of its raw state. When you do not dress up the indicator based strategy with additional indicators, entry/exit techniques, filters, order and management techniques, you get to see it perform as it should, with less chance of curve-fitting and indicator pollution. With less parts and parameters to the system, there is less chance that the system has been curve-fitted on historical data. Moreover, layering on many combinations of indicators and techniques can obscure and distort the true nature of the indicator based strategy, and so withholding this outfitting process, at least in the beginning, can help one see how the indicated based strategy can perform in its naked state.
Additionally, I have argued that of all the internal parameters, length is the most important, and method (with the real choice here between Simple and Exponential) is next in importance. I chose the 20-200 Dual SMA Crossover because it is one of the most popular versions of the moving average crossover to determine long term trend direction. While most use it on the daily time frame, I thought it could used just as well on the H4 time frame because of the fractal nature of the markets, and because we can see a greater trade sample size. I was not entirely surprised to see it successful over 41 years because whenever I had these two simple moving averages plotted out on a chart, I could visualize how the fast crossing the slow can usually pick up the larger trends.
In the next article, we will proceed with optimization of the length and method to see if we can discover if our dual moving average crossover can be enhanced by a length different from 200 or a method different than simple, such as exponential. In doing so we will seek to avoid the twin dangers of over-optimization and curve-fitting.