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:

  1. restricting outside options;
  2. 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:

  1. No combination with other indicators.
  2. No additional entry techniques.
  3. No additional exit techniques
    (no stops, take profits, break-evens, trailing stops…
    just the plain stop and reverse direction at opposite signal).
  4. No additional filtering techniques (no hourly or daily filters, no volume, trend or counter trend filters).
  5. No additional order management techniques.
  6. 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:

  1. What is the best currency pair (EURUSD or GBPUSD or USDCHF or AUDUSD, etc.)?
  2. What is the best time frame (from M1 to MN1)?
  3. What is the best price (open, high, low, close)?
  4. What is the best method (simple, exponential, linear weighted, etc.)?
  5. 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:

double iMA (string symbol), int timeframe, int period, int ma_shift, int ma_method, int MAPrice, int Shift)

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:

MA
Parameters
Description
SymbolSymbol for trading, such as EURUSD. NULL or Symbol() represents the currency pair of the chart the indicator is placed upon.
TimeFrameThe time period of the chart to apply moving average, usually set to 0, meaning the symbol of the chart EA is attached to.
MAPeriodThe look-back period of the moving average. This is the most important variable.
MAShiftThe forward shift of the moving average line, in bars, usually set to 0.
MAMethodThe calculation method of the moving average, with choices including simple, exponential, smoothed or linear weighted. The second most important variable.
MAPriceThe 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.
ShiftThe 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.

Currency Pair.

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.

Time frame

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

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.

For instance:

double ma_current = iMA (NULL,0,200,0,0,0,0);

will be:

// 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.

ConstantValueNameCalculation Description
MODE_SMA0Simple Moving AverageEqual weight is given to each price over the calculation period.
MODE_EMA1Exponential Moving AverageMore weight is given to recent prices in attempt to reduce lag.
MODE_SMMA2Smoothed Moving AverageSimilar to a SMA; however, rather than subtracting the oldest value, the previous smoothed average value is subtracted.
MODE_LWMA3Linear Weighted Moving AverageDesigned 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.

For instance:

double ma_current = iMA(NULL,0,200,0,0,0,0);

will be:

// 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.

Entry Conditions:

  • 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.

Exit Conditions:

  • 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
double
FastMACurrent,
FastMAPrevious,
SlowMACurrent,
SlowMAPrevious;

// 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:

bool
OpenBuy = false,
OpenSell = false,
CloseBuy = false,
CloseSell = false;

if (FastMACurrent > SlowMACurrent && FastMAPrevious < SlowMAPrevious)
{
OpenBuy = true; // Buy
if (OppositeClose)
CloseSell = true;
}

if (FastMACurrent < SlowMACurrent && FastMAPrevious > SlowMAPrevious)
{
OpenSell = true; // Sell
if (OppositeClose)
CloseBuy=true;
}

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.

Anecdotal Comparison to TS8

In Tradestation’s EasyLanguage you use a reserved word (function) named “Crosses Above/Over” or “Crosses Below/Under” that saves this extra step; you just need to say, “if AverageFC (C,20) Crosses Over AverageFC (C,200) then Buy”. However, in MT4, it is not as simple. You do not have the convenience of a “cross over” function unless you create one yourself. Instead, you must spell out the procedure of a crossover with two conditions: if MA (20) > MA (200) for current bar, and MA (20) < MA (200) for past bar, then Buy.

Conclusion

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.

In the next article, we will proceed with optimization of the length and method so we will seek to avoid the twin dangers of over-optimization and curve-fitting.