MACD EMA Expert for MT4 and MT5
This is the classic MACD crossover strategy with the combined moving average trend filter. Use the tutorial as the basis for building your own trading robot.
This video uses classes developed in my earlier video “Use Common Classes to Write MQL4 and MQL5 Experts”.
The key functions used are shown below, the video will explain how these are used as part of the expert.
To use the indicator classes include these lines before any code
// Include the indicator classes
#include <Orchard/Indicators/IndicatorMA.mqh>
CIndicatorMA MA(Symbol(), Period(), InpMAPeriod, InpMAMethod, InpMAAppliedPrice);
#include <Orchard/Indicators/IndicatorMACD.mqh>
CIndicatorMACD MACD(Symbol(), Period(), InpMACDFastPeriod, InpMACDSlowPeriod, InpMACDSignalPeriod, InpMACDAppliedPrice);
For MQL5 you will also need to include thse lines at the beginning of your code
// For MQL5 use the CTrade class
// This is a candidate for the modular approach soon
#include <Trade/Trade.mqh>
CTrade Trade;
CPositionInfo PositionInfo;
and then initialise the Trade object
Trade.SetExpertMagicNumber(InpMagicNumber);
Then most of the work happens in the OnTick function
void OnTick() {
// Some general get out early conditions
if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return; // exit if expert trading is not allowed
if (!MQLInfoInteger(MQL_TRADE_ALLOWED)) return;
if (!AccountInfoInteger(ACCOUNT_TRADE_EXPERT)) return;
if (!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED)) return;
if (!NewBar()) return; // Only trade once per bar
if (TradeCount()>0) return; // Only trade if there are no current trades open
// Grab the relevant values
double ma = MA.GetValue(1); // A single value
double close = iClose(Symbol(), Period(), 1);
double macd[]; // Use macd and signal to get arrays of 3 elements
double signal[];
int count = MACD.GetArray(0, 0, 3, macd); // Get 3 to make index less confusing
if (count<3) return; // Not enough data, did not return 3 values
count = MACD.GetArray(1, 0, 3, signal);
if (count<3) return; // Should not happen if the first call worked
// Now check for trades
if ( close>ma
&& macd[1]<0
&& macd[1]>signal[1]
&& macd[2]<=signal[2] ) { // Buy
OpenTrade(ORDER_TYPE_BUY);
}
if ( close<ma
&& macd[1]>0
&& macd[1]<signal[1]
&& macd[2]>=signal[2] ) { // Sell
OpenTrade(ORDER_TYPE_SELL);
}
}
The OpenTrade function has common code to setting prices and calls a small function then specific to opening trades on each platform
void OpenTrade(ENUM_ORDER_TYPE type) {
double price = (type==ORDER_TYPE_BUY) ? SymbolInfoDouble(Symbol(), SYMBOL_ASK) : SymbolInfoDouble(Symbol(), SYMBOL_BID);
price = NormalizeDouble(price, Digits());
double sl = NormalizeDouble(SwingPrice(type), Digits());
double tp = NormalizeDouble(price + ((price-sl)*InpRatio), Digits());
if (!VersionOpenTrade(type, price, sl, tp)) {
PrintFormat("Error %i placing order type %s", GetLastError(), EnumToString(type));
}
}
The SwingPrice function will find the most recent swing high or low
double SwingPrice(ENUM_ORDER_TYPE type) {
// init the variables
int bar = 0;
double price = 0;
if (type==ORDER_TYPE_BUY) {
bar = iLowest(Symbol(), Period(), MODE_LOW, InpSwingLookback, 1); // First just find lowest for the period
price = iLow(Symbol(), Period(), bar);
while (price>=iLow(Symbol(), Period(), ++bar)) { // Now keep moving back as long as next bar is lower
price = iLow(Symbol(), Period(), bar);
}
} else { // Sell is just opposite to buy
bar = iHighest(Symbol(), Period(), MODE_HIGH, InpSwingLookback, 1);
price = iHigh(Symbol(), Period(), bar);
while (price<=iHigh(Symbol(), Period(), ++bar)) {
price = iHigh(Symbol(), Period(), bar);
}
}
return(price);
}
Hello, I have followed the steps of the video line by line but I get error due to lack of #include , could you pass me the code if possible please.
Thank you very much
Did you read the note at the top of screen?
This video uses classes developed in my earlier video “Use Common Classes to Write MQL4 and MQL5 Experts”.