//------------------------------------------------------------------
#property copyright "mladen"
#property link      "www.forex-station.com"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers    2
#property indicator_color1     LimeGreen
#property indicator_color2     PaleVioletRed
#property indicator_width1     2
#property indicator_width2     2
#property indicator_level1     0

//
//
//
//
//

extern ENUM_TIMEFRAMES TimeFrame       = PERIOD_CURRENT;
extern int             AtrPeriod       = 14;
extern bool            alertsOn        = false;
extern bool            alertsOnCurrent = true;
extern bool            alertsMessage   = true;
extern bool            alertsSound     = false;
extern bool            alertsEmail     = false;

double Hi[];
double Lo[];
double no[];
double kr[];
double trend[];
string indicatorFileName;
bool   returnBars;

//------------------------------------------------------------------
//                                                                  
//------------------------------------------------------------------

int init()
{
   IndicatorDigits(0);      
   IndicatorBuffers(5);   
      SetIndexBuffer(0,kr); SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexLabel(0,"XO Up");
      SetIndexBuffer(1,no); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexLabel(1,"XO Down");
      SetIndexBuffer(2,Hi);
      SetIndexBuffer(3,Lo);
      SetIndexBuffer(4,trend);
   SetIndexEmptyValue(0,0.00);
   SetIndexEmptyValue(1,0.00);
   SetIndexEmptyValue(2,0.00);
   SetIndexEmptyValue(3,0.00);
      indicatorFileName = WindowExpertName();
      returnBars        = (TimeFrame==-99);
      TimeFrame         = MathMax(TimeFrame,_Period);

   //
   //
   //
   //
   //
      
   IndicatorShortName(timeFrameToString(TimeFrame)+" XO ("+DoubleToStr(AtrPeriod,2)+")");
   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) { kr[0] = limit+1; return(0); }

   //
   //
   //
   //
   //
   
   if (TimeFrame == Period())
   {
      for(int i=limit; i>=0; i--)
      {         
         if (i>=(Bars-2)) { Hi[i+1]=Close[i]; Lo[i+1]=Close[i]; continue; }
         double BoxPeriod = iATR(NULL,0,AtrPeriod,i);
         double cur      = Close[i];
                Hi[i]    = Hi[i+1];
                Lo[i]    = Lo[i+1];
                no[i]    = no[i+1];
                kr[i]    = kr[i+1];
                trend[i] = trend[i+1];

                if (cur > (Hi[i]+BoxPeriod)) 
                {
                     Hi[i]    = cur;
                     Lo[i]    = cur-BoxPeriod;
                     kr[i]    = kr[i+1]+1;
                     no[i]    = 0;
                     trend[i] = 1;
                }
                if (cur < (Lo[i]-BoxPeriod)) 
                {
                     Lo[i]    = cur;
                     Hi[i]    = cur+BoxPeriod;
                     no[i]    = no[i+1]-1;
                     kr[i]    = 0;
                     trend[i] = -1;
                }
      }
      manageAlerts();
      return(0);
   }
   
   //
   //
   //
   //
   //
   
      limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/_Period));
      for(i=limit; i>=0; i--)
      {
         int y = iBarShift(NULL,TimeFrame,Time[i]);
            kr[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,AtrPeriod,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,0,y);
            no[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,AtrPeriod,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,1,y); 
      }
      return(0);     
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

void manageAlerts()
{
   if (alertsOn)
   {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      if (trend[whichBar] != trend[whichBar+1])
      {
         if (trend[whichBar] ==  1) doAlert(whichBar,"up");
         if (trend[whichBar] == -1) doAlert(whichBar,"down");
      }
   }
}

//
//
//
//
//

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 = timeFrameToString(Period())+" "+Symbol()+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" XO trend changed to "+doWhat;
          if (alertsMessage) Alert(message);
          if (alertsEmail)   SendMail(StringConcatenate(Symbol()," XO"),message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

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("");
}