//+------------------------------------------------------------------+
//|                                              V2 START ARROW .mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_chart_window

#property indicator_buffers 2
#property indicator_color1 clrRed
#property indicator_color2 clrLime

input int CountBars = 500;
input int period = 1;
input int Len=7;
input double  Filter   =  0.0;

extern bool               alertsOn             = false;            // Alerts on?
extern bool               alertsOnCurrent      = false;            // Alerts on current open bar?
extern bool               alertsMessage        = false;            // Alerts message?
extern bool               alertsSound          = false;            // Alerts sound?
extern bool               alertsNotify         = false;            // Alerts notification by phone?


double bufferUP[],bufferDN[];

double ExtBuffer0[];
double Up[];
double Down[];

double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double trend[],value[];

double rsx[];
double jrhi[];
double jrlo[];

int init(){
   IndicatorBuffers(14);
   IndicatorDigits(_Digits+1);
   
   SetIndexLabel(0,NULL);
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,234);
   SetIndexBuffer(0,bufferDN);
   SetIndexLabel(1,NULL);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,233);
   SetIndexBuffer(1,bufferUP);
   
   
   SetIndexBuffer(2,ExtBuffer0);
   SetIndexBuffer(3,Up);
   SetIndexBuffer(4,Down);
   SetIndexDrawBegin(3,Bars-CountBars+period);
   SetIndexDrawBegin(4,Bars-CountBars+period);
   
   
   SetIndexBuffer(5, ExtMapBuffer1);
   SetIndexBuffer(6, ExtMapBuffer2);
   SetIndexBuffer(7, ExtMapBuffer3);
   SetIndexBuffer(8, ExtMapBuffer4);
   SetIndexBuffer(9,trend);
   SetIndexDrawBegin(5,10);
   SetIndexDrawBegin(6,10);
   
   SetIndexBuffer(10,rsx);
   SetIndexBuffer(11,jrhi);
   SetIndexBuffer(12,jrlo);
   SetIndexBuffer(13,value);
   return(0);}

int start(){
   
   int i,counted_bars=IndicatorCounted();
   bool Pr=false,PrevPr=false;
   double val,val2;
   int limit;
   
   if(Bars<=CountBars)return(0);
   
   //================
   if(counted_bars<1){ 
   for(i=1;i<=period;i++)Up[CountBars-i]=0.0;
   for(i=1;i<=period;i++)Down[CountBars-i]=0.0;
   }
   
   i=CountBars-period-1;
   limit = CountBars-period-1;
   while(i>=0){
   val=iMA(NULL,0,period,1,MODE_SMA,PRICE_HIGH,i);
   val2=iMA(NULL,0,period,1,MODE_SMA,PRICE_LOW,i);
   if (Close[i]<val2 && PrevPr==true)Pr=false;
   if (Close[i]>val && PrevPr==false)Pr=true;
   PrevPr=Pr;
   Up[i]=0.0;
   Down[i]=0.0;
   if (Pr==false)Up[i] = val+2*Point; 
   if (Pr==true)Down[i] = val2-2*Point; 
   i--; 
   } 
   //====================
   double haOpen, haHigh, haLow, haClose;
   if (counted_bars<0) return(-1);
//---- last counted bar will be recounted
   if (counted_bars>0) counted_bars--;
   int pos=limit;
   
   while(pos>=0)
     {
      haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
      haClose=(Open[pos]+High[pos]+Low[pos]+Close[pos])/4;
      haHigh=MathMax(High[pos], MathMax(haOpen, haClose));
      haLow=MathMin(Low[pos], MathMin(haOpen, haClose));
      trend[pos]=trend[pos+1];
      if (haOpen<haClose) 
        {
         trend[pos]=1;
         ExtMapBuffer1[pos]=0;
         ExtMapBuffer2[pos]=1;
        } 
      else
        {
         trend[pos]=-1;
         ExtMapBuffer1[pos]=1;
         ExtMapBuffer2[pos]=0;
        } 
      ExtMapBuffer3[pos]=haOpen;
      ExtMapBuffer4[pos]=haClose;
 	   pos--;
     }
   //==========================
   double f88, f90;
   double f0, v4, v8, vC, v10, v14, v18, v20;
   double f8, f10, f18, f20, f28, f30, f38, f48, v1C;
   double f50, f58, f60, f68, f70, f78, f80, f40;
   
   
   for (int shift=limit;shift>=0;shift--) {
      if (f90 == 0.0) {
      
         f90 = 1.0;
         f0 = 0.0;
         if (Len-1 >= 5) f88 = Len-1.0; else f88 = 5.0;
         f8 = 100.0*((High[shift]+Low[shift]+Close[shift])/3);
         f18 = 3.0 / (Len + 2.0);
         f20 = 1.0 - f18;
         
      } else{
         if (f88 <= f90) f90 = f88 + 1; else f90 = f90 + 1;
         f10 = f8;
         f8 = 100.0*((High[shift]+Low[shift]+Close[shift])/3);
         v8 = f8 - f10;
         f28 = f20 * f28 + f18 * v8;
         f30 = f18 * f28 + f20 * f30;
         vC = f28 * 1.5 - f30 * 0.5;
         f38 = f20 * f38 + f18 * vC;
         f40 = f18 * f38 + f20 * f40;
         v10 = f38 * 1.5 - f40 * 0.5;
         f48 = f20 * f48 + f18 * v10;
         f50 = f18 * f48 + f20 * f50;
         v14 = f48 * 1.5 - f50 * 0.5;
         f58 = f20 * f58 + f18 * MathAbs(v8);
         f60 = f18 * f58 + f20 * f60;
         v18 = f58 * 1.5 - f60 * 0.5;
         f68 = f20 * f68 + f18 * v18;

         f70 = f18 * f68 + f20 * f70;
         v1C = f68 * 1.5 - f70 * 0.5;
         f78 = f20 * f78 + f18 * v1C;
         f80 = f18 * f78 + f20 * f80;
         v20 = f78 * 1.5 - f80 * 0.5;

         if ((f88 >= f90) && (f8 != f10)) f0 = 1.0;
         if ((f88 == f90) && (f0 == 0.0)) f90 = 0.0;
      }

      if ((f88 < f90) && (v20 > 0.0000000001)) {

         v4 = (v14 / v20 + 1.0) * 50.0;
         if (v4 > 100.0) v4 = 100.0;
         if (v4 < 0.0) v4 = 0.0;

      } else {
         v4 = 50.0;
      }
      
      rsx[shift]=v4;
      jrhi[shift]=v4;
      jrlo[shift]=v4;

      if (rsx[shift] > rsx[shift+1]-Filter)
      {
          jrlo[shift] = EMPTY_VALUE;
      }
      else if (rsx[shift] < rsx[shift+1]+Filter) 
      {
          jrhi[shift] = EMPTY_VALUE;
      }
      else if (rsx[shift] == rsx[shift+1]+Filter) 
      {
          jrhi[shift] = EMPTY_VALUE;
          jrlo[shift] = EMPTY_VALUE;
      }
   }
   //================
   for(i=limit;i>=0;i--)
   {
      value[i] = 0;
      bufferUP[i] = bufferDN[i] = EMPTY_VALUE;
      if(Up[i]  !=0.0  && trend[i]== 1 && rsx[i]>rsx[i+1]-Filter) value[i] = 1;
      if(Down[i]!=0.0  && trend[i]==-1 && rsx[i]<rsx[i+1]-Filter) value[i] =-1;
      
      if (value[i] != value[i+1])
      {
         if (value[i] == 1) bufferUP[i]=Low[i] -0.5*iATR(_Symbol,0,5,i);
         if (value[i] ==-1) bufferDN[i]=High[i]+0.5*iATR(_Symbol,0,5,i);
      }
   }
     
   manageAlerts();   
     
return(0);}

void manageAlerts()
{
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0;
      if (bufferDN[whichBar] != EMPTY_VALUE || bufferUP[whichBar] != EMPTY_VALUE)
      {
         if (bufferUP[whichBar] != EMPTY_VALUE && bufferUP[whichBar+1] == EMPTY_VALUE) doAlert(whichBar,"up");
         if (bufferDN[whichBar] != EMPTY_VALUE && bufferDN[whichBar+1] == EMPTY_VALUE) doAlert(whichBar,"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 =  StringConcatenate(Symbol()," ",timeFrameToString(_Period)+" signal ",doWhat);
          if (alertsMessage) Alert(message);
          if (alertsNotify)  SendNotification(message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}

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("");
}
