//+------------------------------------------------------------------+
//|                                              StochWithPoints.mq4 |
//|                                                                * |
//+------------------------------------------------------------------+
#property copyright "*"
#property link      "*"

#property indicator_separate_window
#property indicator_minimum    0
#property indicator_maximum    100
#property indicator_buffers    10
#property indicator_color6     clrYellow
#property indicator_width6     1
#property indicator_color7     clrYellow
#property indicator_width7     1
#property indicator_color8     clrYellow
#property indicator_width8     1
#property indicator_color9     clrRed
#property indicator_width9     1
#property indicator_color10    clrLime
#property indicator_width10    1
#property indicator_levelcolor clrGray

extern string          TimeFrame       = "Current time frame";
extern int             K               = 14;//5;
extern int             D               = 3;
extern int             S               = 8;//3;
extern ENUM_MA_METHOD  Method          = MODE_SMA;
extern ENUM_STO_PRICE  Price           = STO_CLOSECLOSE;
extern int             MainHP          = 3;
extern int             SignalHP        = 3;
extern double          levOs           = 30;
extern double          levOb           = 70;
extern color           BearColor       = clrOrange;
extern color           BullColor       = clrLimeGreen;
extern color           NeutColor       = clrLightSteelBlue;
extern int             lineWidth       = 3;

//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double ExtMapBuffer5[];
double ExtMapBuffer6[],trend[];
double stoUpa[];
double stoUpb[];
double stoNua[];
double stoNub[];
double stoDna[];
double stoDnb[];
string indicatorFileName;
bool   returnBars;
int    timeFrame;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(11);
   SetIndexBuffer(0,ExtMapBuffer1);  SetIndexStyle(0,DRAW_LINE,EMPTY,lineWidth,NeutColor);
   SetIndexBuffer(1,stoUpa);         SetIndexStyle(1,DRAW_LINE,EMPTY,lineWidth,BullColor);
   SetIndexBuffer(2,stoUpb);         SetIndexStyle(2,DRAW_LINE,EMPTY,lineWidth,BullColor);
   SetIndexBuffer(3,stoDna);         SetIndexStyle(3,DRAW_LINE,EMPTY,lineWidth,BearColor);
   SetIndexBuffer(4,stoDnb);         SetIndexStyle(4,DRAW_LINE,EMPTY,lineWidth,BearColor);
   SetIndexBuffer(5,ExtMapBuffer2);  SetIndexStyle(5,DRAW_LINE);
   SetIndexBuffer(6,ExtMapBuffer3);  SetIndexStyle(6,DRAW_ARROW); SetIndexArrow(6,159);
   SetIndexBuffer(7,ExtMapBuffer4);  SetIndexStyle(7,DRAW_ARROW); SetIndexArrow(7,159);
   SetIndexBuffer(8,ExtMapBuffer5);  SetIndexStyle(8,DRAW_ARROW); SetIndexArrow(8,234);//(4,159);
   SetIndexBuffer(9,ExtMapBuffer6);  SetIndexStyle(9,DRAW_ARROW); SetIndexArrow(9,233);//(5,159);
   SetIndexBuffer(10,trend);
   SetLevelValue(0,levOb);
   SetLevelValue(1,levOs);
   SetLevelStyle(STYLE_DOT,0);
   
    timeFrame         = stringToTimeFrame(TimeFrame);
    indicatorFileName = WindowExpertName();
    returnBars        = (TimeFrame=="returnBars"); if (returnBars) return(0);
    
    IndicatorShortName(timeFrameToString(timeFrame)+" S_p");
return(0);
}
int deinit() { return(0); }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(MathMax(Bars-counted_bars,MathMax(MainHP,SignalHP)*2+1),Bars-1);
           if (returnBars) { ExtMapBuffer1[0] = limit+1; return(0); }
           if (timeFrame!=Period())
           {
               limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,indicatorFileName,"returnBars",0,0)*timeFrame/Period()));
               if (trend[limit]== 1) CleanPoint(limit,stoUpa,stoUpb);
               if (trend[limit]==-1) CleanPoint(limit,stoDna,stoDnb); 
               for(int i=limit;i>=0;i--)
               {
                  int y = iBarShift(NULL,timeFrame,Time[i]);
                  int x = iBarShift(NULL,timeFrame,Time[i+1]);
                     ExtMapBuffer1[i] = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,0, y);
                     ExtMapBuffer2[i] = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,5, y);
                     trend[i]         = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,10,y);
                     stoUpa[i] = stoUpb[i] = EMPTY_VALUE;
                     stoDna[i] = stoDnb[i] = EMPTY_VALUE;
                     if (x!=y)
                     {
                        ExtMapBuffer3[i] = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,6,y);
                        ExtMapBuffer4[i] = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,7,y);
                        ExtMapBuffer5[i] = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,8,y);
                        ExtMapBuffer6[i] = iCustom(NULL,timeFrame,indicatorFileName,"",K,D,S,Method,Price,MainHP,SignalHP,levOs,levOb,BearColor,BullColor,NeutColor,lineWidth,9,y);
                     }
                     else
                     {
                        ExtMapBuffer3[i] = EMPTY_VALUE;
                        ExtMapBuffer4[i] = EMPTY_VALUE;
                        ExtMapBuffer5[i] = EMPTY_VALUE;
                        ExtMapBuffer6[i] = EMPTY_VALUE;
                     }
               }
               for(i=limit;i>=0;i--)
               {
                 if (trend[i+1] == 1) PlotPoint(i,stoUpa,stoUpb,ExtMapBuffer1);
                 if (trend[i+1] ==-1) PlotPoint(i,stoDna,stoDnb,ExtMapBuffer1);   
               }
      return(0);     
      }

      //
      //
      //
      //
      //
      
      if (trend[limit]== 1) CleanPoint(limit,stoUpa,stoUpb);
      if (trend[limit]==-1) CleanPoint(limit,stoDna,stoDnb); 
      for(i=limit;i>=0;i--)
      {
         ExtMapBuffer1[i]=iStochastic(NULL,0,K,D,S,Method,Price,0,i);
         ExtMapBuffer2[i]=iStochastic(NULL,0,K,D,S,Method,Price,1,i);         
         ExtMapBuffer3[i+MainHP]   = EMPTY_VALUE;
         ExtMapBuffer4[i+MainHP]   = EMPTY_VALUE;
         ExtMapBuffer5[i+SignalHP] = EMPTY_VALUE;
         ExtMapBuffer6[i+SignalHP] = EMPTY_VALUE;
         if(ArrayMaximum(ExtMapBuffer1,MainHP*2+1,i)==i+MainHP)
         ExtMapBuffer3[i+MainHP]=ExtMapBuffer1[i+MainHP];
         if(ArrayMinimum(ExtMapBuffer1,MainHP*2+1,i)==i+MainHP)
         ExtMapBuffer4[i+MainHP]=ExtMapBuffer1[i+MainHP];     
         
         if(ArrayMaximum(ExtMapBuffer2,SignalHP*2+1,i)==i+SignalHP)
         ExtMapBuffer5[i+SignalHP]=ExtMapBuffer2[i+SignalHP];
         if(ArrayMinimum(ExtMapBuffer2,SignalHP*2+1,i)==i+SignalHP)
         ExtMapBuffer6[i+SignalHP]=ExtMapBuffer2[i+SignalHP];
         stoUpa[i] = stoUpb[i] = EMPTY_VALUE;
         stoDna[i] = stoDnb[i] = EMPTY_VALUE;
         trend[i] = (i<Bars-1) ? (ExtMapBuffer1[i]>levOb)                             ? -2 : 
                                 (ExtMapBuffer1[i]<levOs)                             ?  2 : 
                                 (ExtMapBuffer1[i]<levOb && ExtMapBuffer1[i+1]>levOb) ? -1 : 
                                 (ExtMapBuffer1[i]>levOs && ExtMapBuffer1[i+1]<levOs) ?  1 : trend[i+1] : 0;  
         
         if (trend[i+1] == 1) PlotPoint(i,stoUpa,stoUpb,ExtMapBuffer1);
         if (trend[i+1] ==-1) PlotPoint(i,stoDna,stoDnb,ExtMapBuffer1);   
      }
return(0);
}

//-------------------------------------------------------------------
//                                                                  
//-------------------------------------------------------------------

void CleanPoint(int i,double& first[],double& second[])
{
   if (i>=Bars-3) return;
   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
        second[i+1] = EMPTY_VALUE;
   else
      if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
          first[i+1] = EMPTY_VALUE;
}

void PlotPoint(int i,double& first[],double& second[],double& from[])
{
   if (i>=Bars-2) return;
   if (first[i+1] == EMPTY_VALUE)
      if (first[i+2] == EMPTY_VALUE) 
            { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
      else  { second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }
   else     { first[i]  = from[i];                          second[i] = EMPTY_VALUE; }
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

//
//
//
//
//

int stringToTimeFrame(string tfs) {
   tfs = stringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period()));
                                                      return(Period());
}
string timeFrameToString(int tf) {
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

//
//
//
//
//

string stringUpperCase(string str) {
   string   s = str;

   for (int length=StringLen(str)-1; length>=0; length--) {
      int tchar = StringGetChar(s, length);
         if((tchar > 96 && tchar < 123) || (tchar > 223 && tchar < 256))
                     s = StringSetChar(s, length, tchar - 32);
         else if(tchar > -33 && tchar < 0)
                     s = StringSetChar(s, length, tchar + 224);
   }
   return(s);
}