//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "www.forex-tsd.com"
#property link      "www.forex-tsd.com"

#property indicator_separate_window
#property indicator_buffers    3
#property indicator_color1     LimeGreen
#property indicator_color2     DeepPink
#property indicator_color3     Gold
#property indicator_width1     2
#property indicator_width2     2
#property indicator_style3     STYLE_DASH
#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES    TimeFrame       = PERIOD_CURRENT; // Time frame to use
extern ENUM_APPLIED_PRICE Price           = PRICE_CLOSE;    // Price
extern double             ItPeriod        = 20;             // Period
extern ENUM_MA_METHOD     MaMethod        = MODE_EMA;       // Average method
extern int                LevelBars       = 300;            // Look back period for levels
extern double             LevelFactor     = 0.283;          // Levels factor
extern bool               alertsOn        = true;           // Turn alerts on?
extern bool               alertsOnCurrent = true;           // Alerts on still opened bar?
extern bool               alertsMessage   = true;           // Alerts should display a message?
extern bool               alertsSound     = false;          // Alerts should play a sound?
extern bool               alertsEmail     = false;          // Alerts shoud send email?
extern bool               Interpolate     = true;           // Interpolate in multi time frame mode?

//
//
//
//
//

double Upval[],Dnval[],ItLev[],trend[];
string indicatorFileName;
bool   returnBars;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int init()
{
      IndicatorBuffers(6);
      SetIndexBuffer(0,Upval); SetIndexStyle(0,DRAW_HISTOGRAM);
      SetIndexBuffer(1,Dnval); SetIndexStyle(1,DRAW_HISTOGRAM);
      SetIndexBuffer(2,ItLev);
      SetIndexBuffer(3,trend);
      
      //
      //
      //
      //
      //
      
      indicatorFileName = WindowExpertName();
      returnBars        = (TimeFrame==-99);
      TimeFrame         = MathMax(TimeFrame,_Period);
      IndicatorShortName(timeFrameToString(TimeFrame)+"  ITrend ");
   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) { Upval[0] = limit+1; return(0); }
         if (TimeFrame!=Period())
         {
            limit = (int)MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/Period()));
            for (int i=limit;i>=0; i--)
            {
               int y = iBarShift(NULL,TimeFrame,Time[i]);
                  Upval[i]  = iCustom(NULL,TimeFrame,indicatorFileName,0,Price,ItPeriod,MaMethod,LevelBars,LevelFactor,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,0,y);
                  Dnval[i]  = iCustom(NULL,TimeFrame,indicatorFileName,0,Price,ItPeriod,MaMethod,LevelBars,LevelFactor,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,1,y);
                  ItLev[i]  = iCustom(NULL,TimeFrame,indicatorFileName,0,Price,ItPeriod,MaMethod,LevelBars,LevelFactor,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,2,y);

                  if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
                     int n,k; datetime time = iTime(NULL,TimeFrame,y);
                        for(n = 1; i+n < Bars && Time[i+n] >= time; n++) continue;	
                        for(k = 1; i+n < Bars && i+k < Bars && k<n; k++)
                        {
                           Upval[i+k] = Upval[i] + (Upval[i+n]-Upval[i])*k/n;
                           Dnval[i+k] = Dnval[i] + (Dnval[i+n]-Dnval[i])*k/n;
                        }               
            }   
            return(0);
         }               

   //
   //
   //
   //
   //

   for (int i=limit-1; i>=0; i--)
   {  
      double ma = iMA(NULL,0,1,0,MaMethod,Price,i);
      double mv = iMA(NULL,0,(int)ItPeriod,0,MaMethod,Price,i);
      Upval[i]  = ma - mv;
      Dnval[i]  = - (Low[i]+High[i]-2*mv);
         double hi = MathMax(Upval[ArrayMaximum(Upval,LevelBars,i)],Dnval[ArrayMaximum(Dnval,LevelBars,i)]);
         ItLev[i]  = hi*LevelFactor; 
	      trend[i]  = (Upval[i]>ItLev[i]) ? 1 	: (Dnval[i]>ItLev[i]) ? -1 : (i<Bars-1) ? trend[i+1] : 0;
   }  
   manageAlerts();
   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 manageAlerts()
{
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0;
      if (trend[whichBar] != trend[whichBar+1])
      {
         if (trend[whichBar] == 1) doAlert(whichBar,"buy");
         if (trend[whichBar] ==-1) doAlert(whichBar,"sell");
      }         
   }
}   

//
//
//
//
//

void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];

       //
       //
       //
       //
       //

       message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," - ",timeFrameToString(_Period)+"  Itrend ",doWhat);
          if (alertsMessage) Alert(message);
          if (alertsEmail)   SendMail(StringConcatenate(Symbol(),"  Itrend "),message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}