//+------------------------------------------------------------------+
//|                                 AllMACD Divergence_v2.6 600+.mq4 |
//|                                Copyright © 2016, TrendLaboratory |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                   E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, TrendLaboratory"
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property link      "http://newdigital-world.com/forum.php"


#property indicator_separate_window
#property indicator_buffers 7

#property indicator_color1 clrLimeGreen
#property indicator_color2 clrGreen
#property indicator_color3 clrRed
#property indicator_color4 clrMaroon
#property indicator_color5 clrDimGray
#property indicator_color6 clrYellow
#property indicator_color7 clrDimGray
#property indicator_width1 2
#property indicator_width2 1
#property indicator_width3 2
#property indicator_width4 1
#property indicator_width5 2
#property indicator_width6 1
#property indicator_style6 2  
#property indicator_width7 1

#property indicator_level1 0
#property indicator_levelcolor clrDimGray

enum ENUM_MA_MODE
{
   SMA,                 // Simple Moving Average
   EMA,                 // Exponential Moving Average
   Wilder,              // Wilder Exponential Moving Average
   LWMA,                // Linear Weighted Moving Average
   SineWMA,             // Sine Weighted Moving Average
   TriMA,               // Triangular Moving Average
   LSMA,                // Least Square Moving Average (or EPMA, Linear Regression Line)
   SMMA,                // Smoothed Moving Average
   HMA,                 // Hull Moving Average by A.Hull
   ZeroLagEMA,          // Zero-Lag Exponential Moving Average
   DEMA,                // Double Exponential Moving Average by P.Mulloy
   T3_basic,            // T3 by T.Tillson (original version)
   ITrend,              // Instantaneous Trendline by J.Ehlers
   Median,              // Moving Median
   REMA,                // Regularized EMA by C.Satchwell
   ILRS,                // Integral of Linear Regression Slope
   IE_2,                // Combination of LSMA and ILRS
   TriMAgen,            // Triangular Moving Average generalized by J.Ehlers
   VWMA,                // Volume Weighted Moving Average
   JSmooth,             // M.Jurik's Smoothing
   SMA_eq,              // Simplified SMA
   ALMA,                // Arnaud Legoux Moving Average
   TEMA,                // Triple Exponential Moving Average by P.Mulloy
   T3,                  // T3 by T.Tillson (correct version)
   Laguerre,            // Laguerre filter by J.Ehlers
   BF2P,                // Two-pole modified Butterworth filter by J.Ehlers
   BF3P,                // Three-pole modified Butterworth filter by J.Ehlers
   SuperSmu,            // SuperSmoother by J.Ehlers
   Decycler,            // Simple Decycler by J.Ehlers
   eVWMA                // Modified eVWMA
};   


enum ENUM_PRICE
{
   close,               // Close
   open,                // Open
   high,                // High
   low,                 // Low
   median,              // Median
   typical,             // Typical
   weightedClose,       // Weighted Close
   heikenAshiClose,     // Heiken Ashi Close
   heikenAshiOpen,      // Heiken Ashi Open
   heikenAshiHigh,      // Heiken Ashi High   
   heikenAshiLow,       // Heiken Ashi Low
   heikenAshiMedian,    // Heiken Ashi Median
   heikenAshiTypical,   // Heiken Ashi Typical
   heikenAshiWeighted   // Heiken Ashi Weighted Close   
};


#define pi 3.14159265358979323846



//---- 

input ENUM_TIMEFRAMES   TimeFrame               =        0;       // TimeFrame
input ENUM_PRICE        FastPrice               =        0;       // Fast MA Price
input int               FastLength              =       12;       // Fast MA Period 
input ENUM_MA_MODE      FastMode                =        1;       // Fast MA Method
input ENUM_PRICE        SlowPrice               =        0;       // Slow MA Price
input int               SlowLength              =       26;       // Slow MA Period
input ENUM_MA_MODE      SlowMode                =        1;       // Slow MA Mode
input int               SignalLength            =        9;       // Signal Period  
input ENUM_MA_MODE      SignalMode              =        0;       // Signal MA Mode
input bool              ShowOscillator          =    false;       // Show Oscillator   
input int               CountBars               =        0;       // Number of bars counted: 0-all bars 

input string            Divergence              = "=== Divergence ===";
input bool              ShowRegularDivergence   =     true;       // Show Regular Divergence
input bool              ShowHiddenDivergence    =     true;       // Show Hidden Divergence
input bool              DivergenceOnOscillator  =    false;       // Divergence On Oscillator
input ENUM_PRICE        DivergencePrice         =        0;       // Divergence Price
input bool              UseHighLow              =     true;       // Use High/Low Prices
input int               PivotStrength           =        1;       // Pivot Strength(Fractal Size) 
input int               PivotOccurrence         =        1;       // Pivot Occurrence in bars
input int               LookBackPivots          =        1;       // LookBack Period for Pivots
input int               MinBarsBetweenPivots    =        5;       // Min Distance Between Pivots in bars
input int               MaxBarsBetweenPivots    =       50;       // Max Distance Between Pivots in bars
input color	            BullishDivergenceColor  = clrDeepSkyBlue;
input color	            BearishDivergenceColor  = clrLightCoral;
input ENUM_LINE_STYLE   RegularDivergenceStyle  =        0;
input ENUM_LINE_STYLE   HiddenDivergenceStyle   =        2;
input int               RegularDivergenceWidth  =        2;
input int               HiddenDivergenceWidth   =        0;
input string            UniqueName              = "allmacd";

input string            Arrows                  = "=== Arrows ===";
input bool              ShowArrows              =     true;       // Show Arrows    
input int               ArrowSize               =       11;
input string            ArrowFontName           = "Wingdings";
input int               ArrowBuyCode            =      233;
input int               ArrowSellCode           =      234;
input color	            UpArrowColor            = clrDeepSkyBlue;
input color	            DnArrowColor            = clrLightCoral;

input string            Alerts                  = "=== Alerts & Emails ===";
input bool              AlertOn                 =    false;
input bool              DivergenceAlertOn       =     true;
input int               AlertShift              =        1;       // Alert Shift:0-current bar,1-previous bar
input int               SoundsNumber            =        5;       // Number of sounds after Signal
input int               SoundsPause             =        5;       // Pause in sec between sounds 
input string            UpTrendSound            = "alert.wav";
input string            DnTrendSound            = "alert2.wav";
input bool              EmailOn                 =    false;       
input int               EmailsNumber            =        1;          
input bool              PushNotificationOn      =    false;


double uprising[];
double upfalling[];
double dnrising[];
double dnfalling[];
double difference[];
double signal[];
double oscillator[];
double trend[];
double diversignal[];
double fastprice[];
double slowprice[];
double diverprice[];


int      timeframe, cBars, draw_begin, fastsize, slowsize, signalsize;
string   IndicatorName, TF, short_name;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
{
   timeframe = TimeFrame;
   if(timeframe <= Period()) timeframe = Period(); 
   TF = tf(timeframe);
   
   IndicatorDigits(7);
//----    
   IndicatorBuffers(12);
      
   SetIndexBuffer( 0,   uprising); SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer( 1,  upfalling); SetIndexStyle(3,DRAW_HISTOGRAM);
   SetIndexBuffer( 2,   dnrising); SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer( 3,  dnfalling); SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer( 4, difference); SetIndexStyle(4,DRAW_LINE);
   SetIndexBuffer( 5,     signal); SetIndexStyle(5,DRAW_LINE); 
   SetIndexBuffer( 6, oscillator); SetIndexStyle(6,DRAW_LINE);
   SetIndexBuffer( 7,      trend);
   SetIndexBuffer( 8,diversignal);
   SetIndexBuffer( 9,  fastprice);
   SetIndexBuffer(10,  slowprice);
   SetIndexBuffer(11, diverprice);
//----   
   
   fastsize   = averageSize(FastMode  );
   slowsize   = averageSize(SlowMode  );
   signalsize = averageSize(SignalMode);  
   
   IndicatorName = WindowExpertName();
   short_name    = IndicatorName+"["+TF+"]("+FastPrice+","+FastLength+","+FastMode+","+SlowPrice+","+SlowLength+","+SlowMode+","+SignalLength+","+SignalMode+")";
   IndicatorShortName(short_name);
   
   SetIndexLabel(0,"UpTrend Rising");
   SetIndexLabel(1,"UpTrend Falling");
   SetIndexLabel(2,"DnTrend Rising");
   SetIndexLabel(3,"DnTrend Falling");
   SetIndexLabel(4,"AllMACD");   
   SetIndexLabel(5,"AllMACD Signal");
   SetIndexLabel(6,"AllMACD Oscillator");  
//----         
   if(CountBars == 0) cBars = iBars(NULL,timeframe)*timeframe/Period() - MathMax(FastLength,SlowLength) - SignalLength; else cBars = CountBars*timeframe/Period();
  
   draw_begin = Bars - cBars;
   
   SetIndexDrawBegin(0,draw_begin);
   SetIndexDrawBegin(1,draw_begin);
   SetIndexDrawBegin(2,draw_begin);
   SetIndexDrawBegin(3,draw_begin);
   SetIndexDrawBegin(4,draw_begin);
   SetIndexDrawBegin(5,draw_begin);
   SetIndexDrawBegin(6,draw_begin);
//----   
   ArrayResize(tmp,MathMax(fastsize,MathMax(slowsize,signalsize)));
   
   ArrayResize(upPivot    ,LookBackPivots+1);
   ArrayResize(dnPivot    ,LookBackPivots+1); 
   ArrayResize(upPivotTime,LookBackPivots+1);
   ArrayResize(dnPivotTime,LookBackPivots+1); 
   ArrayResize(upbar      ,LookBackPivots+1); 
   ArrayResize(dnbar      ,LookBackPivots+1); 
   
   return(0);
}
//-----
int deinit()
{
   deleteObj(UniqueName);
   Comment("");
   return(0);
}


//+------------------------------------------------------------------+
//|  AllMACD Divergence_v2.6 600+                                    |
//+------------------------------------------------------------------+

int start()
{
   int shift, limit, counted_bars = IndicatorCounted();
      
   if(counted_bars > 0) limit = Bars - counted_bars - 1;
   if(counted_bars < 0) return(0);
   if(counted_bars < 1)
   { 
   limit = Bars - 1;   
      for(int i=limit;i>=0;i--) 
      {
      uprising  [i] = EMPTY_VALUE;
      upfalling [i] = EMPTY_VALUE;
      dnrising  [i] = EMPTY_VALUE;
      dnfalling [i] = EMPTY_VALUE;
      signal    [i] = EMPTY_VALUE;
      difference[i] = EMPTY_VALUE;
      oscillator[i] = EMPTY_VALUE;
      }
   }   
  
   int window = WindowFind(short_name);
   
   if(timeframe != Period())
   {
   limit = MathMax(limit,timeframe/Period());   
      
      for(shift = 0;shift < limit;shift++) 
      {	
      int y = iBarShift(NULL,timeframe,Time[shift]);
	   
	   
	   uprising[shift]   = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,0,y);
      
      upfalling[shift]  = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,1,y);
      
	   dnrising[shift]   = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,2,y);
      
      dnfalling[shift]  = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,3,y);
	    
	   difference[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,4,y);
	   
	   signal[shift]     = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,5,y);
	   
	   oscillator[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,FastPrice,FastLength,FastMode,SlowPrice,SlowLength,SlowMode,SignalLength,SignalMode,ShowOscillator,CountBars,
	                              "",ShowRegularDivergence,ShowHiddenDivergence,DivergenceOnOscillator,DivergencePrice,UseHighLow,PivotStrength,PivotOccurrence,LookBackPivots,
	                              MinBarsBetweenPivots,MaxBarsBetweenPivots,BullishDivergenceColor,BearishDivergenceColor,RegularDivergenceStyle,HiddenDivergenceStyle,RegularDivergenceWidth,HiddenDivergenceWidth,UniqueName,
                                 "",ShowArrows,ArrowSize,ArrowFontName,ArrowBuyCode,ArrowSellCode,UpArrowColor,DnArrowColor,
	                              "",AlertOn,DivergenceAlertOn,AlertShift,SoundsNumber,SoundsPause,UpTrendSound,DnTrendSound,EmailOn,EmailsNumber,PushNotificationOn,6,y);
	   }
	   
	   if(CountBars > 0)
      {
      SetIndexDrawBegin(0,Bars - cBars);   
      SetIndexDrawBegin(1,Bars - cBars);
      SetIndexDrawBegin(2,Bars - cBars);
      SetIndexDrawBegin(3,Bars - cBars);   
      SetIndexDrawBegin(4,Bars - cBars);
      SetIndexDrawBegin(5,Bars - cBars);
      SetIndexDrawBegin(6,Bars - cBars);
      }   
	   
	
	return(0);
	}
   else 
   for(shift=limit;shift>=0;shift--) 
   {
      if((int)FastPrice <= 6) fastprice[shift] = iMA(NULL,0,1,0,0,(int)FastPrice,shift);   
      else
      if((int)FastPrice > 6 && (int)FastPrice <= 13) fastprice[shift] = HeikenAshi(0,(int)FastPrice-7,cBars,shift);
   
   double fastMA = allAveragesOnArray(0,fastprice,FastLength,(int)FastMode,fastsize,cBars +  + MathMax(FastLength,SlowLength),shift); 
   
      if((int)SlowPrice <= 6) slowprice[shift] = iMA(NULL,0,1,0,0,(int)SlowPrice,shift);   
      else
      if((int)SlowPrice > 6 && (int)SlowPrice <= 13) slowprice[shift] = HeikenAshi(1,(int)SlowPrice-7,cBars,shift);
   
   double slowMA = allAveragesOnArray(1,slowprice,SlowLength,(int)SlowMode,slowsize,cBars + MathMax(FastLength,SlowLength),shift); 
   
   difference[shift] = fastMA - slowMA;
   
      if(SignalLength > 0) 
      {
      if(SignalLength >  1) signal[shift] = allAveragesOnArray(2,difference,SignalLength,SignalMode,signalsize,cBars + MathMax(FastLength,SlowLength) + SignalLength,shift);
      if(SignalLength == 1) signal[shift] = difference[shift+1];
      }
   
       
   if(ShowOscillator) oscillator[shift] = difference[shift] - signal[shift]; else oscillator[shift] = EMPTY_VALUE;
   
   uprising[shift]  = EMPTY_VALUE;
   upfalling[shift] = EMPTY_VALUE;
   dnrising[shift]  = EMPTY_VALUE;
   dnfalling[shift] = EMPTY_VALUE;
   
   
   trend[shift] = trend[shift+1];
   
      if(!ShowOscillator)
      {    
      if(difference[shift] > difference[shift+1]) trend[shift] =  1;
      if(difference[shift] < difference[shift+1]) trend[shift] = -1;
   
         if(difference[shift] > 0)
            if(trend[shift] > 0) uprising[shift] = difference[shift];
            else  upfalling[shift] = difference[shift];
         else               
            if(trend[shift] > 0) dnfalling[shift] = difference[shift];
            else  dnrising[shift] = difference[shift];
      }
      else
      {
      if(oscillator[shift] > oscillator[shift+1]) trend[shift] =  1;
      if(oscillator[shift] < oscillator[shift+1]) trend[shift] = -1;
   
         if(oscillator[shift] > 0)
            if(trend[shift] > 0) uprising[shift] = oscillator[shift];
            else  upfalling[shift] = oscillator[shift];
         else               
            if(trend[shift] > 0) dnfalling[shift] = oscillator[shift];
            else  dnrising[shift] = oscillator[shift];
      }     
   
      
      if(ShowRegularDivergence || ShowHiddenDivergence)
      {
         if((int)DivergencePrice <= 6) diverprice[shift] = iMA(NULL,0,1,0,0,(int)DivergencePrice,shift);   
         else
         if((int)DivergencePrice > 6 && (int)DivergencePrice <= 13) diverprice[shift] = HeikenAshi(2,(int)DivergencePrice-7,cBars,shift);
   
         if(!DivergenceOnOscillator) 
            divergenceBuilder(ShowRegularDivergence,ShowHiddenDivergence,window,difference,diverprice,UseHighLow,PivotStrength,
                              PivotOccurrence,LookBackPivots,MinBarsBetweenPivots,MaxBarsBetweenPivots,ShowArrows,shift);    
         else
            divergenceBuilder(ShowRegularDivergence,ShowHiddenDivergence,window,oscillator,diverprice,UseHighLow,PivotStrength,
                              PivotOccurrence,LookBackPivots,MinBarsBetweenPivots,MaxBarsBetweenPivots,ShowArrows,shift);
      }
   }
  
   if(AlertOn || EmailOn || PushNotificationOn)
   {
      if(SignalLength > 0)
      {
      bool upsignal = signal[AlertShift] > difference[AlertShift] && signal[AlertShift+1] <= difference[AlertShift+1];
      bool dnsignal = signal[AlertShift] < difference[AlertShift] && signal[AlertShift+1] >= difference[AlertShift+1];
      }
      else
      {
      upsignal = trend[AlertShift] > 0 && trend[AlertShift+1] <= 0;
      dnsignal = trend[AlertShift] < 0 && trend[AlertShift+1] >= 0;
      }
      
      if(DivergenceAlertOn)
      {
      bool upregular = diversignal[AlertShift] == 1 && diversignal[AlertShift+1] != 1;
      bool dnregular = diversignal[AlertShift] ==-1 && diversignal[AlertShift+1] !=-1;
      bool uphidden  = diversignal[AlertShift] == 2 && diversignal[AlertShift+1] != 2;
      bool dnhidden  = diversignal[AlertShift] ==-2 && diversignal[AlertShift+1] !=-2;
      }
      
                  
      if(upsignal || dnsignal || upregular || dnregular || uphidden || dnhidden)
      {
         if(isNewBar(timeframe))
         {
            if(AlertOn)
            {
            BoxAlert(upsignal ," : BUY Signal @ " +DoubleToStr(Close[AlertShift],Digits));   
            BoxAlert(dnsignal ," : SELL Signal @ "+DoubleToStr(Close[AlertShift],Digits)); 
            BoxAlert(upregular," : Bullish Regular Divergence @ " +DoubleToStr(Close[AlertShift],Digits));   
            BoxAlert(dnregular," : Bearish Regular Divergence @ " +DoubleToStr(Close[AlertShift],Digits)); 
            BoxAlert(uphidden ," : Bullish Hidden Divergence @ "  +DoubleToStr(Close[AlertShift],Digits));   
            BoxAlert(dnhidden ," : Bearish Hidden Divergence @ "  +DoubleToStr(Close[AlertShift],Digits)); 
            }
                   
            if(EmailOn)
            {
            EmailAlert(upsignal ,"BUY" ," : BUY Signal @ " +DoubleToStr(Close[AlertShift],Digits),EmailsNumber); 
            EmailAlert(dnsignal ,"SELL"," : SELL Signal @ "+DoubleToStr(Close[AlertShift],Digits),EmailsNumber); 
            EmailAlert(upregular,"BUY" ," : Bullish Regular Divergence @ " +DoubleToStr(Close[AlertShift],Digits),EmailsNumber); 
            EmailAlert(dnregular,"SELL"," : Bearish Regular Divergence @ " +DoubleToStr(Close[AlertShift],Digits),EmailsNumber); 
            EmailAlert(uphidden ,"BUY" ," : Bullish Hidden Divergence @ "  +DoubleToStr(Close[AlertShift],Digits),EmailsNumber); 
            EmailAlert(dnhidden ,"SELL"," : Bearish Hidden Divergence @ "  +DoubleToStr(Close[AlertShift],Digits),EmailsNumber); 
            }
         
            if(PushNotificationOn)
            {
            PushAlert(upsignal ," : BUY Signal @ " +DoubleToStr(Close[AlertShift],Digits));   
            PushAlert(dnsignal ," : SELL Signal @ "+DoubleToStr(Close[AlertShift],Digits)); 
            PushAlert(upregular," : Bullish Regular Divergence @ " +DoubleToStr(Close[AlertShift],Digits));   
            PushAlert(dnregular," : Bearish Regular Divergence @ " +DoubleToStr(Close[AlertShift],Digits)); 
            PushAlert(uphidden ," : Bullish Hidden Divergence @ "  +DoubleToStr(Close[AlertShift],Digits));   
            PushAlert(dnhidden ," : Bearish Hidden Divergence @ "  +DoubleToStr(Close[AlertShift],Digits)); 
            }
         }
         else
         {
            if(AlertOn)
            {
            WarningSound(upsignal ,SoundsNumber,SoundsPause,UpTrendSound,Time[AlertShift]);
            WarningSound(dnsignal ,SoundsNumber,SoundsPause,DnTrendSound,Time[AlertShift]);
            WarningSound(upregular,SoundsNumber,SoundsPause,UpTrendSound,Time[AlertShift]);
            WarningSound(dnregular,SoundsNumber,SoundsPause,DnTrendSound,Time[AlertShift]);
            WarningSound(uphidden ,SoundsNumber,SoundsPause,UpTrendSound,Time[AlertShift]);
            WarningSound(dnhidden ,SoundsNumber,SoundsPause,DnTrendSound,Time[AlertShift]);
            }
         }     
      }
   }
   
   
   if(CountBars > 0)
   {
   SetIndexDrawBegin(0,Bars - cBars);   
   SetIndexDrawBegin(1,Bars - cBars);
   SetIndexDrawBegin(2,Bars - cBars);
   SetIndexDrawBegin(3,Bars - cBars);   
   SetIndexDrawBegin(4,Bars - cBars);
   SetIndexDrawBegin(5,Bars - cBars);
   SetIndexDrawBegin(6,Bars - cBars);
   }   
   
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int      upbar[][2], dnbar[][2];
double   upPivot[][2], dnPivot[][2], prevupPivot, prevdnPivot;
datetime upPivotTime[][2], dnPivotTime[][2], prevupTime, prevdnTime;
  
void divergenceBuilder(bool regular,bool hidden,int win,double& osc[],double& price[],bool hilo,int size,int occur,int lookback,int minbars,int maxbars,bool arrows,int bar)
{
   int i, hhbar1, hhbar2, llbar1, llbar2;
   double hiArray[], loArray[], hhprice1, hhprice2, llprice1, llprice2;
   string up_osc, up_line, dn_osc, dn_line, up_arrow, dn_arrow;
   datetime uppivtime = 0, dnpivtime = 0;
   
   if(bar < cBars) 
   {   
   ArrayResize(hiArray,2*size+1);
   ArrayResize(loArray,2*size+1);
      
      for(int j=0;j<2*size+1;j++)
      { 
      hiArray[j] = osc[bar+j]; 
      loArray[j] = hiArray[j]; 
      }   
   
         
   double up = getPivots(0,hiArray,size,0,bar,uppivtime);
              
      if(up != EMPTY_VALUE)
      {
      upPivot[0][0]     = up;
      upPivotTime[0][0] = uppivtime;
      upbar[0][0]       = Bars - 1 - iBarShift(NULL,0,upPivotTime[0][0]);
      }

   double dn = getPivots(1,loArray,size,0,bar,dnpivtime);
              
      if(dn != EMPTY_VALUE)
      {
      dnPivot[0][0]     = dn;
      dnPivotTime[0][0] = dnpivtime;
      dnbar[0][0]       = Bars - 1 - iBarShift(NULL,0,dnPivotTime[0][0]);
      }   
        
      
      if(up != EMPTY_VALUE && uppivtime == Time[bar+size])
      {
         for(i=1;i<=lookback;i++)
         {
         upPivot[i][0]     = upPivot[i-1][1]; 
         upPivotTime[i][0] = upPivotTime[i-1][1]; 
         upbar[i][0]       = upbar[i-1][1];
         }
      if(bar == 0) prevupTime = uppivtime;
      }
      
      if(bar == 0 && up == EMPTY_VALUE && prevupTime == Time[bar+size])
      {
         for(i=0;i<=lookback;i++)
         {
         upPivot[i][0]     = upPivot[i][1]; 
         upPivotTime[i][0] = upPivotTime[i][1]; 
         upbar[i][0]       = upbar[i][1];
         }
         
         
         for(i=0;i<=lookback;i++)
         {
         up_osc   = UniqueName + " upOscReg " + i + " " + TimeToStr(Time[bar+size]);
         up_line  = UniqueName + " upLinReg " + i + " " + TimeToStr(Time[bar+size]);   
         dn_arrow = UniqueName + " dnArrReg " + i + " " + TimeToStr(Time[bar]); 
            
         if(arrows && ObjectFind(dn_arrow) >= 0) ObjectDelete(dn_arrow); 
         if(ObjectFind(up_osc )  >= 0) ObjectDelete(up_osc ); 	   
         if(ObjectFind(up_line)  >= 0) ObjectDelete(up_line);    
         }
         
         for(i=0;i<=lookback;i++)
         {
         up_osc   = UniqueName + " upOscHid " + i + " " + TimeToStr(Time[bar+size]);
         up_line  = UniqueName + " upLinHid " + i + " " + TimeToStr(Time[bar+size]);   
         dn_arrow = UniqueName + " dnArrHid " + i + " " + TimeToStr(Time[bar]);    
            
         if(arrows && ObjectFind(dn_arrow) >= 0) ObjectDelete(dn_arrow); 
         if(ObjectFind(up_osc )  >= 0) ObjectDelete(up_osc ); 	   
         if(ObjectFind(up_line)  >= 0) ObjectDelete(up_line);     
         }
      }
              
      if(upPivotTime[0][0] == Time[bar+size+1])
      {
         for(i=0;i<=lookback;i++)
         {
         upPivot[i][1]     = upPivot[i][0]; 
         upPivotTime[i][1] = upPivotTime[i][0]; 
         upbar[i][1]       = upbar[i][0];
         }           
      }
      
      if(dn != EMPTY_VALUE && dnpivtime == Time[bar+size])
      {
         for(i=1;i<=lookback;i++)
         {
         dnPivot[i][0]     = dnPivot[i-1][1]; 
         dnPivotTime[i][0] = dnPivotTime[i-1][1]; 
         dnbar[i][0]       = dnbar[i-1][1];
         }
      if(bar == 0) prevdnTime = dnpivtime;
      }  
                        
      if(bar == 0 && dn == EMPTY_VALUE && prevdnTime == Time[bar+size])
      {
         for(i=0;i<=lookback;i++)
         {
         dnPivot[i][0]     = dnPivot[i][1]; 
         dnPivotTime[i][0] = dnPivotTime[i][1]; 
         dnbar[i][0]       = dnbar[i][1];
         }
         
         if(regular)
         {
            for(i=0;i<=lookback;i++)
            {
            dn_osc   = UniqueName + " dnOscReg " + i + " " + TimeToStr(Time[bar+size]);
            dn_line  = UniqueName + " dnLinReg " + i + " " + TimeToStr(Time[bar+size]);   
            up_arrow = UniqueName + " upArrReg " + i + " " + TimeToStr(Time[bar]);  
            
            if(arrows && ObjectFind(up_arrow) >= 0) ObjectDelete(up_arrow); 
            if(ObjectFind(dn_osc ) >= 0) ObjectDelete(dn_osc );   	   
            if(ObjectFind(dn_line) >= 0) ObjectDelete(dn_line); 
            }
         }
         
         if(hidden)
         {
            for(i=0;i<=lookback;i++)
            {
            dn_osc   = UniqueName + " dnOscHid " + i + " " + TimeToStr(Time[bar+size]);
            dn_line  = UniqueName + " dnLinHid " + i + " " + TimeToStr(Time[bar+size]);
            up_arrow = UniqueName + " upArrHid " + i + " " + TimeToStr(Time[bar]);    
             
            if(arrows && ObjectFind(up_arrow) >= 0) ObjectDelete(up_arrow); 
            if(ObjectFind(dn_osc ) >= 0) ObjectDelete(dn_osc );
            if(ObjectFind(dn_line) >= 0) ObjectDelete(dn_line); 
            }
         }
      }
         
      if(dnPivotTime[0][0] == Time[bar+size+1])
      {
         for(i=0;i<=lookback;i++)
         {
         dnPivot[i][1]     = dnPivot[i][0]; 
         dnPivotTime[i][1] = dnPivotTime[i][0]; 
         dnbar[i][1]       = dnbar[i][0];
         }           
      }
   
   
      
      
   if(arrows) double gap = 0.5*MathCeil(iATR(NULL,0,14,bar+1)/Point);   
   
   diversignal[bar] = 0;
       
      if(regular)
      {
         if(dn != EMPTY_VALUE) 
         {
            for(i=0;i<=lookback;i++)
            {
            dn_osc   = UniqueName + " dnOscReg " + i + " " + TimeToStr(Time[bar+size]);
            dn_line  = UniqueName + " dnLinReg " + i + " " + TimeToStr(Time[bar+size]);   
            up_arrow = UniqueName + " upArrReg " + i + " " + TimeToStr(Time[bar]);  
               
               if(dnPivot[0][0] > dnPivot[i][0] && dnbar[0][0] - dnbar[i][0] > minbars && dnbar[0][0] - dnbar[i][0] < maxbars) 
               {
               llbar1 = doubleLowest(price,hilo,Bars-1-dnbar[0][0],Bars-1-dnbar[i][0],PivotOccurrence,llbar2); 
               
               if(!hilo) {llprice1 = price[llbar1]; llprice2 = price[llbar2];} else {llprice1 = Low[llbar1]; llprice2 = Low[llbar2];}
               
                  if(llprice1 < llprice2 && llbar2 - llbar1 > minbars && llbar2 - llbar1 < maxbars)   
                  {
                  if(ObjectFind(dn_osc ) < 0) PlotLine(dn_osc ,win,dnPivotTime[i][0],dnPivot[i][0],dnPivotTime[0][0],dnPivot[0][0],BullishDivergenceColor,RegularDivergenceWidth,RegularDivergenceStyle); 
                  if(ObjectFind(dn_line) < 0) PlotLine(dn_line,  0,     Time[llbar2],     llprice2,     Time[llbar1],     llprice1,BullishDivergenceColor,RegularDivergenceWidth,RegularDivergenceStyle); 
                  if(arrows && ObjectFind(up_arrow) < 0) drawArrow(up_arrow,0,Time[bar],NormalizeDouble(Low[bar]- gap*Point,Digits),ArrowFontName,ArrowSize,CharToStr(ArrowBuyCode),UpArrowColor);    
                  diversignal[bar] = 1; 
                  }
               }
            }
         }
                  
         if(up != EMPTY_VALUE)
         {   
            for(i=0;i<=lookback;i++)
            {
            up_osc   = UniqueName + " upOscReg " + i + " " + TimeToStr(Time[bar+size]);
            up_line  = UniqueName + " upLinReg " + i + " " + TimeToStr(Time[bar+size]);   
            dn_arrow = UniqueName + " dnArrReg " + i + " " + TimeToStr(Time[bar]); 
            
               if(upPivot[0][0] < upPivot[i][0] && upbar[0][0] - upbar[i][0] > minbars && upbar[0][0] - upbar[i][0] < maxbars) 
               {
               hhbar1 = doubleHighest(price,hilo,Bars-1-upbar[0][0],Bars-1-upbar[i][0],PivotOccurrence,hhbar2); 
               
               if(!hilo) {hhprice1 = price[hhbar1]; hhprice2 = price[hhbar2];} else {hhprice1 = High[hhbar1]; hhprice2 = High[hhbar2];}
               
                  if(hhprice1 > hhprice2 && hhbar2 - hhbar1 > minbars && hhbar2 - hhbar1 < maxbars)   
                  {
                  if(ObjectFind(up_osc ) < 0) PlotLine(up_osc ,win,upPivotTime[i][0],upPivot[i][0],upPivotTime[0][0],upPivot[0][0],BearishDivergenceColor,RegularDivergenceWidth,RegularDivergenceStyle);
                  if(ObjectFind(up_line) < 0) PlotLine(up_line,  0,Time[hhbar2]     ,hhprice2     ,Time[hhbar1]     ,hhprice1     ,BearishDivergenceColor,RegularDivergenceWidth,RegularDivergenceStyle);
                  if(arrows && ObjectFind(dn_arrow) < 0) drawArrow(dn_arrow,0,Time[bar],NormalizeDouble(High[bar] + 2*gap*Point,Digits),ArrowFontName,ArrowSize,CharToStr(ArrowSellCode),DnArrowColor);    
                  diversignal[bar] =-1; 
                  }
               }   
            }
         }
      }
         
      if(hidden)
      {
         if(dn != EMPTY_VALUE)
         {
            for(i=0;i<=lookback;i++)
            {
            dn_osc   = UniqueName + " dnOscHid " + i + " " + TimeToStr(Time[bar+size]);
            dn_line  = UniqueName + " dnLinHid " + i + " " + TimeToStr(Time[bar+size]);
            up_arrow = UniqueName + " upArrHid " + i + " " + TimeToStr(Time[bar]);    
            
               if(dnPivot[0][0] <= dnPivot[i][0] && dnbar[0][0] - dnbar[i][0] > minbars && dnbar[0][0] - dnbar[i][0] < maxbars) 
               {
               llbar1 = doubleLowest(price,hilo,Bars-1-dnbar[0][0],Bars-1-dnbar[i][0],PivotOccurrence,llbar2); 
               
               if(!hilo) {llprice1 = price[llbar1]; llprice2 = price[llbar2];} else {llprice1 = Low[llbar1]; llprice2 = Low[llbar2];}
               
                  if(llprice1 >= llprice2 && llbar2 - llbar1 > minbars && llbar2 - llbar1 < maxbars)   
                  {
                  if(ObjectFind(dn_osc ) < 0) PlotLine(dn_osc ,win,dnPivotTime[i][0],dnPivot[i][0],dnPivotTime[0][0],dnPivot[0][0],BullishDivergenceColor,HiddenDivergenceWidth,HiddenDivergenceStyle); 
                  if(ObjectFind(dn_line) < 0) PlotLine(dn_line,  0,     Time[llbar2],     llprice2,     Time[llbar1],     llprice1,BullishDivergenceColor,HiddenDivergenceWidth,HiddenDivergenceStyle); 
                  if(arrows && ObjectFind(up_arrow) < 0) drawArrow(up_arrow,0,Time[bar],NormalizeDouble(Low[bar]- gap*Point,Digits),ArrowFontName,ArrowSize,CharToStr(ArrowBuyCode),UpArrowColor);    
                  diversignal[bar] = 2; 
                  }
               }
            }
         }   
                 
         if(up != EMPTY_VALUE)
         {      
            for(i=0;i<=lookback;i++)
            {
            up_osc   = UniqueName + " upOscHid " + i + " " + TimeToStr(Time[bar+size]);
            up_line  = UniqueName + " upLinHid " + i + " " + TimeToStr(Time[bar+size]);   
            dn_arrow = UniqueName + " dnArrHid " + i + " " + TimeToStr(Time[bar]);   
         
               if(upPivot[0][0] >= upPivot[i][0] && upbar[0][0] - upbar[i][0] > minbars && upbar[0][0] - upbar[i][0] < maxbars) 
               {
               hhbar1 = doubleHighest(price,hilo,Bars-1-upbar[0][0],Bars-1-upbar[i][0],PivotOccurrence,hhbar2); 
               
               if(!hilo) {hhprice1 = price[hhbar1]; hhprice2 = price[hhbar2];} else {hhprice1 = High[hhbar1]; hhprice2 = High[hhbar2];}
               
                  if(hhprice1 <= hhprice2 && hhbar2 - hhbar1 > minbars && hhbar2 - hhbar1 < maxbars)   
                  {
                  if(ObjectFind(up_osc ) < 0) PlotLine(up_osc ,win,upPivotTime[i][0],upPivot[i][0],upPivotTime[0][0],upPivot[0][0],BearishDivergenceColor,HiddenDivergenceWidth,HiddenDivergenceStyle);
                  if(ObjectFind(up_line) < 0) PlotLine(up_line,  0,Time[hhbar2]     ,hhprice2     ,Time[hhbar1]     ,hhprice1     ,BearishDivergenceColor,HiddenDivergenceWidth,HiddenDivergenceStyle);
                  if(arrows && ObjectFind(dn_arrow) < 0) drawArrow(dn_arrow,0,Time[bar],NormalizeDouble(High[bar] + 2*gap*Point,Digits),ArrowFontName,ArrowSize,CharToStr(ArrowSellCode),DnArrowColor);    
                  diversignal[bar] =-2;
                  }
               }   
            }
         }
      }
   }  
}


int doubleHighest(double& price[],bool hilo,int istart,int iend,int occur,int& hhbar2)
{
   int hhbar1 = istart; hhbar2 = iend;
   double hh1, hh2, hiprice1, hiprice2, hiprice3;
   
   if(!hilo) {hh1 = price[istart]; hh2 = price[iend+occur];} else {hh1 = High[iend]; hh2 = High[iend+occur];}
   
   for(int i=istart+1;i<=iend-1;i++)
   {      
   if(!hilo) {hiprice1 = price[i-1]; hiprice2 = price[i]; hiprice3 = price[i+1];}
   else {hiprice1 = High[i-1]; hiprice2 = High[i]; hiprice3 = High[i+1];}
        
   if(hiprice1 < hiprice2 && hiprice3 < hiprice2 && hiprice2 > hh1 && i < istart + occur) {hh1 = hiprice2; hhbar1 = i;}
   }
    
   for(i=istart+1;i<=iend-1+occur;i++)
   {      
   if(!hilo) {hiprice1 = price[i-1]; hiprice2 = price[i]; hiprice3 = price[i+1];}
   else {hiprice1 = High[i-1]; hiprice2 = High[i]; hiprice3 = High[i+1];}
   
      if(hiprice1 < hiprice2 && hiprice3 < hiprice2 && hiprice2 > hh2 && i != hhbar1 && i > iend - occur && i < iend + occur) 
      {
      hh2    = hiprice2; 
      hhbar2 = i;
      }
   }
    
   return(hhbar1);
}

int doubleLowest(double& price[],bool hilo,int istart,int iend,int occur,int& llbar2)
{
   int llbar1 = istart; llbar2 = iend;
   double ll1, ll2, loprice1, loprice2, loprice3;
   
   if(!hilo) {ll1 = price[istart]; ll2 = price[iend+occur];} else {ll1 = Low[iend]; ll2 = Low[iend+occur];}
   
   for(int i=istart+1;i<=iend-1;i++)
   {      
   if(!hilo) {loprice1 = price[i-1]; loprice2 = price[i]; loprice3 = price[i+1];}
   else {loprice1 = Low[i-1]; loprice2 = Low[i]; loprice3 = Low[i+1];}
        
   if(loprice1 > loprice2 && loprice3 > loprice2 && loprice2 < ll1 && i < istart + occur) {ll1 = loprice2; llbar1 = i;}
   }
    
   for(i=istart+1;i<=iend-1+occur;i++)
   {      
   if(!hilo) {loprice1 = price[i-1]; loprice2 = price[i]; loprice3 = price[i+1];}
   else {loprice1 = Low[i-1]; loprice2 = Low[i]; loprice3 = Low[i+1];}
   
      if(loprice1 > loprice2 && loprice3 > loprice2 && loprice2 < ll2 && i != llbar1 && i > iend - occur && i < iend + occur) 
      {
      ll2    = loprice2; 
      llbar2 = i;
      }
   }
    
   return(llbar1);
}

//----------------  
//---------------- 
int averageSize(int mode)
{   
   int arraysize;
   
   switch(mode)
   {
   case 10: arraysize = 2; break;
   case 11: arraysize = 6; break;
   case 19: arraysize = 5; break;
   case 22: arraysize = 4; break;
   case 23: arraysize = 6; break;
   case 24: arraysize = 4; break;
   default: arraysize = 0; break;
   }
   
   return(arraysize);
}


double   tmp[][3][2], ma[3][4];
datetime prevtime[3];  

double allAveragesOnArray(int index,double& price[],int period,int mode,int arraysize,int cbars,int bar)
{
   if(period == 1) return(price[bar]);
      
   double MA[4];  
        
   if(mode == 1 || mode == 2 || mode == 7 || mode == 9 || mode == 10 || mode == 11 || mode == 12 || mode == 14 || (mode >= 19 && mode <= 29))  
   {
      if(prevtime[index] != Time[bar])
      {
      ma[index][3] = ma[index][2]; 
      ma[index][2] = ma[index][1]; 
      ma[index][1] = ma[index][0]; 
   
      if(arraysize > 0) for(int i=0;i<arraysize;i++) tmp[i][index][1] = tmp[i][index][0];
    
      prevtime[index] = Time[bar]; 
      }
   
      if(mode == 12 || mode == 15 || mode == 20 || (mode > 24 && mode < 29)) for(i=0;i<4;i++) MA[i] = ma[index][i]; 
   }
   
   switch(mode)
   {
   case 1 : ma[index][0] = EMAOnArray(price[bar],ma[index][1],period,cbars,bar); break;
   case 2 : ma[index][0] = WilderOnArray(price[bar],ma[index][1],period,cbars,bar); break;  
   case 3 : ma[index][0] = LWMAOnArray(price,period,bar); break;
   case 4 : ma[index][0] = SineWMAOnArray(price,period,bar); break;
   case 5 : ma[index][0] = TriMAOnArray(price,period,bar); break;
   case 6 : ma[index][0] = LSMAOnArray(price,period,bar); break;
   case 7 : ma[index][0] = SMMAOnArray(price,ma[index][1],period,cbars,bar); break;
   case 8 : ma[index][0] = HMAOnArray(price,period,cbars,bar); break;
   case 9 : ma[index][0] = ZeroLagEMAOnArray(price,ma[index][1],period,cbars,bar); break;
   case 10: ma[index][0] = DEMAOnArray(index,0,price[bar],period,1,cbars,bar); break;
   case 11: ma[index][0] = T3_basicOnArray(index,0,price[bar],period,0.7,cbars,bar); break;
   case 12: ma[index][0] = ITrendOnArray(price,MA,period,cbars,bar); break;
   case 13: ma[index][0] = MedianOnArray(price,period,bar); break;
   case 14: ma[index][0] = REMAOnArray(price[bar],MA,period,0.5,cbars,bar); break;
   case 15: ma[index][0] = ILRSOnArray(price,period,bar); break;
   case 16: ma[index][0] = IE2OnArray(price,period,bar); break;
   case 17: ma[index][0] = TriMA_genOnArray(price,period,bar); break;
   case 18: ma[index][0] = VWMAOnArray(price,period,bar); break;
   case 19: ma[index][0] = JSmoothOnArray(index,0,price[bar],period,1,cbars,bar); break;
   case 20: ma[index][0] = SMA_eqOnArray(price,MA,period,cbars,bar); break;
   case 21: ma[index][0] = ALMAOnArray(price,period,0.85,8,bar); break;
   case 22: ma[index][0] = TEMAOnArray(index,price[bar],period,1,cbars,bar); break;
   case 23: ma[index][0] = T3OnArray(index,0,price[bar],period,0.7,cbars,bar); break;
   case 24: ma[index][0] = LaguerreOnArray(index,price[bar],period,4,cbars,bar); break;
   case 25: ma[index][0] = BF2POnArray(price,MA,period,cbars,bar); break;
   case 26: ma[index][0] = BF3POnArray(price,MA,period,cbars,bar); break;
   case 27: ma[index][0] = SuperSmuOnArray(price,MA,period,cbars,bar); break;
   case 28: ma[index][0] = DecyclerOnArray(price,MA,period,cbars,bar); return(price[bar] - ma[index][0]); 
   case 29: ma[index][0] = eVWMAOnArray(price[bar],ma[index][1],period,cbars,bar); break;
   default: ma[index][0] = SMAOnArray(price,period,bar); break;
   }
   
   return(ma[index][0]);
}

// MA_Method=0: SMA - Simple Moving Average
double SMAOnArray(double& array[],int per,int bar)
{
   double sum = 0;
   for(int i=0;i<per;i++) sum += array[bar+i];
   
   return(sum/per);
}                
// MA_Method=1: EMA - Exponential Moving Average
double EMAOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar >= cbars - 2) double ema = price;
   else 
   ema = prev + 2.0/(1 + per)*(price - prev); 
   
   return(ema);
}
// MA_Method=2: Wilder - Wilder Exponential Moving Average
double WilderOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar >= cbars - 2) double wilder = price; 
   else 
   wilder = prev + (price - prev)/per; 
   
   return(wilder);
}

// MA_Method=3: LWMA - Linear Weighted Moving Average 
double LWMAOnArray(double& array[],int per,int bar)
{
   double sum = 0, weight = 0;
   
      for(int i=0;i<per;i++)
      { 
      weight += (per - i);
      sum    += array[bar+i]*(per - i);
      }
   
   if(weight > 0) return(sum/weight); else return(0); 
} 

// MA_Method=4: SineWMA - Sine Weighted Moving Average
double SineWMAOnArray(double& array[],int per,int bar)
{
   double sum = 0, weight = 0;
  
      for(int i=0;i<per;i++)
      { 
      weight += MathSin(pi*(i + 1)/(per + 1));
      sum    += array[bar+i]*MathSin(pi*(i + 1)/(per + 1)); 
      }
   
   if(weight > 0) return(sum/weight); else return(0); 
}

// MA_Method=5: TriMA - Triangular Moving Average
double TriMAOnArray(double& array[],int per,int bar)
{
   int len = MathCeil((per + 1)*0.5);
   double sum = 0;
   
   for(int i=0;i<len;i++) sum += SMAOnArray(array,len,bar+i);
         
   return(sum/len);
}

// MA_Method=6: LSMA - Least Square Moving Average (or EPMA, Linear Regression Line)
double LSMAOnArray(double& array[],int per,int bar)
{   
   double sum = 0;
   
   for(int i=per;i>=1;i--) sum += (i - (per + 1)/3.0)*array[bar+per-i];
   
   return(sum*6/(per*(per + 1)));
}

// MA_Method=7: SMMA - Smoothed Moving Average
double SMMAOnArray(double& array[],double prev,int per,int cbars,int bar)
{
   if(bar == cbars - per) double smma = SMAOnArray(array,per,bar);
   else 
   if(bar  < cbars - per)
   {
   double sum = 0;
   for(int i=0;i<per;i++) sum += array[bar+i+1];
   smma = (sum - prev + array[bar])/per;
   }
   
   return(smma);
}                

// MA_Method=8: HMA - Hull Moving Average by Alan Hull
double HMAOnArray(double& array[],int per,int cbars,int bar)
{
   double _tmp[];
   int len = MathSqrt(per);
   
   ArrayResize(_tmp,len);
   
   if(bar == cbars - per) double hma = array[bar]; 
   else
   if(bar < cbars - per)
   {
   for(int i=0;i<len;i++) _tmp[i] = 2*LWMAOnArray(array,per/2,bar+i) - LWMAOnArray(array,per,bar+i);  
   hma = LWMAOnArray(_tmp,len,0); 
   }  

   return(hma);
}

// MA_Method=9: ZeroLagEMA - Zero-Lag Exponential Moving Average
double ZeroLagEMAOnArray(double& price[],double prev,int per,int cbars,int bar)
{
   int lag = 0.5*(per - 1); 
   double alpha = 2.0/(1 + per); 
      
   if(bar >= cbars - lag) double zema = price[bar];
   else 
   zema = alpha*(2*price[bar] - price[bar+lag]) + (1 - alpha)*prev;
   
   return(zema);
}

// MA_Method=10: DEMA - Double Exponential Moving Average by Patrick Mulloy
double DEMAOnArray(int index,int num,double price,double per,double v,int cbars,int bar)
{
   double alpha = 2.0/(1 + per);
   
   if(bar == cbars - 2) {double dema = price; tmp[num][index][0] = dema; tmp[num+1][index][0] = dema;}
   else 
   if(bar <  cbars - 2) 
   {
   tmp[num  ][index][0] = tmp[num  ][index][1] + alpha*(price              - tmp[num  ][index][1]); 
   tmp[num+1][index][0] = tmp[num+1][index][1] + alpha*(tmp[num][index][0] - tmp[num+1][index][1]); 
   dema                 = tmp[num  ][index][0]*(1+v) - tmp[num+1][index][0]*v;
   }
   
   return(dema);
}

// MA_Method=11: T3 by T.Tillson
double T3_basicOnArray(int index,int num,double price,int per,double v,int cbars,int bar)
{
   double dema1, dema2;
   
   if(bar == cbars - 2) 
   {
   double T3 = price; 
   for(int k=0;k<6;k++) tmp[num+k][index][0] = price;
   }
   else 
   if(bar < cbars - 2) 
   {
   dema1 = DEMAOnArray(index,num  ,price,per,v,cbars,bar); 
   dema2 = DEMAOnArray(index,num+2,dema1,per,v,cbars,bar); 
   T3    = DEMAOnArray(index,num+4,dema2,per,v,cbars,bar);
   }
   
   return(T3);
}

// MA_Method=12: ITrend - Instantaneous Trendline by J.Ehlers
double ITrendOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   double alpha = 2.0/(per + 1);
   if(bar < cbars - 7) double it = (alpha - 0.25*alpha*alpha)*price[bar] + 0.5*alpha*alpha*price[bar+1] 
                                 - (alpha - 0.75*alpha*alpha)*price[bar+2] + 2*(1 - alpha)*array[1] 
                                 - (1 - alpha)*(1 - alpha)*array[2];
   else it = (price[bar] + 2*price[bar+1] + price[bar+2])/4;
   
   return(it);
}
// MA_Method=13: Median - Moving Median
double MedianOnArray(double& price[],int per,int bar)
{
   double array[];
   ArrayResize(array,per);
   
   for(int i=0;i<per;i++) array[i] = price[bar+i];
   ArraySort(array,WHOLE_ARRAY,0,MODE_DESCEND);
   
   int num = MathRound((per - 1)*0.5); 
   if(MathMod(per,2) > 0) double median = array[num]; else median = 0.5*(array[num] + array[num+1]);
    
   return(median); 
}

// MA_Method=14: GeoMean - Geometric Mean
double GeoMeanOnArray(double& price[],int per,int cbars,int bar)
{
   if(bar < cbars - per)
   { 
   double gmean = MathPow(price[bar],1.0/per); 
   for(int i=1;i<per;i++) gmean *= MathPow(price[bar+i],1.0/per); 
   }
   else gmean = SMAOnArray(price,per,bar);
   
   return(gmean);
}

// MA_Method=15: REMA - Regularized EMA by Chris Satchwell 
double REMAOnArray(double price,double& array[],int per,double lambda,int cbars,int bar)
{
   double alpha =  2.0/(per + 1);
   
   if(bar >= cbars - 3) double rema = price;
   else 
   rema = (array[1]*(1 + 2*lambda) + alpha*(price - array[1]) - lambda*array[2])/(1 + lambda); 
   
   return(rema);
}
// MA_Method=16: ILRS - Integral of Linear Regression Slope 
double ILRSOnArray(double& price[],int per,int bar)
{
   double sum  = per*(per - 1)*0.5;
   double sum2 = (per - 1)*per*(2*per - 1)/6.0;
     
   double sum1 = 0;
   double sumy = 0;
      for(int i=0;i<per;i++)
      { 
      sum1 += i*price[bar+i];
      sumy += price[bar+i];
      }
   double num1 = per*sum1 - sum*sumy;
   double num2 = sum*sum - per*sum2;
   
   if(num2 != 0) double slope = num1/num2; else slope = 0; 
   double ilrs = slope + SMAOnArray(price,per,bar);
   
   return(ilrs);
}
// MA_Method=17: IE/2 - Combination of LSMA and ILRS 
double IE2OnArray(double& price[],int per,int bar)
{
   double ie = 0.5*(ILRSOnArray(price,per,bar) + LSMAOnArray(price,per,bar));
      
   return(ie); 
}
 
// MA_Method=18: TriMAgen - Triangular Moving Average Generalized by J.Ehlers
double TriMA_genOnArray(double& array[],int per,int bar)
{
   int len1 = MathFloor((per + 1)*0.5);
   int len2 = MathCeil ((per + 1)*0.5);
   double sum = 0;
   
   for(int i = 0;i < len2;i++) sum += SMAOnArray(array,len1,bar+i);
   
   return(sum/len2);
}

// MA_Method=19: VWMA - Volume Weighted Moving Average 
double VWMAOnArray(double& array[],int per,int bar)
{
   double sum = 0, weight = 0;
   
      for(int i=0;i<per;i++)
      { 
      weight += Volume[bar+i];
      sum    += array[bar+i]*Volume[bar+i];
      }
   
   if(weight > 0) return(sum/weight); else return(0); 
} 

// MA_Method=20: JSmooth - Smoothing by Mark Jurik
double JSmoothOnArray(int index,int num,double price,int per,double power,int cbars,int bar)
{
   double beta  = 0.45*(per - 1)/(0.45*(per - 1) + 2);
	double alpha = MathPow(beta,power);
	
	if(bar == cbars - 2) {tmp[num+4][index][0] = price; tmp[num+0][index][0] = price; tmp[num+2][index][0] = price;}
	else 
   if(bar <  cbars - 2) 
   {
	tmp[num+0][index][0] = (1 - alpha)*price + alpha*tmp[num+0][index][1];
	tmp[num+1][index][0] = (price - tmp[num+0][index][0])*(1-beta) + beta*tmp[num+1][index][1];
	tmp[num+2][index][0] = tmp[num+0][index][0] + tmp[num+1][index][0];
	tmp[num+3][index][0] = (tmp[num+2][index][0] - tmp[num+4][index][1])*MathPow((1-alpha),2) + MathPow(alpha,2)*tmp[num+3][index][1];
	tmp[num+4][index][0] = tmp[num+4][index][1] + tmp[num+3][index][0]; 
   }
   return(tmp[num+4][index][0]);
}

// MA_Method=21: SMA_eq     - Simplified SMA
double SMA_eqOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   if(bar == cbars - per) double sma = SMAOnArray(price,per,bar);
   else 
   if(bar <  cbars - per) sma = (price[bar] - price[bar+per])/per + array[1]; 
   
   return(sma);
}                        		

// MA_Method=22: ALMA by Arnaud Legoux / Dimitris Kouzis-Loukas / Anthony Cascino
double ALMAOnArray(double& price[],int per,double offset,double sigma,int bar)
{
   double m = MathFloor(offset*(per - 1)), s = per/sigma, w, sum = 0, wsum = 0;		
	
	for (int i=0;i<per;i++) 
	{
	w     = MathExp(-((i - m)*(i - m))/(2*s*s));
   wsum += w;
   sum  += price[bar+(per-1-i)]*w; 
   }
   
   if(wsum != 0) return(sum/wsum); else return(0);
}   

// MA_Method=23: TEMA - Triple Exponential Moving Average by Patrick Mulloy
double TEMAOnArray(int index,double price,int per,double v,int cbars,int bar)
{
   double alpha = 2.0/(per+1);
	
	if(bar == cbars - 2) {tmp[0][index][0] = price; tmp[1][index][0] = price; tmp[2][index][0] = price;}
	else 
   if(bar <  cbars - 2) 
   {
	tmp[0][index][0] = tmp[0][index][1] + alpha *(price            - tmp[0][index][1]);
	tmp[1][index][0] = tmp[1][index][1] + alpha *(tmp[0][index][0] - tmp[1][index][1]);
	tmp[2][index][0] = tmp[2][index][1] + alpha *(tmp[1][index][0] - tmp[2][index][1]);
	tmp[3][index][0] = tmp[0][index][0] + v*(tmp[0][index][0] + v*(tmp[0][index][0]-tmp[1][index][0]) - tmp[1][index][0] - v*(tmp[1][index][0] - tmp[2][index][0])); 
	}
   
   return(tmp[3][index][0]);
}

// MA_Method=24: T3 by T.Tillson (correct version) 
double T3OnArray(int index,int num,double price,int per,double v,int cbars,int bar)
{
   double len = MathMax((per + 5.0)/3.0 - 1,1), dema1, dema2;
   
   if(bar == cbars - 2) 
   {
   double T3 = price; 
   for(int k=0;k<6;k++) tmp[num+k][index][0] = T3;
   }
   else 
   if(bar < cbars - 2) 
   {
   dema1 = DEMAOnArray(index,num  ,price,len,v,cbars,bar); 
   dema2 = DEMAOnArray(index,num+2,dema1,len,v,cbars,bar); 
   T3    = DEMAOnArray(index,num+4,dema2,len,v,cbars,bar);
   }
      
   return(T3);
}

// MA_Method=25: Laguerre filter by J.Ehlers
double LaguerreOnArray(int index,double price,int per,int order,int cbars,int bar)
{
   double gamma = 1 - 10.0/(per + 9);
   double aPrice[];
   
   ArrayResize(aPrice,order);
   
   for(int i=0;i<order;i++)
   {
      if(bar >= cbars - order) tmp[i][index][0] = price;
      else
      {
         if(i == 0) tmp[i][index][0] = (1 - gamma)*price + gamma*tmp[i][index][1];
         else
         tmp[i][index][0] = -gamma * tmp[i-1][index][0] + tmp[i-1][index][1] + gamma * tmp[i][index][1];
      
      aPrice[i] = tmp[i][index][0];
      }
   }
   double laguerre = TriMA_genOnArray(aPrice,order,0);  

   return(laguerre);
}

// MA_Method=26:  MD - McGinley Dynamic
double McGinleyOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar == cbars - 2) double md = price;
   else 
   if(bar <  cbars - 2) 
   {
      if(prev  != 0) md = prev + (price - prev)/(per*MathPow(price/prev,4)/2);
      else md = price;
   }
   
   return(md);
}

// MA_Method=27: BF2P - Two-pole modified Butterworth filter
double BF2POnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   double a  = MathExp(-1.414*pi/per);
   double b  = 2*a*MathCos(1.414*1.25*pi/per);
   double c2 = b;
   double c3 = -a*a;
   double c1 = 1 - c2 - c3;
   
   if(bar < cbars - 7) double bf2p = c1*(price[bar] + 2*price[bar+1] + price[bar+2])/4 + c2*array[1] + c3*array[2];
   else bf2p = (price[bar] + 2*price[bar+1] + price[bar+2])/4;
   
   return(bf2p);
}

// MA_Method=28: BF3P - Three-pole modified Butterworth filter
double BF3POnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   double a  = MathExp(-pi/per);
   double b  = 2*a*MathCos(1.738*pi/per);
   double c  = a*a;
   double d2 = b + c;
   double d3 = -(c + b*c);
   double d4 = c*c;
   double d1 = 1 - d2 - d3 - d4;
   
   if(bar < cbars - 7) double bf3p = d1*(price[bar] + 3*price[bar+1] + 3*price[bar+2] + price[bar+3])/8 + d2*array[1] + d3*array[2] + d4*array[3];
   else bf3p = (price[bar] + 3*price[bar+1] + 3*price[bar+2] + price[bar+3])/8;
   
   return(bf3p);
}

// MA_Method=29: SuperSmu - SuperSmoother filter
double SuperSmuOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   double a  = MathExp(-1.414*pi/per);
   double b  = 2*a*MathCos(1.414*pi/per);
   double c2 = b;
   double c3 = -a*a;
   double c1 = 1 - c2 - c3;
   
   if(bar < cbars - 7) double supsm = c1*(price[bar] + price[bar+1])/2 + c2*array[1] + c3*array[2];
   else {supsm = (price[bar] + price[bar+1])/2; Print("bar=",bar," ma=",supsm);}
   
   return(supsm);
}

// MA_Method=30: Decycler - Simple Decycler by J.Ehlers
double DecyclerOnArray(double& price[],double& hp[],int per,int cbars,int bar)
{
   double alpha1 = (MathCos(1.414*pi/per) + MathSin(1.414*pi/per) - 1)/MathCos(1.414*pi/per);
  
   
   if(bar > cbars - 4) return(0);
   
   hp[0] = (1 - alpha1/2)*(1 - alpha1/2)*(price[bar] - 2*price[bar+1] + price[bar+2]) + 2*(1 - alpha1)*hp[1] - (1 - alpha1)*(1 - alpha1)*hp[2];		
     
   return(hp[0]);
}

// MA_Method=31: eVWMA - Elastic Volume Weighted Moving Average by C.Fries
double eVWMAOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar >= cbars - per) double evwma = price;
   else 
   {
   double max = 0;
   for(int i=0;i<per;i++) max = MathMax(max,Volume[bar+i]);
      
   double ediff = 3*max - Volume[bar];
          
      if(ediff < 0) evwma = prev;
      else 
      evwma = (ediff*prev + Volume[bar]*price)/(3*max); 
   }
   
   return(evwma);
}

double getPivots(int type,double& price[],int size,double height,int bar,datetime& pivottime)
{
   if(type < 2) int len = 2*MathMax(1,size) + 1; else len = size;
      
   int imax = 0, imin = 0;
   double max = -1000000000, min = 100000000;
       
   for(int i=0;i<len;i++)
   { 
      if((type == 0 || type == 2) && price[i] > max && price[i] < 1000000) {max = price[i]; imax = i;}  
      if((type == 1 || type == 3) && price[i] < min ) {min = price[i]; imin = i;}  
   }
   
   if(type < 2) 
   {
   if(imax == size && max - price[0] > height && max - price[len-1] > height) {pivottime = Time[bar+size]; return(max);} 
   if(imin == size && price[0] - min > height && price[len-1] - min > height) {pivottime = Time[bar+size]; return(min);}
   }
   else 
   {
   if(type == 2) return(max); 
   if(type == 3) return(min); 
   }
   
   return(EMPTY_VALUE);  
}




void drawArrow(string name,int win,int time,double price,string font,int size,string acode,color clr)
{
   if(ObjectCreate(name,OBJ_TEXT,win,time,price)) ObjectSetText(name,acode,size,font,clr); 
}

void PlotLine(string name,int win,datetime time1,double value1,datetime time2,double value2,color clr,int width,int style)
{
   if(ObjectCreate(name,OBJ_TREND,win,time1,value1,time2,value2))
   {
   //if(win > 0) Print("name=",name," time2=",TimeToStr(time2)," valu2=",value2);
   ObjectSet(name, OBJPROP_WIDTH,width);
   ObjectSet(name, OBJPROP_STYLE,style);
   ObjectSet(name, OBJPROP_RAY  ,false);
   ObjectSet(name, OBJPROP_BACK ,false);
   ObjectSet(name, OBJPROP_COLOR,clr  );
   }  
}      

bool deleteObj(string name)
{
   bool result = false;
   
   int length = StringLen(name);
   for(int i=ObjectsTotal()-1; i>=0; i--)
   {
   string objName = ObjectName(i); 
   if(StringSubstr(objName,0,length) == name) {ObjectDelete(objName); result = true;}
   }
   
   return(result);
}   




// HeikenAshi Price
double   haClose[3][2], haOpen[3][2], haHigh[3][2], haLow[3][2];
datetime prevhatime[3];

double HeikenAshi(int index,int price,int cbars,int bar)
{ 
   if(prevhatime[index] != Time[bar])
   {
   haClose[index][1] = haClose[index][0];
   haOpen [index][1] = haOpen [index][0];
   haHigh [index][1] = haHigh [index][0];
   haLow  [index][1] = haLow  [index][0];
   prevhatime[index] = Time[bar];
   }
   
   if(bar == cbars - 1) 
   {
   haClose[index][0] = Close[bar];
   haOpen [index][0] = Open [bar];
   haHigh [index][0] = High [bar];
   haLow  [index][0] = Low  [bar];
   }
   else
   {
   haClose[index][0] = (Open[bar] + High[bar] + Low[bar] + Close[bar])/4;
   haOpen [index][0] = (haOpen[index][1] + haClose[index][1])/2;
   haHigh [index][0] = MathMax(High[bar],MathMax(haOpen[index][0],haClose[index][0]));
   haLow  [index][0] = MathMin(Low [bar],MathMin(haOpen[index][0],haClose[index][0]));
   }
   
   switch(price)
   {
   case  0: return(haClose[index][0]); break;
   case  1: return(haOpen [index][0]); break;
   case  2: return(haHigh [index][0]); break;
   case  3: return(haLow  [index][0]); break;
   case  4: return((haHigh[index][0] + haLow[index][0])/2); break;
   case  5: return((haHigh[index][0] + haLow[index][0] +   haClose[index][0])/3); break;
   case  6: return((haHigh[index][0] + haLow[index][0] + 2*haClose[index][0])/4); break;
   default: return(haClose[index][0]); break;
   }
} 


string tf(int itimeframe)
{
   string result = "";
   
   switch(itimeframe)
   {
   case PERIOD_M1:   result = "M1" ;
   case PERIOD_M5:   result = "M5" ;
   case PERIOD_M15:  result = "M15";
   case PERIOD_M30:  result = "M30";
   case PERIOD_H1:   result = "H1" ;
   case PERIOD_H4:   result = "H4" ;
   case PERIOD_D1:   result = "D1" ;
   case PERIOD_W1:   result = "W1" ;
   case PERIOD_MN1:  result = "MN1";
   default:          result = "N/A";
   }
   
   if(result == "N/A")
   {
   if(itimeframe <  PERIOD_H1 ) result = "M"  + itimeframe;
   if(itimeframe >= PERIOD_H1 ) result = "H"  + itimeframe/PERIOD_H1;
   if(itimeframe >= PERIOD_D1 ) result = "D"  + itimeframe/PERIOD_D1;
   if(itimeframe >= PERIOD_W1 ) result = "W"  + itimeframe/PERIOD_W1;
   if(itimeframe >= PERIOD_MN1) result = "MN" + itimeframe/PERIOD_MN1;
   }
   
   return(result); 
}

datetime prevnbtime;

bool isNewBar(int tf)
{
   bool res = false;
   
   if(tf >= 0)
   {
      if(iTime(NULL,tf,0) != prevnbtime)
      {
      res   = true;
      prevnbtime = iTime(NULL,tf,0);
      }   
   }
   else res = true;
   
   return(res);
}

string prevmess;
 
bool BoxAlert(bool cond,string text)   
{      
   string mess = IndicatorName + "("+Symbol()+","+TF + ")" + text;
   
   if (cond && mess != prevmess)
	{
	Alert (mess);
	prevmess = mess; 
	return(true);
	} 
  
   return(false);  
}

datetime pausetime;

bool Pause(int sec)
{
   if(TimeCurrent() >= pausetime + sec) {pausetime = TimeCurrent(); return(true);}
   
   return(false);
}

datetime warningtime;

void WarningSound(bool cond,int num,int sec,string sound,datetime curtime)
{
   static int i;
   
   if(cond)
   {
   if(curtime != warningtime) i = 0; 
   if(i < num && Pause(sec)) {PlaySound(sound); warningtime = curtime; i++;}       	
   }
}

string prevemail;

bool EmailAlert(bool cond,string text1,string text2,int num)   
{      
   string subj = "New " + text1 +" Signal from " + IndicatorName + "!!!";    
   string mess = IndicatorName + "("+Symbol()+","+TF + ")" + text2;
   
   if (cond && mess != prevemail)
	{
	if(subj != "" && mess != "") for(int i=0;i<num;i++) SendMail(subj, mess);  
	prevemail = mess; 
	return(true);
	} 
  
   return(false);  
}

string prevpush;
 
bool PushAlert(bool cond,string text)   
{      
   string push = IndicatorName + "("+Symbol() + "," + TF + ")" + text;
   
   if(cond && push != prevpush)
	{
	SendNotification(push);
	
	prevpush = push; 
	return(true);
	} 
  
   return(false);  
}
    

