//+------------------------------------------------------------------+
//|                                                DT Oscillator.mq4 |
//|                             Copyright © 2016, Behzad Habibzadeh. |
//|                                email: behzadhabibzade@gmail.com  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Behzad Habibzadeh khoei."
#property link      "behzadhabibzade@gmail.com"

#property indicator_separate_window
#property indicator_level1 25
#property indicator_level2 75
//#property indicator_minimum -5
//#property indicator_maximum 105
#property indicator_buffers 4
#property indicator_color1 DeepSkyBlue
#property indicator_color2 Magenta

string short_name;
int subwindow_number=WRONG_VALUE;
//---- input parameters
enum __in{ 
   _p1=1,   // 8 5 3 3 
   _p2=2,   // 13 8 5 5 
   _p3=3,   // 21 13 8 8
   _p4=4,   // 34 21 13 13       
};
extern __in setting = _p1;
//---- input parameters
int       rsiLength;
int       kLength;
int       KSmooth;
int       DLength;
bool      SmoothKLine; 
//---- buffers
double K[];
double D[];
double rsi[];
double stoch[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,K);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,D);
   SetIndexStyle(2,DRAW_NONE);
   SetIndexBuffer(2,rsi);
   SetIndexStyle(3,DRAW_NONE);
   SetIndexBuffer(3,stoch);
//----
   Setting();
   IndicatorName();
   Buttons();
   ObjectSetInteger(0,"8 5 3 3",OBJPROP_STATE,true);   
   BtnUpdate();
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ButtonDelete(0,"8 5 3 3");
   ButtonDelete(0,"13 8 5 5");
   ButtonDelete(0,"21 13 8 8");
   ButtonDelete(0,"34 21 13 13");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Create the button                                                |
//+------------------------------------------------------------------+
bool ButtonCreate(const long              chart_ID=0,               // chart's ID
                  const string            name="Button",            // button name
                  const int               sub_window=0,             // subwindow index
                  const int               x=0,                      // X coordinate
                  const int               y=0,                      // Y coordinate
                  const int               width=50,                 // button width
                  const int               height=18,                // button height
                  const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, // chart corner for anchoring
                  const string            text="Button",            // text
                  const string            font="Arial",             // font
                  const int               font_size=10,             // font size
                  const color             clr=clrBlack,             // text color
                  const color             back_clr=C'236,233,216',  // background color
                  const color             border_clr=clrNONE,       // border color
                  const bool              state=false,              // pressed/released
                  const bool              back=false,               // in the background
                  const bool              selection=false,          // highlight to move
                  const bool              hidden=true,              // hidden in the object list
                  const long              z_order=0)                // priority for mouse click
  {
//--- reset the error value
   ResetLastError();
//--- create the button
   if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
     {
      Print(__FUNCTION__,
            ": failed to create the button! Error code = ",GetLastError());
      return(false);
     }
//--- set button coordinates
   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- set button size
   ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
   ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- set the chart's corner, relative to which point coordinates are defined
   ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- set the text
   ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- set text font
   ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- set font size
   ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- set text color
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set background color
   ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- set border color
   ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- set button state
   ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
//--- enable (true) or disable (false) the mode of moving the button by mouse
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   return(true);
  }
  
bool ButtonDelete(const long   chart_ID=0,    // chart's ID
                  const string name="Button") // button name
  {
//--- reset the error value
   ResetLastError();
//--- delete the button
   if(!ObjectDelete(chart_ID,name))
     {
      Print(__FUNCTION__,
            ": failed to delete the button! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
    if (id == CHARTEVENT_OBJECT_CLICK) {
    if(sparam=="8 5 3 3")
        if (ObjectGetInteger(0, "8 5 3 3", OBJPROP_STATE)) {
            Sleep(100);            
            ObjectSetInteger(0, "13 8 5 5", OBJPROP_STATE, false);
            ObjectSetInteger(0, "21 13 8 8", OBJPROP_STATE, false);
            ObjectSetInteger(0, "34 21 13 13", OBJPROP_STATE, false);
            setting=1;start();
        }
    if(sparam=="13 8 5 5")        
        if (ObjectGetInteger(0, "13 8 5 5", OBJPROP_STATE)) {
            Sleep(100);
            ObjectSetInteger(0, "8 5 3 3", OBJPROP_STATE, false);
            ObjectSetInteger(0, "21 13 8 8", OBJPROP_STATE, false);
            ObjectSetInteger(0, "34 21 13 13", OBJPROP_STATE, false);
            setting=2;start();
        }
    if(sparam=="21 13 8 8")
        if (ObjectGetInteger(0, "21 13 8 8", OBJPROP_STATE)) {
            Sleep(100);
            ObjectSetInteger(0, "13 8 5 5", OBJPROP_STATE, false);
            ObjectSetInteger(0, "8 5 3 3", OBJPROP_STATE, false);
            ObjectSetInteger(0, "34 21 13 13", OBJPROP_STATE, false);
            setting=3;start();
        }
    if(sparam=="34 21 13 13")        
        if (ObjectGetInteger(0, "34 21 13 13", OBJPROP_STATE)) {
            Sleep(100);
            ObjectSetInteger(0, "8 5 3 3", OBJPROP_STATE, false);
            ObjectSetInteger(0, "21 13 8 8", OBJPROP_STATE, false);
            ObjectSetInteger(0, "13 8 5 5", OBJPROP_STATE, false);
            setting=4;start();
        }        
    BtnUpdate(); 
      }  
              
}  
void BtnUpdate(){
      if (ObjectGetInteger(0, "8 5 3 3", OBJPROP_STATE)){
            ObjectSetInteger(0,"8 5 3 3",OBJPROP_COLOR,clrWhite);
            ObjectSetInteger(0,"8 5 3 3",OBJPROP_BGCOLOR,clrRed);      
      }
      else {
            ObjectSetInteger(0,"8 5 3 3",OBJPROP_COLOR,clrBlack);
            ObjectSetInteger(0,"8 5 3 3",OBJPROP_BGCOLOR,C'236,233,216');
      }
      if (ObjectGetInteger(0, "13 8 5 5", OBJPROP_STATE)){
            ObjectSetInteger(0,"13 8 5 5",OBJPROP_COLOR,clrWhite);
            ObjectSetInteger(0,"13 8 5 5",OBJPROP_BGCOLOR,clrRed);      
      }
      else {
            ObjectSetInteger(0,"13 8 5 5",OBJPROP_COLOR,clrBlack);
            ObjectSetInteger(0,"13 8 5 5",OBJPROP_BGCOLOR,C'236,233,216');
      }   
      if (ObjectGetInteger(0, "21 13 8 8", OBJPROP_STATE)){
            ObjectSetInteger(0,"21 13 8 8",OBJPROP_COLOR,clrWhite);
            ObjectSetInteger(0,"21 13 8 8",OBJPROP_BGCOLOR,clrRed);      
      }
      else {
            ObjectSetInteger(0,"21 13 8 8",OBJPROP_COLOR,clrBlack);
            ObjectSetInteger(0,"21 13 8 8",OBJPROP_BGCOLOR,C'236,233,216');
      }
      if (ObjectGetInteger(0, "34 21 13 13", OBJPROP_STATE)){
            ObjectSetInteger(0,"34 21 13 13",OBJPROP_COLOR,clrWhite);
            ObjectSetInteger(0,"34 21 13 13",OBJPROP_BGCOLOR,clrRed);      
      }
      else {
            ObjectSetInteger(0,"34 21 13 13",OBJPROP_COLOR,clrBlack);
            ObjectSetInteger(0,"34 21 13 13",OBJPROP_BGCOLOR,C'236,233,216');
      }                 
}

void Setting(){
if(setting==1){
       rsiLength=8;
       kLength=5;
       KSmooth=3;
       DLength=3;
      SmoothKLine=true;
}

if(setting==2){
       rsiLength=13;
       kLength=8;
       KSmooth=5;
       DLength=5;
      SmoothKLine=true;
}

if(setting==3){
       rsiLength=21;
       kLength=13;
       KSmooth=8;
       DLength=8;
      SmoothKLine=true;
}

if(setting==4){
       rsiLength=34;
       kLength=21;
       KSmooth=13;
       DLength=13;
      SmoothKLine=true;
}
}
void Buttons(){
//--- create the button
ButtonCreate(0,"8 5 3 3",subwindow_number,5,20,70,20,CORNER_LEFT_UPPER,"8  5  3  3","Arial",8,
      clrBlack,C'236,233,216',clrNONE,false,false,false,true,0);

ButtonCreate(0,"13 8 5 5",subwindow_number,5,50,70,20,CORNER_LEFT_UPPER,"13  8  5  5","Arial",8,
      clrBlack,C'236,233,216',clrNONE,false,false,false,true,0);

ButtonCreate(0,"21 13 8 8",subwindow_number,5,80,70,20,CORNER_LEFT_UPPER,"21 13 8 8","Arial",8,
      clrBlack,C'236,233,216',clrNONE,false,false,false,true,0);

ButtonCreate(0,"34 21 13 13",subwindow_number,5,110,70,20,CORNER_LEFT_UPPER,"34 21 13 13","Arial",8,
      clrBlack,C'236,233,216',clrNONE,false,false,false,true,0);  
}
void IndicatorName(){
   short_name="setting ("+IntegerToString(rsiLength)+" "+IntegerToString(kLength)+" "+IntegerToString(KSmooth)+" "+IntegerToString(DLength)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);   
//--- Indicator subwindow number
   subwindow_number=ChartWindowFind(0,short_name); 
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   Setting();
   IndicatorName();
  
//---- start ----  
   int    counted_bars=IndicatorCounted();

   for (int i = Bars; i >= 0; i--)
   {
      rsi[i] = iRSI(Symbol(), 0, rsiLength, PRICE_CLOSE, i); 
      stoch[i] = iStochK (kLength, i); 
      K[i] = Smooth(stoch, KSmooth, i);
      D[i] = Smooth(K, DLength, i);
   }

   return(0);
  }
  
double iStochK(int len, int bar)
{
   double ll = 9999, hh = -5555;
   for(int i = 0; i < len; i++)
   {
      if (ll > rsi[bar + i]) ll = rsi[bar + i];
      if (hh < rsi[bar + i]) hh = rsi[bar + i];
   }
   
   if (ll == hh) return (stoch[bar+1]);
   
   return (100 * (rsi[bar] - ll) / (hh - ll));
}


double Smooth (double array[], int period, int shift)
{
   double sum = 0;
   for (int i = shift + period - 1; i >= shift; i--)
   {
      sum += array[i];
   }
   return (sum / period);
}


//+------------------------------------------------------------------+