//+------------------------------------------------------------------+
//|                                      BetterVolume 1.5 Alerts.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
// Alert code added by Andriy Moraru (http://www.earnforex.com)
// + Alerts can be now turned off for particular colors (2012-08-23)

#property copyright ""
#property link      ""

// BetterVolume 1.5.mq4 
// modified to correct start loop 

#property indicator_separate_window
#property indicator_buffers 7
#property indicator_color1 clrRed 
#property indicator_color2 clrDeepSkyBlue 
#property indicator_color3 clrYellow 
#property indicator_color4 clrLime 
#property indicator_color5 clrWhite 
#property indicator_color6 clrMagenta 	// Climax Churn 
#property indicator_color7 clrLightSeaGreen 	// Ma 		Maroon 

#property indicator_width1 4
#property indicator_width2 4
#property indicator_width3 4
#property indicator_width4 4
#property indicator_width5 4
#property indicator_width6 4

extern int     NumberOfBars = 0 ; // 1500 ; 500;
extern string  Note = "0 means Display all bars";
extern int     MAPeriod = 14 ;
extern int     LookBack = 20;
extern int     width1 = 4 ;
extern int     width2 = 4 ;

input bool             alertsOn              = true;              // Alerts on true/false?
input bool             alertsOnCurrent       = false;             // Alerts on open bar true/false?
input bool             alertsMessage         = true;              // Alerts message true/false?
input bool             alertsSound           = false;             // Alerts sound true/false?
input bool             alertsNotify          = false;             // Alerts notification true/false?
input bool             alertsEmail           = false;             // Alerts email true/false?
input string           soundFile             = "alert2.wav";      // Sound file

extern bool IgnoreLightSeaGreen = false;
extern bool IgnoreWhite = false;
extern bool IgnoreFireBrick = false;
extern bool IgnoreDodgerBlue = false;
extern bool IgnoreLightSalmon = false;
extern bool IgnoreMagenta = false;

double red[],blue[],yellow[],green[],white[],magenta[],v4[];

// Variables for alerts:
color CurrentColor[3] = {White, White, White};
datetime LastAlertTime = D'1980.01.01';

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
      SetIndexBuffer(0,red);
      SetIndexStyle(0,DRAW_HISTOGRAM,0,width2);
      SetIndexLabel(0,"Climax High ");
      
      SetIndexBuffer(1,blue);
      SetIndexStyle(1,DRAW_HISTOGRAM,0,width1);
      SetIndexLabel(1,"Neutral");
      
      SetIndexBuffer(2,yellow);
      SetIndexStyle(2,DRAW_HISTOGRAM,0,width1);
      SetIndexLabel(2,"Low ");
      
      SetIndexBuffer(3,green);
      SetIndexStyle(3,DRAW_HISTOGRAM,0,width1);
      SetIndexLabel(3,"HighChurn ");

      SetIndexBuffer(4,white);
      SetIndexStyle(4,DRAW_HISTOGRAM,0,width2);
      SetIndexLabel(4,"Climax Low ");

      SetIndexBuffer(5,magenta);
      SetIndexStyle(5,DRAW_HISTOGRAM,0,width1);
      SetIndexLabel(5,"ClimaxChurn ");

      SetIndexBuffer(6,v4);
      SetIndexStyle(6,DRAW_LINE,0,1);
      SetIndexLabel(6,"Average("+MAPeriod+")");

      IndicatorShortName("Better Volume 1.5" );

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {

   double VolLowest,Range,Value2,Value3,HiValue2,HiValue3,LoValue3,tempv2,tempv3,tempv;
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;

/*
   if ( NumberOfBars == 0 )  //				0 = all - appalling resource hog if using anything but 0 
      NumberOfBars = Bars-counted_bars;
   limit=NumberOfBars; //Bars-counted_bars;
*/
   if ( NumberOfBars == 0 )
      limit = Bars-counted_bars;
   if ( NumberOfBars > 0 && NumberOfBars < Bars )  //
      limit = NumberOfBars - counted_bars;

   for(int i=0; i<limit; i++)   
      {
         red[i] = EMPTY_VALUE; blue[i] = Volume[i]; yellow[i] = EMPTY_VALUE; green[i] = EMPTY_VALUE; white[i] = EMPTY_VALUE; magenta[i] = EMPTY_VALUE;
         Value2=0;Value3=0;HiValue2=0;HiValue3=0;LoValue3=99999999;tempv2=0;tempv3=0;tempv=0;
         if (i <= 2) CurrentColor[i] = clrWhite;


         VolLowest = Volume[iLowest(NULL,0,MODE_VOLUME,20,i)];
         if (Volume[i] == VolLowest)
            {
               yellow[i] = NormalizeDouble(Volume[i],0);
               blue[i]=EMPTY_VALUE;
               if (i <= 2) CurrentColor[i] = clrFireBrick;
            }

         Range = (High[i]-Low[i]);
         Value2 = Volume[i]*Range;

         if (Range != 0) Value3 = Volume[i]/Range;
         for (int n=i;n<i+MAPeriod;n++){   tempv= Volume[n] + tempv; } 
         v4[i] = NormalizeDouble(tempv/MAPeriod,0);
         for (n=i;n<i+LookBack;n++)
         {
             tempv2 = Volume[n]*((High[n]-Low[n])); 
               if (tempv2 >= HiValue2) HiValue2 = tempv2;
               if (Volume[n]*((High[n]-Low[n])) != 0 )
               {           
                  tempv3 = Volume[n] / ((High[n]-Low[n]));
                  if (tempv3 > HiValue3)  HiValue3 = tempv3; 
                  if (tempv3 < LoValue3)  LoValue3 = tempv3;
               } 
         }
         if (Value2 == HiValue2  && Close[i] > (High[i] + Low[i]) / 2)
         {
               red[i]    = NormalizeDouble(Volume[i],0);
               blue[i]   = EMPTY_VALUE;
               yellow[i] = EMPTY_VALUE;
               if (i <= 2) CurrentColor[i] = clrLightSeaGreen;
         }   

         if (Value3 == HiValue3)
         {
               green[i]  = NormalizeDouble(Volume[i],0);                
               blue[i]   = EMPTY_VALUE;
               yellow[i] = EMPTY_VALUE;
               red[i]    = EMPTY_VALUE;
               if (i <= 2) CurrentColor[i] = clrDodgerBlue;
         }
         if (Value2 == HiValue2 && Value3 == HiValue3)
         {
               magenta[i] = NormalizeDouble(Volume[i],0);
               blue[i]    = EMPTY_VALUE;
               red[i]     = EMPTY_VALUE;
               green[i]   = EMPTY_VALUE;
               yellow[i]  = EMPTY_VALUE;
               if (i <= 2) CurrentColor[i] = clrMagenta;
            } 
         if (Value2 == HiValue2  && Close[i] <= (High[i] + Low[i]) / 2)
            {
               white[i]   = NormalizeDouble(Volume[i],0);
               magenta[i] = EMPTY_VALUE;
               blue[i]    = EMPTY_VALUE;
               red[i]     = EMPTY_VALUE;
               green[i]   = EMPTY_VALUE;
               yellow[i]  = EMPTY_VALUE;
               if (i <= 2) CurrentColor[i] = clrLightSalmon;
            }
      }
//----

//----
   if ((CurrentColor[1] != CurrentColor[2]))
   {
      if ((CurrentColor[1] == clrLightSeaGreen) && (IgnoreLightSeaGreen)) return(0);
      if ((CurrentColor[1] == clrWhite)         && (IgnoreWhite))         return(0);
      if ((CurrentColor[1] == clrFireBrick)     && (IgnoreFireBrick))     return(0);
      if ((CurrentColor[1] == clrDodgerBlue)    && (IgnoreDodgerBlue))    return(0);
      if ((CurrentColor[1] == clrLightSalmon)   && (IgnoreLightSalmon))   return(0);
      if ((CurrentColor[1] == clrMagenta)       && (IgnoreMagenta))       return(0);
   }
   
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0; 
      static datetime time1 = 0;
      static string   mess1 = "";
         if (red[whichBar+1]     == EMPTY_VALUE && red[whichBar]     != EMPTY_VALUE) doAlert(time1,mess1,whichBar,"Climax High");
         if (blue[whichBar+1]    == EMPTY_VALUE && blue[whichBar]    != EMPTY_VALUE) doAlert(time1,mess1,whichBar,"Neutral");
         if (yellow[whichBar+1]  == EMPTY_VALUE && yellow[whichBar]  != EMPTY_VALUE) doAlert(time1,mess1,whichBar,"Low");
         if (green[whichBar+1]   == EMPTY_VALUE && green[whichBar]   != EMPTY_VALUE) doAlert(time1,mess1,whichBar,"High Churn");
         if (white[whichBar+1]   == EMPTY_VALUE && white[whichBar]   != EMPTY_VALUE) doAlert(time1,mess1,whichBar,"Climax Low");
         if (magenta[whichBar+1] == EMPTY_VALUE && magenta[whichBar] != EMPTY_VALUE) doAlert(time1,mess1,whichBar,"Climax Churn");          
   }                   
return(0);
}
  
  //
//
//
//
//

void doAlert(datetime& previousTime, string& previousAlert, int forBar, string doWhat)
{
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];
       
       //
       //
       //
       //
       //

       message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" Better Volume "+doWhat;
          if (alertsMessage) Alert(message);
          if (alertsNotify)  SendNotification(message);
          if (alertsEmail)   SendMail(_Symbol+" Better Volume ",message);
          if (alertsSound)   PlaySound(soundFile);
      }
}

//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
  
