//+------------------------------------------------------------------+ //| BB_Divergence_v2.mq4 | //| Copyright 2018. BUREAL.RU, Bureal | //| http://www.bureal.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2018. BUREAL.RU, Bureal" #property link "http://www.bureal.ru" #property description "Bolinger Band Divergence Indicator" #property version "3.10" #property strict //---- #property indicator_chart_window //#property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 clrDarkGreen #property indicator_color2 clrMaroon //---- #define arrowsDisplacement 0.0001 //---- input parameters sinput string separator1 = " BB Settings "; //- input int Bands_period = 20; // Bands Period input double Bands_deviation = 2; // Band Deviation input int BarMax = 50; // Bar Max input int BarMin = 5; // Bar Min sinput string separator2 = " Indicator Settings "; //- input bool displayAlert = true; // Display Alert input bool displayHiddenDiv = true; // Display Hidden Div input bool alertsON = false; // Alert //---- buffers double PercentBB[]; double signal[]; double bbUP[]; double bbDN[]; //---- static datetime lastAlertTimePk; // last alert on a Peak static datetime lastAlertTimeTr; // last alert on a Trough int vBars = 0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit(){ IndicatorBuffers(4); SetIndexStyle(0, DRAW_ARROW);SetIndexBuffer(0,bbUP);SetIndexArrow(0, 233); SetIndexStyle(1, DRAW_ARROW);SetIndexBuffer(1,bbDN);SetIndexArrow(1, 234); SetIndexStyle(2, DRAW_NONE);SetIndexBuffer(2, PercentBB); SetIndexStyle(3, DRAW_NONE);SetIndexDrawBegin(3, Bands_period); IndicatorDigits((int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS)+2); IndicatorShortName("BB_Divergence(" + IntegerToString(Bands_period) + ")"); vBars = (Bars - Bands_period); ArrayInitialize(PercentBB,0); ArrayInitialize(signal,0); ArrayInitialize(bbUP,0); ArrayInitialize(bbDN,0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit(){ for(int i = ObjectsTotal() - 1; i >= 0; i--){ string label = ObjectName(i); if(StringSubstr(label, 0, 13) != "BB_Divergence")continue; ObjectDelete(label); } return(0);} //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start(){ vBars = (Bars - Bands_period); int countedBars = IndicatorCounted()-Bands_period; if(countedBars < 0)countedBars = 0; CalculateIndicator(countedBars); return(0);} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CalculateIndicator(int countedBars){ for (int i = Bars - countedBars; i >= 0; i--){ if(i BarMax || dist < BarMin)return; if(PercentBB[currentTrough] > PercentBB[lastTrough] && Low[currentTrough] < Low[lastTrough]){ bbUP[currentTrough]=Low[currentTrough]; if(displayAlert == true)DisplayAlert("BB Classical bullish divergence on: ", currentTrough, False); // was not a Peak } if(PercentBB[currentTrough] < PercentBB[lastTrough] && Low[currentTrough] > Low[lastTrough]){ bbUP[currentTrough]=Low[currentTrough]; if(displayAlert == true && displayHiddenDiv == true)DisplayAlert("BB Hidden bullish divergence on: ", currentTrough,False); // was not a Peak } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CatchBearishDivergence(int shift){ if(IsIndicatorPeak(shift) == false)return; int currentPeak = shift; int lastPeak = GetIndicatorLastPeak(shift); if(lastPeak<0)return; int dist = lastPeak-currentPeak; if(dist > BarMax || dist < BarMin)return; if(PercentBB[currentPeak] < PercentBB[lastPeak] && High[currentPeak] > High[lastPeak]){ bbDN[currentPeak]=High[currentPeak]; if(displayAlert == true) DisplayAlert("BB Classical bearish divergence on: ", currentPeak, True); // was a Peak } if(PercentBB[currentPeak] > PercentBB[lastPeak] && High[currentPeak] < High[lastPeak]){ bbDN[currentPeak]=High[currentPeak]; if (displayAlert == true && displayHiddenDiv == true)DisplayAlert("BB Hidden bearish divergence on: ", currentPeak, True); // was a Peak } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsIndicatorPeak(int shift){ if(PercentBB[shift] >= PercentBB[shift+1] && PercentBB[shift] > PercentBB[shift+2] && PercentBB[shift] > PercentBB[shift-1])return(true); return(false);} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsIndicatorTrough(int shift){ if(PercentBB[shift] <= PercentBB[shift+1] && PercentBB[shift] < PercentBB[shift+2] && PercentBB[shift] < PercentBB[shift-1])return(true); return(false);} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetIndicatorLastPeak(int shift){ for(int i = shift+4; i < vBars; i++){ for(int j = i; j < vBars; j++){ if(PercentBB[j] >= PercentBB[j+1] && PercentBB[j] > PercentBB[j+2] && PercentBB[j] >= PercentBB[j-1] && PercentBB[j] > PercentBB[j-2])return(j); } } return(-1);} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetIndicatorLastTrough(int shift){ for(int i = shift+4; i < vBars;i++){ for(int j = i; j < vBars; j++){ if(PercentBB[j] <= PercentBB[j+1] && PercentBB[j] < PercentBB[j+2] && PercentBB[j] <= PercentBB[j-1] && PercentBB[j] < PercentBB[j-2])return(j); } } return(-1);} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DisplayAlert(string message, int shift, bool peak){ if(alertsON){ if (peak){ if(shift <= 2 && Time[shift] != lastAlertTimePk){ lastAlertTimePk = Time[shift]; Alert(message, Symbol(), " , ", Period(), " minutes chart"); } } // was a Peak if (!peak){ if(shift <= 2 && Time[shift] != lastAlertTimeTr){ lastAlertTimeTr = Time[shift]; Alert(message, Symbol(), " , ", Period(), " minutes chart"); } } // not a Peak } }