//------------------------------------------------------------------
#property link      "https://howtofxmarkets.web.app/"
#property copyright "https://howtofxmarkets.web.app/ StochDoubleLevelFilterMTF by csj179t"
//   - Forex education, mentorship, signals, trading rooms.
//   - Low cost and high leverage, regulated broker. With a lot of FREE additional services.
//   - And a Guide-o-FX is a list of FREE useful forex resources.
//------------------------------------------------------------------
#property copyright "www.forex-station.com"
// Many thanks to forex-station.com, to mrtools, mladen
// and other coder helping for free. Special thanks to Jimmy!
// I got this code template at forex-station:  bars iterator, mtf feature...
// And making my indicators, by editing modifying it.

#property indicator_separate_window
#property indicator_buffers    6
#property indicator_color1     clrGreen
#property indicator_width1     2
#property indicator_color2     clrRed
#property indicator_width2     2
#property indicator_color3    clrWhite
#property indicator_width3     2
#property indicator_color4     clrWhite
#property indicator_width4    2
#property indicator_color5    clrWhite
#property indicator_width5    2
#property indicator_color6    clrWhite
#property indicator_width6    2


#property indicator_minimum 0
#property indicator_maximum 100


extern ENUM_TIMEFRAMES           TimeFrame       = PERIOD_CURRENT;
extern int k_period=5;
extern int d_period= 3;
extern int slowing =3;
extern int stoch_mode = 0;
extern ENUM_STO_PRICE stoch_price = STO_LOWHIGH;
input bool               alertsOn                   = false;            // Turn alerts on?
input bool               alertsOnCurrent            = false;            // Alerts on still opened bar?
input bool               alertsMessage              = true;             // Alerts should display message?
input bool               alertsSound                = false;            // Alerts should play a sound?
input bool               alertsNotify               = false;            // Alerts should send a notification?
input bool               alertsEmail                = false;     // Alerts should send an email?
input string             soundFile                  = "alert2.wav";     // Sound file
input bool               arrowsVisible              = true;            // Show arrows?
input bool               arrowsOnNewest             = false;            // Arrows drawn on newest bar of higher time frame bar true/false?
input string             arrowsIdentifier           = "StochDoubleLevel arrows";    // Arrows ID
input double             arrowsUpperGap             = 0.5;              // Arrows Upper Gap
input double             arrowsLowerGap             = 0.5;              // Arrows lower gap
input color              arrowsUpColor  = clrLimeGreen;     //  Up arrow color
input color              arrowsDnColor  = clrRed;           //  Down arrows color
input int                arrowsUpCode   = 241;              //  Up arrow code
input int                arrowsDnCode   = 242;              //  Down arrow code
input int                arrowsUpSize   = 2;                //  Up arrow size
input int                arrowsDnSize   = 2;                //  Down arrow size
extern int dnLvl1 = 10;
extern int dnLvl2 = 15;
extern int upLvl1 = 85;
extern int upLvl2 = 90;
extern bool               Interpolate   = true;

extern string             nameInd = "StochDoubleLevelFilterMTF";


double buffer1[];
double buffer2[];
double buffer3[];
double buffer4[];
double buffer5[];
double buffer6[];
double trend[];

string indicatorFileName;
bool   returnBars;

string name2 = nameInd + " " + TimeFrame;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {




   IndicatorBuffers(7);
   SetIndexBuffer(0,buffer1);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,buffer2);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,buffer3);
   SetIndexStyle(2,DRAW_LINE,STYLE_DOT,1,clrWhite);
   SetIndexBuffer(3,buffer4);
   SetIndexStyle(3,DRAW_LINE,STYLE_DOT,1,clrWhite);
   SetIndexBuffer(4,buffer5);
   SetIndexStyle(4,DRAW_LINE,STYLE_DOT,1,clrWhite);
   SetIndexBuffer(5,buffer6);
   SetIndexStyle(5,DRAW_LINE,STYLE_DOT,1,clrWhite);
   SetIndexBuffer(6,trend);


   indicatorFileName = WindowExpertName();
   returnBars        = TimeFrame==-99;
   TimeFrame         = fmax(TimeFrame,_Period);

   IndicatorShortName(name2);

   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 counted_bars=IndicatorCounted();
   int i,limit;


   if(counted_bars < 0)
      return(-1);
   if(counted_bars > 0)
      counted_bars--;
   limit = MathMin(Bars-counted_bars,Bars-1);
   if(returnBars)
     {
      buffer1[0] = limit+1;
      return(0);
     }


   if(TimeFrame == Period())
     {

      for(i=limit; i>=0; i--)
        {




         buffer1[i] =   iStochastic(NULL,0,k_period,d_period,slowing,stoch_mode,stoch_price,MODE_MAIN,i);
         buffer2[i] =   iStochastic(NULL,0,k_period,d_period,slowing,stoch_mode,stoch_price,MODE_SIGNAL,i);
         buffer3[i] =   dnLvl1;
         buffer4[i] =   dnLvl2;
         buffer5[i] =   upLvl1;
         buffer6[i] =   upLvl2;

         //UP
         trend[i]=0;
         if(buffer1[i] > dnLvl2 && buffer1[i+1] < dnLvl2)
           {
            for(int b=1; b <= 5; b++)
              {
               if(buffer1[i+b] > dnLvl2)
                  break;
               trend[i] =   buffer1[i+b] <= dnLvl1 ? 1 : 0   ;
               if(trend[i] == 1)
                  break;
              }
           }

         //Down
         if(buffer1[i] < upLvl1 && buffer1[i+1] > upLvl1)
           {
            for(int s=1; s <= 5; s++)
              {
               if(buffer1[i+s] < upLvl1)
                  break;
               trend[i] =   buffer1[i+s] >= upLvl2 ? -1 : 0   ;
               if(trend[i] == -1)
                  break;
              }
           }


         if(arrowsVisible)
           {
            ObjectDelete(arrowsIdentifier+":1:"+(string)Time[i]);
            string lookFor = arrowsIdentifier+":"+(string)Time[i];
            ObjectDelete(lookFor);

            if(trend[i+1] != 1 && trend[i]== 1)
               drawArrow("1",0.5,i,arrowsUpColor,arrowsUpCode,arrowsUpSize,false);
            if(trend[i+1] !=-1 && trend[i]==-1)
               drawArrow("1",0.5,i,arrowsDnColor,arrowsDnCode,arrowsDnSize,true);


           }
        }


      if(alertsOn)
        {
         int whichBar = 1;
         if(alertsOnCurrent)
            whichBar = 0;
         static datetime time1 = 0;
         static string   mess1 = "";

         if(trend[whichBar+1] ==-1 && trend[whichBar]!=-1)
            doAlert(time1,mess1,whichBar,"crossing upper level down");
         if(trend[whichBar+1] == 1 && trend[whichBar]!= 1)
            doAlert(time1,mess1,whichBar,"crossing lower level up");

        }

      return(0);
     }



   limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/Period()));
   for(i=limit; i>=0; i--)
     {
      int y = iBarShift(NULL,TimeFrame,Time[i]);

      buffer1[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,k_period,d_period,slowing,stoch_mode,stoch_price,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,dnLvl1,dnLvl2,upLvl1,upLvl2,0,y);
      buffer2[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,k_period,d_period,slowing,stoch_mode,stoch_price,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,dnLvl1,dnLvl2,upLvl1,upLvl2,1,y);
      buffer3[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,k_period,d_period,slowing,stoch_mode,stoch_price,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,dnLvl1,dnLvl2,upLvl1,upLvl2,2,y);
      buffer4[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,k_period,d_period,slowing,stoch_mode,stoch_price,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,dnLvl1,dnLvl2,upLvl1,upLvl2,3,y);
      buffer5[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,k_period,d_period,slowing,stoch_mode,stoch_price,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,dnLvl1,dnLvl2,upLvl1,upLvl2,4,y);
      buffer6[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,k_period,d_period,slowing,stoch_mode,stoch_price,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,dnLvl1,dnLvl2,upLvl1,upLvl2,5,y);

      //
      //
      //
      //
      //

      if(!Interpolate || y==iBarShift(NULL,TimeFrame,Time[i-1]))
         continue;

      //
      //
      //
      //
      //

      datetime time = iTime(NULL,TimeFrame,y);
      for(int n = 1; i+n < Bars && Time[i+n] >= time; n++)
         continue;
      for(int x = 1; x < n; x++)
        {

         buffer1[i+x] = buffer1[i] + (buffer1[i+n] - buffer1[i]) * x/n;
         buffer2[i+x] = buffer2[i] + (buffer2[i+n] - buffer2[i]) * x/n;
         buffer3[i+x] = buffer3[i] + (buffer3[i+n] - buffer3[i]) * x/n;
         buffer4[i+x] = buffer4[i] + (buffer4[i+n] - buffer4[i]) * x/n;
         buffer5[i+x] = buffer5[i] + (buffer5[i+n] - buffer5[i]) * x/n;
         buffer6[i+x] = buffer6[i] + (buffer6[i+n] - buffer6[i]) * x/n;


        }
     }







   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 doAlert(datetime& previousTime, string& previousAlert, int forBar, string doWhat)
  {
   string message;

   if(previousAlert != doWhat || previousTime != Time[forBar])
     {
      previousAlert  = doWhat;
      previousTime   = Time[forBar];

      //
      //
      //
      //
      //

      message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" Stochastic Rsi "+doWhat;
      if(alertsMessage)
         Alert(message);
      if(alertsNotify)
         SendNotification(message);
      if(alertsEmail)
         SendMail(_Symbol+" Stochastic Rsi ",message);
      if(alertsSound)
         PlaySound(soundFile);
     }
  }





//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void drawArrow(string nameAdd, double gapMul, int i,color theColor, int theCode, int theWidth, bool up)
  {
   string name = arrowsIdentifier+":"+nameAdd+":"+(string)Time[i];
   double gap  = iATR(NULL,0,20,i)*gapMul;

//
//
//
//
//

   datetime atime = Time[i];
   if(arrowsOnNewest)
      atime += _Period*60-1;
   ObjectCreate(name,OBJ_ARROW,0,atime,0);
   ObjectSet(name,OBJPROP_ARROWCODE,theCode);
   ObjectSet(name,OBJPROP_WIDTH,theWidth);
   ObjectSet(name,OBJPROP_COLOR,theColor);
   if(up)
      ObjectSet(name,OBJPROP_PRICE1,High[i] + arrowsUpperGap * gap);
   else
      ObjectSet(name,OBJPROP_PRICE1,Low[i]  - arrowsLowerGap * gap);
  }
//+------------------------------------------------------------------+
