//+------------------------------------------------------------------+ //| 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 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; } } }