//+------------------------------------------------------------------+
//|                                           Awesome Oscillator.mq4 |
//|                                         Arrows and Alerts by cja |
//+------------------------------------------------------------------+
#property  copyright "Copyright © 2005, MetaQuotes Software Corp."
#property  link      "http://www.metaquotes.net/"
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 3
#property  indicator_color1  Black
#property  indicator_color2  Green
#property  indicator_color3  Red
extern string LLLLLLLLLLLLLL_Arrow_settings = "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL";
extern bool   ShowArrows         = true;   
extern color  LongSignalColor    = Aqua; 
extern color  ShortSignalColor   = Red;
extern double ArrowDistanceUp    = 3; 
extern double ArrowDistanceDn    = 2; 
extern int    ArrowsUpCode       = 225;
extern int    ArrowsDownCode     = 226;
extern int    ArrowsSize         = 1;
extern string LLLLLLLLLLLLLL_Alert_settings = "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL";
      
extern bool   AlertsOn           = false;
extern bool   AlertsMessage      = true;
extern bool   AlertsSound        = true;
extern string AlertSoundFile     = "alert2.wav";
extern bool   AlertsEmail        = false;
extern bool   AlertsOnCurrent    = true;

//---- indicator buffers
double     ExtBuffer0[];
double     ExtBuffer1[];
double     ExtBuffer2[];

int TimeFrame;
string TF;

double myPoint;
   double SetPoint() 
   { double mPoint; 
   if (Digits < 4) 
   mPoint = 0.01; 
   else
   mPoint = 0.0001; 
   return(mPoint); 
   }  
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   myPoint = SetPoint(); 
  
   //---- drawing settings
   SetIndexStyle(0,DRAW_NONE);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexStyle(2,DRAW_HISTOGRAM);
   IndicatorDigits(Digits+1);
   SetIndexDrawBegin(0,34);
   SetIndexDrawBegin(1,34);
   SetIndexDrawBegin(2,34);
//---- 3 indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer0);
   SetIndexBuffer(1,ExtBuffer1);
   SetIndexBuffer(2,ExtBuffer2);
  
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("AO");
   SetIndexLabel(1,NULL);
   SetIndexLabel(2,NULL);
   
      switch(TimeFrame)
   {  
      case 1 : TF="Period M1"; break;
      case 5 : TF="Period M5"; break;
      case 15 : TF="Period M15"; break;
      case 30 : TF="Period M30"; break;
      case 60 : TF="Period H1"; break;
      case 240 : TF="Period H4"; break;
      case 1440 : TF="Period D1"; break;
      case 10080 : TF="Period W1"; break;
      case 43200 : TF="Period MN1"; break;
      default : TimeFrame=Period();init(); return(0);
      } 
     
//---- initialization done
   return(0);
  }
  //+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   deleteArrows();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Awesome Oscillator                                               |
//+------------------------------------------------------------------+
int start()
  {
   int    limit;
   int    counted_bars=IndicatorCounted();
   double prev,current;
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- macd
   for(int i=0; i<limit; i++)
      ExtBuffer0[i]=iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN,i)-iMA(NULL,0,34,0,MODE_SMA,PRICE_MEDIAN,i);
//---- dispatch values between 2 buffers
   bool up=true;
   for(i=limit-1; i>=0; i--)
     {
      current=ExtBuffer0[i];
      prev=ExtBuffer0[i+1];
      if(current>prev) up=true;
      if(current<prev) up=false;
      if(!up)
        {
         ExtBuffer2[i]=current;
         ExtBuffer1[i]=0.0;
        }
      else
        {
         ExtBuffer1[i]=current;
         ExtBuffer2[i]=0.0;
        }
     
     
        if (AlertsOn) 
        { 
      if (AlertsOnCurrent)
           int bar = 0;
      else     bar = 1; bar = iBarShift(NULL,0,iTime(NULL,0,bar));      
        if ((ExtBuffer1[bar]>ExtBuffer1[bar+1]&&ExtBuffer2[bar]<ExtBuffer2[bar+1]&&ExtBuffer0[bar]>0)||(ExtBuffer1[bar]<ExtBuffer1[bar+1]&&ExtBuffer2[bar]>ExtBuffer2[bar+1]&&ExtBuffer0[bar]<0))doAlert(" LONG ");
        if ((ExtBuffer2[bar]>ExtBuffer2[bar+1]&&ExtBuffer1[bar]<ExtBuffer1[bar+1]&&ExtBuffer0[bar]>0)||(ExtBuffer2[bar]<ExtBuffer2[bar+1]&&ExtBuffer1[bar]>ExtBuffer1[bar+1]&&ExtBuffer0[bar]<0))doAlert(" SHORT "); 
       }    
      deleteArrow(Time[i]);
        if (ShowArrows && ((ExtBuffer2[i]>ExtBuffer2[i+1]&&ExtBuffer1[i]<ExtBuffer1[i+1]&&ExtBuffer0[i]>0)||(ExtBuffer2[i]<ExtBuffer2[i+1]&&ExtBuffer1[i]>ExtBuffer1[i+1]&&ExtBuffer0[i]<0))) drawArrow(i,ShortSignalColor,ArrowsDownCode,true);
        if (ShowArrows && ((ExtBuffer1[i]>ExtBuffer1[i+1]&&ExtBuffer2[i]<ExtBuffer2[i+1]&&ExtBuffer0[i]>0)||(ExtBuffer1[i]<ExtBuffer1[i+1]&&ExtBuffer2[i]>ExtBuffer2[i+1]&&ExtBuffer0[i]<0))) drawArrow(i,LongSignalColor,ArrowsUpCode,false);
        }
//---- done
   return(0);
  }
  
        
   void drawArrow(int shift,color theColor,int theCode,bool up)
   {
   string name = ":"+Time[shift];
        
      ObjectCreate(name,OBJ_ARROW,0,Time[shift],0);
         ObjectSet(name,OBJPROP_ARROWCODE,theCode);
         ObjectSet(name,OBJPROP_COLOR,theColor);
         ObjectSet(name,OBJPROP_WIDTH,ArrowsSize);
         ObjectSet(name,OBJPROP_BACK,false);
         if (up)
               ObjectSet(name,OBJPROP_PRICE1,High[shift]+ ArrowDistanceUp*myPoint);
         else  ObjectSet(name,OBJPROP_PRICE1,Low[shift] - ArrowDistanceDn*myPoint);
   }


   void deleteArrows()
   {
   string lookFor       = ":";
   int    lookForLength = StringLen(lookFor);
   for (int shift=ObjectsTotal()-1; shift>=0; shift--)
   {
      string objectName = ObjectName(shift);
         if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
      }
   }
   void deleteArrow(datetime time)
   {
   string lookFor = ":"+time; ObjectDelete(lookFor);
   }
   
   
void doAlert(string doesWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doesWhat || previousTime != Time[0]) {
          previousAlert  = doesWhat;
          previousTime   = Time[0];
          
           	switch(TimeFrame)
	{
		case 1:		TF="M1";  break;
		case 5:		TF="M5";  break;
		case 15:		TF="M15"; break;
		case 30:		TF="M30"; break;
		case 60:		TF="H1";  break;
		case 240:	TF="H4";  break;
		case 1440:	TF="D1";  break;
		case 10080:	TF="W1";  break;
		case 43200:	TF="MN1"; break;
		default:	  {TimeFrame = Period(); init(); }
	}
      
          //
          //
          //
          //
          //
            
          message =  StringConcatenate(Symbol()," ",TF," ",
                                                "  AO  : ", doesWhat," @ ",DoubleToStr(Close[0],Digits));
             if (AlertsMessage) Alert(message);
             if (AlertsSound)   PlaySound(AlertSoundFile);
             if (AlertsEmail)   SendMail(StringConcatenate(Symbol()," AO "),message);
      }        
}