No description
| README.mdMTF_Pullback_Strategy_v2.mq5 | ||
//+------------------------------------------------------------------+
//| MTF_Pullback_Strategy_v2.mq5 |
//| Copyright 2026, AlgoTrader peer |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, AlgoTrader peer"
#property link "https://www.mql5.com"
#property version "2.00"
#include <Trade\Trade.mqh>
CTrade trade;
//--- Input parameters
input group "---- Risk Management ----"
input double InpLotSize = 0.1; // Lot Size
input int InpStopLossPips = 20; // Stop Loss in Pips
input int InpTakeProfitPips = 40; // Take Profit in Pips
input ulong InpMagicNumber = 123456; // EA Magic Number
input group "---- Filter Settings ----"
input int InpADXPeriod = 14; // ADX Period
input int InpADXThreshold = 25; // Ignore markets if ADX is below this
input int InpEMAPeriod = 200; // Trend Filter EMA Period
//--- Global variables
double pipsMultiplier;
datetime lastBarTime;
int adxHandle; // Handle for the ADX indicator
int emaHandle; // Handle for the H4 EMA indicator
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(_Digits == 3 || _Digits == 5) pipsMultiplier = 10 * _Point;
else pipsMultiplier = _Point;
trade.SetExpertMagicNumber(InpMagicNumber);
lastBarTime = 0;
// Initialize the ADX indicator on the M15 timeframe to spot local choppiness
adxHandle = iADX(_Symbol, PERIOD_M15, InpADXPeriod);
if(adxHandle == INVALID_HANDLE)
{
Print("Failed to create ADX indicator handle.");
return(INIT_FAILED);
}
// Initialize the 200 EMA on the H4 timeframe to capture the macro trend direction
emaHandle = iMA(_Symbol, PERIOD_H4, InpEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(emaHandle == INVALID_HANDLE)
{
Print("Failed to create H4 EMA indicator handle.");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Release indicator handles to free up system memory
IndicatorRelease(adxHandle);
IndicatorRelease(emaHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. New Candle Filter (M15)
datetime currentBarTime = iTime(_Symbol, PERIOD_M15, 0);
if(currentBarTime == lastBarTime) return;
// 2. Check open positions
if(PositionsTotal() > 0)
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == InpMagicNumber)
{
return;
}
}
}
// 3. Choppy Market Filter (Fetch current ADX values)
double adxValues[];
ArraySetAsSeries(adxValues, true);
if(CopyBuffer(adxHandle, MAIN_LINE, 1, 1, adxValues) < 1) return; // Read last closed M15 bar value
// If ADX is below our threshold (e.g. 25), market is ranging/choppy. Do not trade.
if(adxValues[0] < InpADXThreshold) return;
// 4. Macro Trend Filter (Fetch H4 200 EMA and Price)
double emaValues[];
MqlRates ratesH4Trend[];
ArraySetAsSeries(emaValues, true);
ArraySetAsSeries(ratesH4Trend, true);
if(CopyBuffer(emaHandle, 0, 1, 1, emaValues) < 1) return;
if(CopyRates(_Symbol, PERIOD_H4, 1, 1, ratesH4Trend) < 1) return;
bool isAbove200EMA = (ratesH4Trend[0].close > emaValues[0]);
// 5. Fetch Multi-Timeframe Candle Directions
MqlRates ratesH4[], ratesH1[], ratesM15[];
ArraySetAsSeries(ratesH4, true);
ArraySetAsSeries(ratesH1, true);
ArraySetAsSeries(ratesM15, true);
if(CopyRates(_Symbol, PERIOD_H4, 1, 1, ratesH4) < 1) return;
if(CopyRates(_Symbol, PERIOD_H1, 1, 1, ratesH1) < 1) return;
if(CopyRates(_Symbol, PERIOD_M15, 1, 1, ratesM15) < 1) return;
bool isH4Bullish = (ratesH4[0].close > ratesH4[0].open);
bool isH1Bullish = (ratesH1[0].close > ratesH1[0].open);
bool isM15Bullish = (ratesM15[0].close > ratesM15[0].open);
// 6. Strategy Rules (Now incorporating the 200 EMA filter)
// BUY: H4 Bullish, H1 Bearish Pullback, M15 Bullish Trigger AND Price must be above H4 200 EMA
bool buyCondition = (isH4Bullish && !isH1Bullish && isM15Bullish && isAbove200EMA);
// SELL: H4 Bearish, H1 Bullish Pullback, M15 Bearish Trigger AND Price must be below H4 200 EMA
bool sellCondition = (!isH4Bullish && isH1Bullish && !isM15Bullish && !isAbove200EMA);
// 7. Execution
if(buyCondition)
{
double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = askPrice - (InpStopLossPips * pipsMultiplier);
double tp = askPrice + (InpTakeProfitPips * pipsMultiplier);
if(trade.Buy(InpLotSize, _Symbol, askPrice, sl, tp, "Filtered Buy"))
{
lastBarTime = currentBarTime;
}
}
else if(sellCondition)
{
double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = bidPrice + (InpStopLossPips * pipsMultiplier);
double tp = bidPrice - (InpTakeProfitPips * pipsMultiplier);
if(trade.Sell(InpLotSize, _Symbol, bidPrice, sl, tp, "Filtered Sell"))
{
lastBarTime = currentBarTime;
}
}
}