#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  clrLimeGreen      
#property indicator_color2  clrRed      

extern int                RsiPeriod1      = 14;
extern ENUM_APPLIED_PRICE RsiPrice1       = PRICE_CLOSE;
extern int                RsiPeriod2      = 32;
extern ENUM_APPLIED_PRICE RsiPrice2       = PRICE_CLOSE;
extern bool               alertsOn        = false; 
extern bool               alertsOnCurrent = true;  
extern bool               alertsMessage   = true;  
extern bool               alertsSound     = false; 
extern bool               alertsPushNotif = false; 
extern bool               alertsEmail     = false; 
input bool                arrowsVisible   = false;            // Arrows visible true/false?
//input bool                arrowsOnNewest  = false;            // Arrows drawn on newest bar of higher time frame bar true/false?
input string              arrowsIdentifier= "rsi Arrows1";    // Unique ID for arrows
input double              arrowsUpperGap  = 1.0;              // Upper arrow gap
input double              arrowsLowerGap  = 1.0;              // Lower arrow gap
input color               arrowsUpColor   = clrBlue;          // Up arrow color
input color               arrowsDnColor   = clrCrimson;       // Down arrow color
input int                 arrowsUpCode    = 221;              // Up arrow code    
input int                 arrowsDnCode    = 222;              // Down arrow code
input int                 arrowsUpSize    = 2;                // Up arrow size
input int                 arrowsDnSize    = 2;                // Down arrow size

double rsi1[],rsi2[],cross[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------


int init()
{
   IndicatorBuffers(3);
   SetIndexBuffer(0,rsi1);
   SetIndexBuffer(1,rsi2);
   SetIndexBuffer(2,cross);
   return(0); 
}
void OnDeinit(const int reason)  {  ObjectsDeleteAll(0,arrowsIdentifier+":"); }

//------------------------------------------------------------------
//
//------------------------------------------------------------------

int start()                         
{
   int counted_bars = IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);

   for(int i = limit; i >= 0; i--) 
   {
      rsi1[i]  = iRSI(NULL,0,RsiPeriod1,RsiPrice1,i);
      rsi2[i]  = iRSI(NULL,0,RsiPeriod2,RsiPrice2,i);
      cross[i] = cross[i+1];
      if (rsi1[i]>rsi2[i] && rsi1[i+1]<=rsi2[i+1] && rsi2[i]>50) cross[i] =  1;
      if (rsi1[i]<rsi2[i] && rsi1[i+1]>=rsi2[i+1] && rsi2[i]<50) cross[i] = -1;
      
      //
      //
      //
         
      if (arrowsVisible)
      {
         string lookFor = arrowsIdentifier+":"+(string)Time[i]; if (ObjectFind(0,lookFor)==0) ObjectDelete(0,lookFor);                       
         if (i<(Bars-1) && cross[i] != cross[i+1])
         {
            if (cross[i] == 1) drawArrow(i,arrowsUpColor,arrowsUpCode,arrowsUpSize,false);
            if (cross[i] ==-1) drawArrow(i,arrowsDnColor,arrowsDnCode,arrowsDnSize, true);
         }
       }    
   }
   manageAlerts();
   return(0);                       
}

//-------------------------------------------------------------------
//                                                                  
//-------------------------------------------------------------------
//
//
//
//
//

void manageAlerts()
{
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0;
      if (cross[whichBar] != cross[whichBar+1])
      {
         if (cross[whichBar] ==  1) doAlert(whichBar,"rsi "+RsiPeriod1+" crossed "+RsiPeriod2+" up");
         if (cross[whichBar] == -1) doAlert(whichBar,"rsi "+RsiPeriod1+" crossed "+RsiPeriod2+" 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)+" rsi cross "+doWhat;
          if (alertsMessage)   Alert(message);
          if (alertsEmail)     SendMail(_Symbol+" rsi cross",message);
          if (alertsPushNotif) SendNotification(message);
          if (alertsSound)     PlaySound("alert2.wav");
   }
}

//-------------------------------------------------------------------
//                                                                  
//-------------------------------------------------------------------

void drawArrow(int i,color theColor,int theCode, int theSize, bool up)
{
   string aname = arrowsIdentifier+":"+(string)Time[i];
   double gap   = iATR(NULL,0,20,i);   
   
      //
      //
      //

      datetime atime = Time[i]; //if (arrowsOnNewest) atime += PeriodSeconds(_Period)-1; 
      ObjectCreate(aname,OBJ_ARROW,0,atime,0);
         ObjectSet(aname,OBJPROP_ARROWCODE,theCode);
         ObjectSet(aname,OBJPROP_COLOR,theColor);
         ObjectSet(aname,OBJPROP_WIDTH,theSize);
         if (up)
               ObjectSet(aname,OBJPROP_PRICE1,High[i] + arrowsUpperGap * gap);
         else  ObjectSet(aname,OBJPROP_PRICE1,Low[i]  - arrowsLowerGap * gap);
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------

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("");
}

