//+------------------------------------------------------------------+
//|                                                       #dtosc.mq4 |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_color1 DeepSkyBlue
#property indicator_color2 OrangeRed
#property indicator_width1 2
#property indicator_width2 2

//
//
//
//
//

   extern ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;
   extern int    PeriodRSI  =13;
   extern int    PeriodStoch= 8;
   extern int    PeriodSK   = 5;
   extern int    PeriodSD   = 3;
   extern double LevelUp    = 70;
   extern double LevelDn    = 30;
   extern ENUM_MA_METHOD MAMode  = MODE_SMA;
   extern bool   alertsOn        = true;
   extern bool   alertsOnCurrent = true;
   extern bool   alertsMessage   = true;
   extern bool   alertsSound     = true;
   extern bool   alertsEmail     = false;
   extern string soundfile       = "alert2.wav";
   extern bool   Interpolate     = true;

//
//
//
//
//

double SK[];
double SD[];
double StoRSI[];
double RSI[];
double cross[];
string IndicatorFileName;
bool   returnBars;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(5);
      SetIndexBuffer(0,SK);
      SetIndexBuffer(1,SD);
      SetIndexBuffer(2,StoRSI);
      SetIndexBuffer(3,RSI);
      SetIndexBuffer(4,cross);
         SetLevelValue(0,LevelUp);
         SetLevelValue(1,LevelDn);

   //
   //
   //
   //
   //
   
   IndicatorFileName = WindowExpertName();
   returnBars = (TimeFrame == -99);
   TimeFrame = MathMax(TimeFrame,_Period);   

   //
   //
   //
   //
   //
   
   IndicatorShortName(timeFrameToString(TimeFrame)+" DTOSC ("+PeriodRSI+","+PeriodStoch+","+PeriodSK+","+PeriodSD+")");
return(0);
}
int deinit() { return(0); }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int counted_bars = IndicatorCounted();
      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
         int limit=MathMin(Bars-counted_bars,Bars-1);
               if (returnBars) { SK[0] = limit; return(0); }

   //
   //
   //
   //
   //
   
   if (TimeFrame != Period())
   {
      limit = MathMax(limit,MathMin(Bars,iCustom(NULL,TimeFrame,IndicatorFileName,-99,0,0)*TimeFrame/Period()));
      for(int i=limit; i>=0; i--)
      {
         int y = iBarShift(NULL,TimeFrame,Time[i]);
            SK[i] = iCustom(NULL,TimeFrame,IndicatorFileName,PERIOD_CURRENT,PeriodRSI,PeriodStoch,PeriodSK,PeriodSD,LevelUp,LevelDn,MAMode,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,soundfile,0,y);
            SD[i] = iCustom(NULL,TimeFrame,IndicatorFileName,PERIOD_CURRENT,PeriodRSI,PeriodStoch,PeriodSK,PeriodSD,LevelUp,LevelDn,MAMode,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,soundfile,1,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 j = 1; j < n; j++)
               {
                  SK[i+j] = SK[i] + (SK[i+n]-SK[i])*j/n;
                  SD[i+j] = SD[i] + (SD[i+n]-SD[i])*j/n;
               }
      }
      return(0);         
   }
   
   //
   //
   //
   //
   //
             
   for(i=limit; i>=0; i--)
   {
      RSI[i] = iRSI(NULL,0,PeriodRSI,PRICE_CLOSE,i);
      double LLV = RSI[ArrayMinimum(RSI,PeriodStoch,i)];
      double HHV = RSI[ArrayMaximum(RSI,PeriodStoch,i)];
      if ((HHV-LLV)!=0)
            StoRSI[i] = 100.0*((RSI[i] - LLV)/(HHV - LLV));
      else  StoRSI[i] = 0;
   }   
   for(i=limit; i>=0; i--) SK[i]=iMAOnArray(StoRSI,0,PeriodSK,0,MAMode,i);
   for(i=limit; i>=0; i--)
   {
      SD[i]=iMAOnArray(SK,0,PeriodSD,0,MAMode,i);
      cross[i] = cross[i+1];
         if (SK[i]>SD[i]) cross[i] =  1;
         if (SK[i]<SD[i]) cross[i] = -1;
   }    
   
   //
   //
   //
   //
   //
        
   if (alertsOn)
   {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      if (cross[whichBar] != cross[whichBar+1])
      if (cross[whichBar] == 1)
            doAlert("dtosc trend changed to up");
      else  doAlert("dtosc trend changed to down");       
   }
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[0]) {
          previousAlert  = doWhat;
          previousTime   = Time[0];

          //
          //
          //
          //
          //

          message =  StringConcatenate(timeFrameToString(_Period)+" "+Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," Dtosc ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsEmail)   SendMail(StringConcatenate(Symbol()," Dtosc "),message);
             if (alertsSound)   PlaySound(soundfile);
      }
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

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("");
}