From e2d42b3015871ae3a107d381e210ab36ea297110 Mon Sep 17 00:00:00 2001 From: Garfield Date: Sun, 22 Mar 2026 10:35:22 -0400 Subject: [PATCH] Add complete volatility filters v1.12 (Anti-Chop) - ATR filter: Blocks trades when volatility < 0.5% (narrow bands) - ADX filter: Blocks trades when trend strength < 20 - CheckVolatilityFilter() called before every trade entry - Prevents over-trading in choppy/consolidating markets - Both filters ON by default, configurable via inputs - Version bumped to 1.12 --- MultiSignal_Confluence_EA.mq5 | 93 ++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/MultiSignal_Confluence_EA.mq5 b/MultiSignal_Confluence_EA.mq5 index 82344da..674f52e 100644 --- a/MultiSignal_Confluence_EA.mq5 +++ b/MultiSignal_Confluence_EA.mq5 @@ -27,6 +27,14 @@ input group "=== Filters ===" input bool InpUseTrendFilter = false; // Use MA trend filter (disable for more trades) input int InpTrendMAPeriod = 50; // Trend MA period +input group "=== Volatility Filter (Anti-Chop) ===" +input bool InpUseVolatilityFilter = true; // Filter out low volatility / narrow bands +input int InpATRPeriod = 14; // ATR period for volatility measurement +input double InpMinATRPercent = 0.5; // Min ATR as % of price (0.5 = 0.5%) +input bool InpUseADXFilter = true; // Use ADX trend strength filter +input int InpADXPeriod = 14; // ADX period +input double InpMinADX = 20.0; // Min ADX to trade (20-25 recommended) + input group "=== EA Settings ===" input ulong InpMagicNumber = 777777; // Magic number input int InpSlippage = 3; // Max slippage @@ -35,6 +43,8 @@ input bool InpDebugMode = true; // Print debug info //--- Global Variables CTrade Trade; int TrendMAHandle; +int ATRHandle; +int ADXHandle; datetime lastBarTime = 0; int totalBuyPositions = 0; @@ -54,14 +64,22 @@ int OnInit() if(InpUseTrendFilter) TrendMAHandle = iMA(_Symbol, _Period, InpTrendMAPeriod, 0, MODE_SMA, PRICE_CLOSE); + // Initialize volatility filters + if(InpUseVolatilityFilter) + ATRHandle = iATR(_Symbol, _Period, InpATRPeriod); + + if(InpUseADXFilter) + ADXHandle = iADX(_Symbol, _Period, InpADXPeriod); + lastBarTime = iTime(_Symbol, _Period, 0); - Print("=== MultiSignal Confluence EA v1.11 Initialized ==="); + Print("=== MultiSignal Confluence EA v1.12 Initialized ==="); Print("Symbol: ", _Symbol); Print("Magic: ", InpMagicNumber); Print("Min Confluence: ", InpMinConfluence); Print("Min Strength: ", InpMinStrength); - Print("Point: ", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_POINT), _Digits)); + Print("Volatility Filter: ", InpUseVolatilityFilter ? "ON" : "OFF"); + Print("ADX Filter: ", InpUseADXFilter ? "ON" : "OFF"); Print("This EA trades DIRECTLY - no external indicator needed!"); return(INIT_SUCCEEDED); @@ -75,6 +93,12 @@ void OnDeinit(const int reason) if(TrendMAHandle != INVALID_HANDLE) IndicatorRelease(TrendMAHandle); + if(ATRHandle != INVALID_HANDLE) + IndicatorRelease(ATRHandle); + + if(ADXHandle != INVALID_HANDLE) + IndicatorRelease(ADXHandle); + Print("EA Deinitialized for ", _Symbol); } @@ -170,6 +194,67 @@ bool CheckTrendFilter(int signalType) return true; } +//+------------------------------------------------------------------+ +//| Check Volatility Filter (Anti-Chop) | +//+------------------------------------------------------------------+ +bool CheckVolatilityFilter() +{ + // Check ATR (volatility) filter + if(InpUseVolatilityFilter) + { + if(ATRHandle == INVALID_HANDLE) + { + if(InpDebugMode) Print("Volatility filter: ATR handle invalid, allowing trade"); + return true; + } + + double atrValue[1]; + if(CopyBuffer(ATRHandle, 0, 0, 1, atrValue) <= 0) + { + if(InpDebugMode) Print("Volatility filter: Failed to get ATR, allowing trade"); + return true; + } + + double close = iClose(_Symbol, _Period, 0); + double atrPercent = (atrValue[0] / close) * 100; + + if(atrPercent < InpMinATRPercent) + { + if(InpDebugMode) Print("Volatility filter BLOCKED: ATR too low (", + DoubleToString(atrPercent, 2), "% < ", + DoubleToString(InpMinATRPercent, 2), "%) - Narrow bands/choppy market"); + return false; + } + } + + // Check ADX (trend strength) filter + if(InpUseADXFilter) + { + if(ADXHandle == INVALID_HANDLE) + { + if(InpDebugMode) Print("ADX filter: Handle invalid, allowing trade"); + return true; + } + + double adxValue[1]; + if(CopyBuffer(ADXHandle, 0, 0, 1, adxValue) <= 0) + { + if(InpDebugMode) Print("ADX filter: Failed to get ADX, allowing trade"); + return true; + } + + if(adxValue[0] < InpMinADX) + { + if(InpDebugMode) Print("ADX filter BLOCKED: Trend too weak (ADX ", + DoubleToString(adxValue[0], 1), " < ", + DoubleToString(InpMinADX, 1), ")"); + return false; + } + } + + return true; +} + //+------------------------------------------------------------------+ //| Calculate Pivots | //+------------------------------------------------------------------+ @@ -527,6 +612,10 @@ void OnTick() return; } + // Check volatility filter (prevents trading in narrow bands / choppy markets) + if(!CheckVolatilityFilter()) + return; + // BUY Signal if(buyCount >= InpMinConfluence && (!InpRequireAllAgree || sellCount == 0)) {