Extreme Price Filter
This is a filter to detect when the current price bar highs are at a local high extreme, or when current price bar lows are at a local low extreme.
The logic is:
High breach = high[i] > Local high extremum – ATR * multiplier
Low breach = low[i] < Local low extremum + ATR * multiplier
It uses two modes
1. Live bar: It will detect when the high or low of the current unclosed bar is breaching the extreme boundary
2. Closed bar only: It will only examine when closed bars have breached the extreme boundary, and this option might be more ideal for automation if the automated system only considers closed bars
Many entry signal based indicators and systems have no idea of extreme local highs and local lows. As such, they can signal a buy at an extreme high, or a sell at an extreme low. By trading these signals, you can fall into the classic Bull Trap or Bear Trap.
The purpose of this is therefore to help other signal indicators (or trading systems).
How to read it visually:
Red markers urge you not to trade a buy position on that price bar.
Blue markers urge you not to trade a sell position on that price bar.
EA usage:
input group "Extreme Price Filter" input bool use_ext_filter = false; // Use extreme price filter input int DonchianPeriod = 40; // Extreme channel period input int AtrPeriodExt = 14; // ATR period input double AtrMultiplier = 0.6; // ATR multiplier (inward band offset) input int InpMinBars = 0; // Minimum bars between breach zones input ENUM_BREACH_MODE InpBreachMode = BREACH_CLOSED; // Breach evaluation mode input int InpExtFilterBars = 10; // Bars after a sweep that still block entries int OnInit(){ ext_handle = iCustom(_Symbol, _Period, "::Indicators\Custom\Extreme Price Filter", DonchianPeriod, AtrPeriodExt, AtrMultiplier, InpMinBars, InpBreachMode, DrawObjects, MaxCircleBars, CircleAtrFactor, CircleWidthBars, CircleColorUp, CircleColorDown); if(ext_handle == INVALID_HANDLE) { Print("Error creating handle for 'Extreme Price Filter.ex5': ", GetLastError()); return INIT_FAILED; } ArraySetAsSeries(extFilter, true); return INIT_SUCCEEDED; } bool ExtremeSweepDetected(const int side, const int bars) { int wanted = MathMax(bars, 1); int available = ArraySize(extFilter); int n = MathMin(wanted, available); if(n <= 0) return(false); for(int k = 0; k < n; k++) { if(extFilter[k] == (double)side) return(true); } return(false); } void OnTick(){ int ext_bars = MathMax(InpExtFilterBars, 1); if(CopyBuffer(dchannel_handle, 2, 0, ext_bars, extFilter) <= 0) { Print("Error copying extreme price filter buffer: ", GetLastError()); return; } bool ext_sweep_high = use_ext_filter && ExtremeSweepDetected(-1, InpExtFilterBars); bool ext_sweep_low = use_ext_filter && ExtremeSweepDetected( 1, InpExtFilterBars); if(myBuySignal && !ext_sweep_high) Buy... if(mySellSignal && !ext_sweep_low) Sell... }
