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
This commit is contained in:
2026-03-22 10:35:22 -04:00
parent 86fa4b2bcb
commit e2d42b3015

View File

@@ -27,6 +27,14 @@ input group "=== Filters ==="
input bool InpUseTrendFilter = false; // Use MA trend filter (disable for more trades) input bool InpUseTrendFilter = false; // Use MA trend filter (disable for more trades)
input int InpTrendMAPeriod = 50; // Trend MA period 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 group "=== EA Settings ==="
input ulong InpMagicNumber = 777777; // Magic number input ulong InpMagicNumber = 777777; // Magic number
input int InpSlippage = 3; // Max slippage input int InpSlippage = 3; // Max slippage
@@ -35,6 +43,8 @@ input bool InpDebugMode = true; // Print debug info
//--- Global Variables //--- Global Variables
CTrade Trade; CTrade Trade;
int TrendMAHandle; int TrendMAHandle;
int ATRHandle;
int ADXHandle;
datetime lastBarTime = 0; datetime lastBarTime = 0;
int totalBuyPositions = 0; int totalBuyPositions = 0;
@@ -54,14 +64,22 @@ int OnInit()
if(InpUseTrendFilter) if(InpUseTrendFilter)
TrendMAHandle = iMA(_Symbol, _Period, InpTrendMAPeriod, 0, MODE_SMA, PRICE_CLOSE); 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); lastBarTime = iTime(_Symbol, _Period, 0);
Print("=== MultiSignal Confluence EA v1.11 Initialized ==="); Print("=== MultiSignal Confluence EA v1.12 Initialized ===");
Print("Symbol: ", _Symbol); Print("Symbol: ", _Symbol);
Print("Magic: ", InpMagicNumber); Print("Magic: ", InpMagicNumber);
Print("Min Confluence: ", InpMinConfluence); Print("Min Confluence: ", InpMinConfluence);
Print("Min Strength: ", InpMinStrength); 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!"); Print("This EA trades DIRECTLY - no external indicator needed!");
return(INIT_SUCCEEDED); return(INIT_SUCCEEDED);
@@ -75,6 +93,12 @@ void OnDeinit(const int reason)
if(TrendMAHandle != INVALID_HANDLE) if(TrendMAHandle != INVALID_HANDLE)
IndicatorRelease(TrendMAHandle); IndicatorRelease(TrendMAHandle);
if(ATRHandle != INVALID_HANDLE)
IndicatorRelease(ATRHandle);
if(ADXHandle != INVALID_HANDLE)
IndicatorRelease(ADXHandle);
Print("EA Deinitialized for ", _Symbol); Print("EA Deinitialized for ", _Symbol);
} }
@@ -170,6 +194,67 @@ bool CheckTrendFilter(int signalType)
return true; 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 | //| Calculate Pivots |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -527,6 +612,10 @@ void OnTick()
return; return;
} }
// Check volatility filter (prevents trading in narrow bands / choppy markets)
if(!CheckVolatilityFilter())
return;
// BUY Signal // BUY Signal
if(buyCount >= InpMinConfluence && (!InpRequireAllAgree || sellCount == 0)) if(buyCount >= InpMinConfluence && (!InpRequireAllAgree || sellCount == 0))
{ {