//------------------------------------------------------------------
#property link      "https://howtofxmarkets.web.app/"
#property copyright "https://howtofxmarkets.web.app/ fibStoch by csj179t"
//   - Forex educational courses, mentorship, trading rooms.
//   - Low (spread+commission) or even no commission forex broker, with a lot of 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   5
#property indicator_color1     clrGreen
#property indicator_width1     2
#property indicator_color2     clrRed
#property indicator_width2     2
#property indicator_color3    clrWhite
#property indicator_width3     1


extern ENUM_TIMEFRAMES    TimeFrame       = PERIOD_CURRENT;
extern int                 fibo_sequence = 5;
extern int                 k_period  = 8;
extern int                 d_period  = 3;
extern int                 slowing  = 3;
extern double  lvlUP = 70;
extern double  lvlDN = 30;
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           = "fibStoch 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 bool               Interpolate   = true;

extern string             name3 = "fibStoch";


double buffer1[];
double buffer2[];
double buffer3[];
double trend[],lvlUp[], lvlDn[];


string indicatorFileName;
bool   returnBars;

string name2 = name3 + " " + TimeFrame;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {




   IndicatorBuffers(6);
   SetIndexBuffer(0,buffer1);
   SetIndexStyle(0,DRAW_LINE,0,2);
   SetIndexBuffer(1,buffer2);
   SetIndexStyle(1,DRAW_LINE,0,2);
   SetIndexBuffer(2,buffer3);
   SetIndexStyle(2,DRAW_LINE,0,2);
   SetIndexBuffer(3,lvlUp);
   SetIndexStyle(3,DRAW_LINE,STYLE_DOT,1,clrWhite);
   SetIndexBuffer(4,lvlDn);
   SetIndexStyle(4,DRAW_LINE,STYLE_DOT,1,clrWhite);


   SetIndexBuffer(5,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--)
        {


         int fib[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987};

         double fibStochMain ;
         double fibStochSig;
         double arrSize = ArraySize(fib);

         if(fibo_sequence <= 0)
           {
            arrSize = 1;
           }
         else
            if(fibo_sequence == 1)
              {

               arrSize = 2;
              }
            else
               if((fibo_sequence > arrSize))
                 {

                  arrSize = ArraySize(fib)-1;
                 }

               else
                  if((fibo_sequence <= arrSize) &&(fibo_sequence >0))
                    {
                     arrSize = fibo_sequence;
                    }


         for(int z=0; z <= arrSize-1; z++)
           {
            int count = fib[z];
            fibStochMain   += iStochastic(NULL,0,k_period,d_period,slowing,MODE_SMA,STO_CLOSECLOSE,MODE_SIGNAL,i+count);
            fibStochSig  += iStochastic(NULL,0,k_period,d_period,slowing,MODE_SMA,STO_CLOSECLOSE,MODE_MAIN,i+count);
           }


         lvlUp[i] = lvlUP;
         lvlDn[i] = lvlDN;

         buffer1[i] =fibStochSig/arrSize;
         buffer2[i] = fibStochMain/arrSize;

         trend[i]= 0;

         if(buffer1[i] > buffer2[i] && buffer1[i+1] < buffer2[i+1] && buffer1[i] < lvlDn[i])
            trend[i] = 1;
         if(buffer1[i] < buffer2[i] && buffer1[i+1] > buffer2[i+1]  && buffer1[i] > lvlUp[i])
            trend[i] = -1;



         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 up");
         if(trend[whichBar+1] != -1 && trend[whichBar]== -1)
            doAlert(time1,mess1,whichBar,"crossing down");

        }




      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,fibo_sequence,k_period,d_period, slowing,lvlUP,lvlDN,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,0,y);
      buffer2[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,fibo_sequence,k_period,d_period, slowing,lvlUP,lvlDN,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,1,y);
      buffer3[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,fibo_sequence,k_period,d_period, slowing,lvlUP,lvlDN,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,2,y);
lvlUp[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,fibo_sequence,k_period,d_period, slowing,lvlUP,lvlDN,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,3,y);
lvlDn[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,fibo_sequence,k_period,d_period, slowing,lvlUP,lvlDN,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,arrowsVisible,arrowsOnNewest,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,arrowsUpColor,arrowsDnColor,arrowsUpCode,arrowsDnCode,arrowsUpSize,arrowsDnSize,4,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;

lvlUp[i+x] = lvlUp[i] + (lvlUp[i+n] - lvlUp[i]) * x/n;
         lvlDn[i+x] = lvlDn[i] + (lvlDn[i+n] - lvlDn[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)+" fibStoch "+doWhat;
      if(alertsMessage)
         Alert(message);
      if(alertsNotify)
         SendNotification(message);
      if(alertsEmail)
         SendMail(_Symbol+" fibStoch ",message);
      if(alertsSound)
         PlaySound(soundFile);
     }
  }





//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void drawArrow(string nameAdd, double gapMul, int i,color theColor, int theCode, int theWidth, bool up)
  {
   string name1 = arrowsIdentifier+":"+nameAdd+":"+(string)Time[i];
   double gap  = iATR(NULL,0,20,i)*gapMul;

//
//
//
//
//

   datetime atime = Time[i];
   if(arrowsOnNewest)
      atime += _Period*60-1;
   ObjectCreate(name1,OBJ_ARROW,0,atime,0);
   ObjectSet(name1,OBJPROP_ARROWCODE,theCode);
   ObjectSet(name1,OBJPROP_WIDTH,theWidth);
   ObjectSet(name1,OBJPROP_COLOR,theColor);
   if(up)
      ObjectSet(name1,OBJPROP_PRICE1,High[i] + arrowsUpperGap * gap);
   else
      ObjectSet(name1,OBJPROP_PRICE1,Low[i]  - arrowsLowerGap * gap);
  }
//+------------------------------------------------------------------+
