Chapter 4: MA Cross with MACD filter

Before I start teaching you how to program an EA which uses an MA Crossover as entry signal with an MACD filter, I need to tell you that I have changed the programming style a bit of the code we wrote the last time. If you download the new file you will see that I have abbreviated a lot. If you compare the new file with the old it should not be a problem for your to read and understand it. This is a way how you can use a boolean simpler.
if(UseFilter) is the same as if(UseFilter==true)

AND

if(!UseFilter) is the same as if(UseFilter==false)
This can also be done with boolean function. (See the next example) And you have to know that you can sometimes leave the curly brackets away. But only if you write only one command line behind it.
// you can do this
if(IsNewBar()) Print("There is a new bar");

// but you cannot do this
if(IsNewBar()) Print("There is a new bar"); Comment("There is a new bar");

// in the second case the Comment would be displayed even if the IsNewBar function returns a false. It's like the Comment is on a new line.

The strategy

We are going to make an MA Cross EA with two Moving Averages. A fast MA with the period of 12 and a slow MA with the period of 16. We only want to open a buy trade if the MACD (12,26,9) is above 0 and if the MACD main line is above the MACD signal line. The data for this indicator should be from the daily chart. (I don’t know yet if it is a winning strategy, but it does not matter).
ma-cross-with-macd-filter

Let’s start

In this chapter we only take a look at our custom functions InitIndicators(), BuySignal() and SellSignal() and the global variables for our new indicators, since these are the only things we need to change to make our new strategy work. First we write are global variables for our indicators to store there values. We have the 4 listed below.
//--- indicators
double MACD_main,MACD_signal;
double fast_MA,slow_MA;
But wait. For this strategy we need some more data than these 4. For a crossover we need 2 variable per MA. We need the price of both MAs before and after the cross to detect a crossover. We need the price of the second and third candles (remember candle 0 is the current candle, candle 1 the past and so on). For the MACD we use the price of the current candle. So we write:
//--- indicators
double MACD_main,MACD_signal;
double fast_MA_candle1,fast_MA_candle2;
double slow_MA_candle1,slow_MA_candle2;
Next we need to fill the variables with the indicators prices within the InitIndicators() function.
void InitIndicators()
  {
      // MACD (0-MODE_MAIN, 1-MODE_SIGNAL)
      MACD_main=iMACD(_Symbol,PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
      MACD_signal=iMACD(_Symbol,PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);

      // Fast MA
      fast_MA_candle1=iMA(_Symbol,PERIOD_CURRENT,12,0,MODE_EMA,PRICE_CLOSE,1);
      fast_MA_candle2=iMA(_Symbol,PERIOD_CURRENT,12,0,MODE_EMA,PRICE_CLOSE,2);

      // Slow MA
      slow_MA_candle1=iMA(_Symbol,PERIOD_CURRENT,16,0,MODE_EMA,PRICE_CLOSE,1);
      slow_MA_candle2=iMA(_Symbol,PERIOD_CURRENT,16,0,MODE_EMA,PRICE_CLOSE,2);
  }
You find more information about the iMACD function here: http://docs.mql4.com/indicators/imacd

Entry Signals

Now we only have to write the entry signals. It is pretty easy. Let’s start with the MAs. If the fast MA on candle 1 is above the slow ma on candle 2 AND the fast MA on candle 2 is below the slow MA on candle 2, the BuySignal function will return true. By default, the function returns a false.
bool BuySignal()
  {
// Check Signal
   if(fast_MA_candle1 > slow_MA_candle1 && fast_MA_candle2 < slow_MA_candle2)return(true);

   return(false);
  }
Vice versa for the Sell Signal

MACD filter

If the MACD main line is not above 0 and the MACD Signal line is also not above 0, the „MACD zero line filter“ will return a false. If the MACD main line is not above the MACD signal line, the „MACD trend filter“ will return a false. We achieve the not with the exclamation mark before the brackets where the strategy is written in.
bool BuySignal()
  {
// MACD zero line filter
   if(!(MACD_main > 0 && MACD_signal > 0))return(false);

// MACD trend filter
   if(!(MACD_main > MACD_signal))return(false);

// Check Signal
   if(fast_MA_candle1 > slow_MA_candle1 && fast_MA_candle2 < slow_MA_candle2)return(true);

   return(false);
  }
Download the source code

Beautify the code

The EA is now finished and work well. But I do not like some details about it. I will now show you how to use arrays to make the code look more beautiful. Instead of using a variable for every price we want to store, we should use arrays. If you do not know what arrays are, please read this first: http://book.mql4.com/variables/arrays. So we use one Array for the MACD, one for the fast MA and one for the slow MA. We will store 2 prices in each. The Main and Signal line in the MACD[]. Candle1 and candle2 of the two MAs in the fast_MA[] and slow_MA[] arrays. But since an array always start counting on 0 and it would look nicer if we store the Mas candle1 in [1], we use 3 memory slots of the arrays and leave the first [0] empty.
//--- indicators
double MACD[2],fast_MA[3],slow_MA[3];
To store the indicators prices in these arrays we use a for loop. See: http://docs.mql4.com/basis/operators/for The first time the for loop is run through, the EA will store the ….
  • int i is 0
  • MACD main price in the MACD[0]
  • Candle1 price of the fast MA in the fast_MA[1]
  • Candle1 price of the slow MA in the slow_MA[1]
The second time the for loop is run through, the EA will store the ….
  • int i is 1
  • MACD signal price in the MACD[1]
  • Candle2 price of the fast MA in the fast_MA[2]
  • Candle2 price of the slow MA in the slow_MA[2]
void InitIndicators()
  {
   for(int i=0;i<2;i++)
     {
      // MACD (0-MODE_MAIN, 1-MODE_SIGNAL)
      MACD[i]=iMACD(_Symbol,PERIOD_D1,12,26,9,PRICE_CLOSE,i,0);

      // Fast MA
      fast_MA[i+1]=iMA(_Symbol,PERIOD_CURRENT,12,0,MODE_EMA,PRICE_CLOSE,1+i);

      // Slow MA
      slow_MA[i+1]=iMA(_Symbol,PERIOD_CURRENT,16,0,MODE_EMA,PRICE_CLOSE,1+i);
     }
  }
After we made these changes we can adapt the Entry Signals as follow:
bool BuySignal()
  {
// MACD zero line filter
   if(!(MACD[0] > 0 && MACD[1] > 0))return(false);

// MACD trend filter
   if(!(MACD[0] > MACD[1]))return(false);

// Check Signal
   if(fast_MA[1] > slow_MA[1] && fast_MA[2] < slow_MA[2])return(true);

   return(false);
  }
I think it look much better now 😀 Please download the file to see the whole source code.

I have not yet wrote a tutorial about how to close trades, but if you want to know how to do it, please check this topic:
https://quivofx.com/boards/topic/orderclose-function/

Go to the next tutorial.

Have questions about this mql4 tutorial? Write a comment or open a topic in the forum (if there is not already an answer for it)

If you see an error please contact me.

This MQL4 tutorial was created on December 14, 2015.

Download the source code
5/56 ratings

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.