
//------------------------------------------------------------------
#property copyright "mrtools"
#property link      "www.forex-station.com"
//------------------------------------------------------------------

#property indicator_separate_window
#property indicator_buffers    5
#property indicator_color1     clrLimeGreen
#property indicator_color2     clrGreen
#property indicator_color3     clrRed
#property indicator_color4     clrMaroon
#property indicator_color5     clrDarkSlateGray
#property indicator_width1     2
#property indicator_width2     2
#property indicator_width3     2
#property indicator_width4     2
#property indicator_width5     2
#property indicator_level1     0
#property indicator_levelcolor clrSlateGray
#property strict

//
//
//
//
//

extern double             pas              = 0.02;              // Accumulation step
extern double             max              = 0.2;               // Accumulation limit
extern bool               alertsOn         = true;              // Turn alerts on?
extern bool               alertsOnCurrent  = false;             // Alerts on current (still opened) bar?
extern bool               alertsMessage    = true;              // Alerts should show pop-up message?
extern bool               alertsSound      = false;             // Alerts should play a sound?
extern bool               alertsEmail      = false;             // Alerts should send email?
extern bool               alertsPushNotif  = false;             // Alerts should send push notification?
extern bool               arrowsVisible    = false;             // Show arrows
extern string             arrowsIdentifier = "sar Arrows1";     // Arrows unique ID
extern double             arrowsUpperGap   = 0.5;               // Arrows upper gap
extern double             arrowsLowerGap   = 0.5;               // Arrows lower gap
extern color              arrowsUpColor    = clrLimeGreen;      // Up arrow color   
extern color              arrowsDnColor    = clrRed;            // Down arrow color
extern int                arrowsUpCode     = 241;               // Up arrow code
extern int                arrowsDnCode     = 242;               // Down arrow code
extern bool               arrowsUpSize     = 2;                 // Up arrow size
extern bool               arrowsDnSize     = 2;                 // Down arrow size

double sar[],sarhuu[],sarhud[],sarhdd[],sarhdu[],trend[],slope[];

//
//
//
//
//

int OnInit()
{
   IndicatorBuffers(7);   
   SetIndexBuffer(0,sarhuu); SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(1,sarhud); SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(2,sarhdd); SetIndexStyle(2, DRAW_HISTOGRAM);
   SetIndexBuffer(3,sarhdu); SetIndexStyle(3, DRAW_HISTOGRAM);
   SetIndexBuffer(4,sar);    SetIndexStyle(4, DRAW_LINE);
   SetIndexBuffer(5,trend);
   SetIndexBuffer(6,slope);
  
   IndicatorShortName("Psar oscillator");
return(INIT_SUCCEEDED);
}
int deinit() 
{ 
   string lookFor       = arrowsIdentifier+":";
   int    lookForLength = StringLen(lookFor);
   for (int i=ObjectsTotal()-1; i>=0; i--)
   {
      string objectName = ObjectName(i);
         if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
   }
return(0); 
} 	  

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int start()
{
   int i,counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1); 
         
   //
   //
   //
   //
   //
   
   for(i=limit; i>=0; i--)
   {
      sar[i] = Close[i]-iSAR(NULL,0,pas,max,i);
      slope[i] = (i<Bars-1) ? (sar[i]>sar[i+1]) ? 1 : (sar[i]<sar[i+1]) ? -1 :  slope[i+1] : 0;
      trend[i] = (i<Bars-1) ? (sar[i]>0)        ? 1 : (sar[i]<0)        ? -1 :  trend[i+1] : 0;
      sarhuu[i] = (trend[i] == 1 && slope[i] == 1) ? sar[i] : EMPTY_VALUE;
      sarhud[i] = (trend[i] == 1 && slope[i] ==-1) ? sar[i] : EMPTY_VALUE;
      sarhdd[i] = (trend[i] ==-1 && slope[i] ==-1) ? sar[i] : EMPTY_VALUE;
      sarhdu[i] = (trend[i] ==-1 && slope[i] == 1) ? sar[i] : EMPTY_VALUE;  
      
      //
      //
      //
      //
      //
      
      if (arrowsVisible)
      {
         string lookFor = arrowsIdentifier+":"+(string)Time[i]; ObjectDelete(lookFor);            
         if (i<(Bars-1) && trend[i] != trend[i+1])
         {
            if (trend[i] == 1) drawArrow(i,arrowsUpColor,arrowsUpCode,arrowsUpSize,false);
            if (trend[i] ==-1) drawArrow(i,arrowsDnColor,arrowsDnCode,arrowsDnSize, true);
         }
       }         
   }
manageAlerts();   
return(0);
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

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("");
}

//-------------------------------------------------------------------
//                                                                  
//-------------------------------------------------------------------
//
//
//
//
//

void manageAlerts()
{
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0;
      if (trend[whichBar] != trend[whichBar+1])
      {
         if (trend[whichBar]== 1) doAlert(whichBar,"crossing zero up");
         if (trend[whichBar]==-1) doAlert(whichBar,"crossing zero down");
      }
   }
}

//
//
//
//
//

void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];

       //
       //
       //
       //
       //

       message = timeFrameToString(_Period)+" "+Symbol()+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" Sar oscillator "+doWhat;
          if (alertsMessage)   Alert(message);
          if (alertsEmail)     SendMail(StringConcatenate(Symbol()," Sar oscillator "),message);
          if (alertsPushNotif) SendNotification(message);
          if (alertsSound)     PlaySound("alert2.wav");
   }
}

//-------------------------------------------------------------------
//                                                                  
//-------------------------------------------------------------------
//
//
//
//
//

void drawArrow(int i,color theColor,int theCode, int theWidth, bool up)
{
   string name = arrowsIdentifier+":"+(string)Time[i];
   double gap  = iATR(NULL,0,20,i);   
   
      //
      //
      //
      //
      //

     // datetime time = Time[i]; if (arrowsOnNewest) time += _Period*60-1;      
      ObjectCreate(name,OBJ_ARROW,0,Time[i],0);
         ObjectSet(name,OBJPROP_COLOR,theColor);
         ObjectSet(name,OBJPROP_ARROWCODE,theCode);
         ObjectSet(name,OBJPROP_WIDTH,theWidth);
         if (up)
               ObjectSet(name,OBJPROP_PRICE1,High[i] + arrowsUpperGap * gap);
         else  ObjectSet(name,OBJPROP_PRICE1,Low[i]  - arrowsLowerGap * gap);
}
