//+------------------------------------------------------------------+
//|                                                    MA_BBands.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 clrWhite
#property indicator_color2 clrWhite
#property indicator_color3 clrBlue
#property indicator_color4 clrRed
#property indicator_color5 clrYellow

#property  indicator_width1  2
#property  indicator_width2  2
#property  indicator_width3  1
#property  indicator_width4  1
#property  indicator_width5  1

extern int MoveShift = 12;
extern int MAPeriod = 9 ;
extern int OsMA = 3 ; 
extern int Dist2 = 20 ;
//-------------------------

extern double Std = 0.4 ; //0.5
extern int BPeriod = 20 ;

extern bool   alertsOn               = true;
extern bool   alertsMessage          = true;
extern bool   alertsSound            = false;
extern bool   alertsEmail            = false;

//-------------------------

double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double ExtMapBuffer5[];
//-------------------

int init()
  {
  
   IndicatorBuffers(5);
  
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ExtMapBuffer2);
   
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,233);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexEmptyValue(2,0.0);
   
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexArrow(3,234);
   SetIndexBuffer(3,ExtMapBuffer4);
   SetIndexEmptyValue(3,0.0);
   
   SetIndexStyle(4,DRAW_LINE);
   SetIndexBuffer(4,ExtMapBuffer5);   

   IndicatorShortName(WindowExpertName()); 
    
   return(0);
  }
//----------------------------------------
 
int deinit()
  {return(0);}
//---------------------------------------- 
int start()
  { 
    
    int counted_bars=IndicatorCounted();    
    if(counted_bars<0) return(-1); 
    if(counted_bars>0) counted_bars--;
    int limit=Bars-counted_bars;   
    
    double OsMA_Now, OsMA_Pre; 
    
    for(int i=limit-1; i>=0; i--)    
     {           
           double MAUP1 = iMA(NULL,0,MAPeriod,-MoveShift,MODE_SMA,PRICE_HIGH,i); 
           double BB_UP = iBands(NULL,0,BPeriod,Std,0,PRICE_HIGH,MODE_UPPER,i);
           double MA_HIGH = iMA(NULL,0,4,0,MODE_LWMA,PRICE_HIGH,i);  
           
           double MADN1 = iMA(NULL,0,MAPeriod,-MoveShift,MODE_SMA,PRICE_LOW,i); 
           double BB_DN = iBands(NULL,0,BPeriod,Std,0,PRICE_LOW ,MODE_LOWER,i);
           double MA_LOW = iMA(NULL,0,4,0,MODE_LWMA,PRICE_LOW,i);  
                  
          if (MAUP1>BB_UP) {ExtMapBuffer1[i]=MAUP1+Dist2*Point; BB_UP=EMPTY_VALUE ;}     
          else if (MAUP1<BB_UP) {ExtMapBuffer1[i]=BB_UP ; MAUP1=EMPTY_VALUE ;}
//--------------------------------------------------------------------             
                                             
         if( MADN1 >0.0 ) 
         {
          if ( MADN1<BB_DN)  {ExtMapBuffer2[i]=MADN1-Dist2*Point; BB_DN=EMPTY_VALUE ;}                        
          else if (MADN1>BB_DN) { ExtMapBuffer2[i]=BB_DN ; MADN1=EMPTY_VALUE ; }
         }
       
         if (MADN1 ==0.0 ) { ExtMapBuffer2[i]=BB_DN; MADN1=EMPTY_VALUE ;}          
//------------------------------------------------------------       
       OsMA_Now = iOsMA(NULL,0,5,9,OsMA,PRICE_CLOSE,i) ;
       OsMA_Pre = iOsMA(NULL,0,5,9,OsMA,PRICE_CLOSE,i+1) ;

//-------------------
        if((OsMA_Now>0 && OsMA_Pre<0)&&(MA_LOW < ExtMapBuffer2[i]) && (Low[i] < ExtMapBuffer2[i]) ) 
       {
       //lower
        ExtMapBuffer3[i+1] = Low[i]-30*Point;
       }
              
       if((OsMA_Now<0 && OsMA_Pre>0) && (MA_HIGH > ExtMapBuffer1[i]) && (High[i] > ExtMapBuffer1[i]) ) 
       {
       //upper
        ExtMapBuffer4[i+1] = High[i]+30*Point;
       }  
              
       ExtMapBuffer5[i] = (ExtMapBuffer1[i] +ExtMapBuffer2[i])/2.0 ;
        
     } 
          
      static datetime previousLevel = -1; static int previousSignal = 0;
   
   if (alertsOn)
   {
      int currentBar=-1;
      
      for (i=0; i<Bars-1; i++) 
      {
       if (ExtMapBuffer3[i]!=EMPTY_VALUE || ExtMapBuffer4[i] !=EMPTY_VALUE) 
          
       {  
         currentBar = i; 
         break; }
       }
      if (currentBar>-1) 
          checkAlert(currentBar,previousLevel,previousSignal,ExtMapBuffer4, ExtMapBuffer3," ");
   }
               
   return(0);
   RefreshRates(); 
   
  } 
//--------------------------------

//+------------------------------------------------------------------+
//|                                                             
//+------------------------------------------------------------------+

void checkAlert(int currentBar, datetime& previousLevel, int& previousSignal, double& upBuffer[], double& dnBuffer[], string text)
{
   int previousBar = iBarShift(NULL,0,previousLevel);
   int currentSignal;
         if (upBuffer[currentBar]!=EMPTY_VALUE)                                      currentSignal = -1;
         if (dnBuffer[currentBar]!=EMPTY_VALUE)                                      currentSignal =  1;
         if (dnBuffer[currentBar]!=EMPTY_VALUE && upBuffer[currentBar]!=EMPTY_VALUE) currentSignal =  0;

   if (currentBar != previousBar || currentSignal != previousSignal)
   {
      if (currentSignal != previousSignal && currentBar > previousBar && previousLevel != -1)
            string alertText = "Reverted to ";
      else         alertText = "Signal ";            
      switch(currentSignal)
      {
         case  0 : doAlert(text+alertText+"UP/DOWN"); break;
         case  1 : doAlert(text+alertText+"UP");      break;
         case -1 : doAlert(text+alertText+"DOWN");
      }               
         
      previousLevel  = Time[currentBar];
      previousSignal = currentSignal;
   }
}

void doAlert(string doWhat)
{
   string message =  StringConcatenate(Symbol(),", ", TF2Str(Period()), " MA BBand ", doWhat , " @ ", TimeToStr(TimeLocal(),TIME_SECONDS));
      if (alertsMessage) Alert(message);
      if (alertsEmail)   SendMail(StringConcatenate(Symbol(),"Fractals"),message);
      if (alertsSound)   PlaySound("alert2.wav");
}

string TF2Str(int period)
  {
   switch(period)
     {
      case PERIOD_M1: return("M1");
      case PERIOD_M5: return("M5");
      case PERIOD_M15: return("M15");
      case PERIOD_M30: return("M30");
      case PERIOD_H1: return("H1");
      case PERIOD_H4: return("H4");
      case PERIOD_D1: return("D1");
      case PERIOD_W1: return("W1");
      case PERIOD_MN1: return("MN");
     }
   return(Period());
  }
//+------------------------------------------------------------------+