//+------------------------------------------------------------------+ //| MadTurtle_MTF.mqh - Multi-Timeframe confirmation filters | //+------------------------------------------------------------------+ #ifndef MADTURTLE_MTF #define MADTURTLE_MTF struct MadTurtleMTFState { double h4_sma_fast; double h4_sma_slow; double h4_rsi; double h4_macd; double h4_volume_ratio; ENUM_ORDER_TYPE h4_bias; double d1_sma_fast; double d1_sma_slow; double d1_rsi; double d1_volume_ratio; ENUM_ORDER_TYPE d1_bias; datetime h4_updated; datetime d1_updated; }; //+------------------------------------------------------------------+ //| Indicator value helpers (MQL5 handle + CopyBuffer) | //+------------------------------------------------------------------+ double MadTurtle_GetMA(ENUM_TIMEFRAMES tf, int period, int shift) { int h = iMA(_Symbol, tf, period, 0, MODE_SMA, PRICE_CLOSE); if(h == INVALID_HANDLE) return 0; double buf[]; if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; } IndicatorRelease(h); return buf[0]; } double MadTurtle_GetRSI(ENUM_TIMEFRAMES tf, int period, int shift) { int h = iRSI(_Symbol, tf, period, PRICE_CLOSE); if(h == INVALID_HANDLE) return 0; double buf[]; if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; } IndicatorRelease(h); return buf[0]; } double MadTurtle_GetATR(ENUM_TIMEFRAMES tf, int period, int shift) { int h = iATR(_Symbol, tf, period); if(h == INVALID_HANDLE) return 0; double buf[]; if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; } IndicatorRelease(h); return buf[0]; } double MadTurtle_GetMACD(ENUM_TIMEFRAMES tf, int fast, int slow, int signal, int shift) { int h = iMACD(_Symbol, tf, fast, slow, signal, PRICE_CLOSE); if(h == INVALID_HANDLE) return 0; double buf[]; if(CopyBuffer(h, 0, shift, 1, buf) != 1) { IndicatorRelease(h); return 0; } IndicatorRelease(h); return buf[0]; } double MadTurtle_GetVolume(ENUM_TIMEFRAMES tf, int shift) { long vol = iVolume(_Symbol, tf, shift); return (double)vol; } ENUM_ORDER_TYPE MadTurtle_MTF_BiasFromSMA(double sma_fast, double sma_slow) { if(sma_fast > sma_slow && sma_fast > 0 && sma_slow > 0) return ORDER_TYPE_BUY; if(sma_fast < sma_slow && sma_fast > 0 && sma_slow > 0) return ORDER_TYPE_SELL; return -1; } //+------------------------------------------------------------------+ //| Update multi-timeframe state | //+------------------------------------------------------------------+ void MadTurtle_UpdateMTFState(MadTurtleMTFState &state) { datetime now = TimeCurrent(); if(now - state.h4_updated >= 60) { state.h4_sma_fast = MadTurtle_GetMA(PERIOD_H4, 10, 1); state.h4_sma_slow = MadTurtle_GetMA(PERIOD_H4, 50, 1); state.h4_rsi = MadTurtle_GetRSI(PERIOD_H4, 14, 1); state.h4_macd = MadTurtle_GetMACD(PERIOD_H4, 12, 26, 9, 1); state.h4_volume_ratio = MadTurtle_GetVolume(PERIOD_H4, 1); state.h4_bias = MadTurtle_MTF_BiasFromSMA(state.h4_sma_fast, state.h4_sma_slow); state.h4_updated = now; } if(now - state.d1_updated >= 60) { state.d1_sma_fast = MadTurtle_GetMA(PERIOD_D1, 10, 1); state.d1_sma_slow = MadTurtle_GetMA(PERIOD_D1, 50, 1); state.d1_rsi = MadTurtle_GetRSI(PERIOD_D1, 14, 1); state.d1_volume_ratio = MadTurtle_GetVolume(PERIOD_D1, 1); state.d1_bias = MadTurtle_MTF_BiasFromSMA(state.d1_sma_fast, state.d1_sma_slow); state.d1_updated = now; } } //+------------------------------------------------------------------+ //| Check if MTF confirmation allows a BUY | //+------------------------------------------------------------------+ bool MadTurtle_MTF_ConfirmBuy(const MadTurtleMTFState &state) { if(state.h4_bias != ORDER_TYPE_BUY) return false; if(state.d1_bias == ORDER_TYPE_SELL) return false; if(state.h4_rsi > 75.0) return false; if(state.d1_rsi > 75.0) return false; if(state.h4_macd < 0 && state.d1_sma_fast < state.d1_sma_slow) return false; return true; } //+------------------------------------------------------------------+ //| Check if MTF confirmation allows a SELL | //+------------------------------------------------------------------+ bool MadTurtle_MTF_ConfirmSell(const MadTurtleMTFState &state) { if(state.h4_bias != ORDER_TYPE_SELL) return false; if(state.d1_bias == ORDER_TYPE_BUY) return false; if(state.h4_rsi < 25.0) return false; if(state.d1_rsi < 25.0) return false; if(state.h4_macd > 0 && state.d1_sma_fast > state.d1_sma_slow) return false; return true; } #endif // MADTURTLE_MTF