//+------------------------------------------------------------------+
//|                                                       #dtosc.mq4 |
//|                                                           mladen |
//|             11.2013 mod. / alerts added - http://forexBaron.net  |
//+------------------------------------------------------------------+
// alert code from "10.6 STO Alert", find it at http://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=74592#p74592

#property copyright "mladen (mladenfx@gmail.com)"
#property link      "http://forexBaron.net"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_width1 2
#property indicator_width2 2
#property indicator_level1 30
#property indicator_level2 70

//
//
//
//
//

   extern string TimeFrame  = "Current time frame";
   extern int    PeriodRSI  =13;
   extern int    PeriodStoch= 8;
   extern int    PeriodSK   = 5;
   extern int    PeriodSD   = 3;
         //    0 = SMA
         //    1 - EMA
         //    2 - SMMA
         //    3 - LWMA
   extern string mah="0:SMA | 1:EMA | 2:SMMA | 3:LWMA";
   extern int MAMode=1;

//

extern string hi1="******* ALERT SETTINGS:";
extern bool KDcrossAlerts = true;
extern bool LevelAlerts = true;
extern int Push1Level = 20;
extern int Drop1Level = 80;
extern bool	PopupAlert        	= true;
extern bool	EmailAlert         	= false;
extern bool SendPushNotification = false;
extern bool SoundAlert           = true;
extern string SoundFilePushUp    = "alert.wav";
extern string SoundFilePushDn    = "alert2.wav";

//
//
//
//

double SK[];
double SD[];
double StoRSI[];
double RSI[];
string IndicatorFileName;
int    timeFrame;
bool   returnBars=false;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(4);
   
   for (int i=0; i<indicator_buffers; i++) SetIndexStyle(i,DRAW_LINE);
      SetIndexBuffer(0,SK);
      SetIndexBuffer(1,SD);
      SetIndexBuffer(2,StoRSI);
      SetIndexBuffer(3,RSI);

   //
   //
   //
   //
   //
   
   if (TimeFrame == "getBarsCount")
   {
      returnBars=true;
      return(0);
   }   
   timeFrame = stringToTimeFrame(TimeFrame);   

   //
   //
   //
   //
   //
   
   IndicatorShortName("DTOSC ("+PeriodRSI+","+PeriodStoch+","+PeriodSK+","+PeriodSD+")");
   IndicatorFileName = WindowExpertName();
return(0);
}
int deinit() { return(0); }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int i,limit;
   int counted_bars = IndicatorCounted();

   if(counted_bars < 0) return(-1);
   if(counted_bars > 0) counted_bars--;
             limit=Bars-counted_bars;

   //
   //
   //
   //
   
	// keep track of the bar on which an alert was last fired
	// since this variable is static, it will "remember" its value between calls
	static datetime tLastLevelAlert = 0;
	static datetime tLastKDcrossAlert = 0;
   
   //
   
   if (returnBars) { SK[0] = limit; return(0); }
   if (timeFrame != Period())
   {
      limit = MathMax(limit,MathMin(Bars,iCustom(NULL,timeFrame,IndicatorFileName,"getBarsCount",0,0)*timeFrame/Period()));
         
      //
      //
      //
      //
      //
         
      for(i=0; i<limit; i++)
      {
         int y = iBarShift(NULL,timeFrame,Time[i]);
            SK[i] = iCustom(NULL,timeFrame,IndicatorFileName,"",PeriodRSI,PeriodStoch,PeriodSK,PeriodSD,MAMode,0,y);
            SD[i] = iCustom(NULL,timeFrame,IndicatorFileName,"",PeriodRSI,PeriodStoch,PeriodSK,PeriodSD,MAMode,1,y);
      }               
      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);
   
//ALERTS:
	if(LevelAlerts && tLastLevelAlert < Time[0]) {
		// if DTOsc dipped down under 80...
		if(SK[1] >= Drop1Level && SK[0] < Drop1Level)
		 {
			   fireAlerts("DTOsc Dropped Below "+Drop1Level+" on " + Symbol() + " (tf:"+Period()+")",SoundFilePushDn);
			   tLastLevelAlert = Time[0];
		 }

		// if DTOsc pushed up over 20...
		if(SK[1] <= Push1Level && SK[0] > Push1Level)
		 {
			   fireAlerts("DTOsc Pushed Up Above "+Push1Level+" on " + Symbol() + " (tf:"+Period()+")",SoundFilePushUp);
			   tLastLevelAlert = Time[0];
       }
	}//if(LevelAlerts && tLastLevelAlert < Time[0]) {

	if(KDcrossAlerts && tLastKDcrossAlert < Time[0]) {
		// if DTOsc crossed down
		if(SK[1] >= SD[1] && SK[0] < SD[0])
		 {
			   fireAlerts("DTOsc crossed down on " + Symbol() + " (tf:"+Period()+")",SoundFilePushDn);
			   tLastKDcrossAlert = Time[0];
		 }

		// if DTOsc crossed up
		if(SK[1] <= SD[1] && SK[0] > SD[0])
		 {
			   fireAlerts("DTOsc crossed up on " + Symbol() + " (tf:"+Period()+")",SoundFilePushUp);
			   tLastKDcrossAlert = Time[0];
       }
	}//if(KDcrossAlerts && tLastKDcrossAlert < Time[0]) {
//end ALERTS   
   
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   for(int l = StringLen(tfs)-1; l >= 0; l--)
   {
      int tchar = StringGetChar(tfs,l);
          if((tchar > 96 && tchar < 123) || (tchar > 223 && tchar < 256))
               tfs = StringSetChar(tfs, l, tchar - 32);
          else 
              if(tchar > -33 && tchar < 0)
                  tfs = StringSetChar(tfs, l, tchar + 224);
   }

   //
   //
   //
   //
   //
   
   int tf=0;
         if (tfs=="M1" || tfs=="1")     tf=PERIOD_M1;
         if (tfs=="M5" || tfs=="5")     tf=PERIOD_M5;
         if (tfs=="M15"|| tfs=="15")    tf=PERIOD_M15;
         if (tfs=="M30"|| tfs=="30")    tf=PERIOD_M30;
         if (tfs=="H1" || tfs=="60")    tf=PERIOD_H1;
         if (tfs=="H4" || tfs=="240")   tf=PERIOD_H4;
         if (tfs=="D1" || tfs=="1440")  tf=PERIOD_D1;
         if (tfs=="W1" || tfs=="10080") tf=PERIOD_W1;
         if (tfs=="MN" || tfs=="43200") tf=PERIOD_MN1;
         if (tf<Period())               tf=Period();
   return(tf);
}


void fireAlerts(string sMsg,string SoundFile) {

	if(PopupAlert)
		Alert(sMsg);
	
	if(EmailAlert)
		SendMail("DTOsc Alert On " + Symbol(),sMsg);

	if(SoundAlert)
		PlaySound(SoundFile);
   
   if(SendPushNotification)
      SendNotification(sMsg);
}