

#property indicator_chart_window
#property indicator_buffers 6

#property indicator_color1 Lavender    // DodgerBlue // DeepSkyBlue     // Line UP
#property indicator_color2 Magenta     // Red // Tomato                 // Line DOWN
#property indicator_color3 Lavender    // DodgerBlue // DeepSkyBlue     // bars Low
#property indicator_color4 Magenta     // Red // Tomato                 // bars High
#property indicator_color5 Lavender    // DodgerBlue // DeepSkyBlue     // arrows UP
#property indicator_color6 Magenta     // Red // Tomato                 // arrows DOWN

#property indicator_width1 2   // Line UP
#property indicator_width2 2   // Line DOWN
#property indicator_width3 1   // bars Low
#property indicator_width4 1   // bars High
#property indicator_width5 1   // arrows UP
#property indicator_width6 1   // arrows DOWN


extern int             Factor      = 2;          //m15 = 6; 
extern ENUM_SERIESMODE seriesStart = MODE_LOW;   // 1 - 0;
extern ENUM_SERIESMODE seriesEnd   = MODE_HIGH;  // 2 - 3;


extern int                MAperiod     = 1,
                          MAshift      = 0;
extern ENUM_MA_METHOD     MAmode       = MODE_SMMA;
extern ENUM_APPLIED_PRICE MApriceStart = PRICE_LOW;
extern ENUM_APPLIED_PRICE MApriceEnd   = PRICE_HIGH;

extern double ATRdelta  = 0.5;

extern bool   ShowLine   =  true,
              ShowBars   =  false,
            ShowArrows   =  true,
              alertsOn   =  false,
       alertsOnCurrent   =  false,
         alertsMessage   =  false,
           alertsSound   =  false,
           alertsEmail   =  false;
           
extern bool AlertsMessageBarUpDn = false;
extern bool AlertsSoundBarUpDn   = false;

extern int    arrowsUP   = 233, 
              arrowsDN   = 234,
              arrowsSize = 0;

extern string  arrowsCodes_42_120_110_108_117_121 = "139-149_171_172_174_181_203_85_86_91",
                _241_242_221_222_228_230_246_248    = "233-234_225-226_217-218_236-238_74-76";



bool nexttrend;
double minhighprice,maxlowprice;
double up[],down[],atrlo[],atrhi[],trend[];
double arrup[],arrdwn[];
datetime TimeBar;


int init()
  {
   IndicatorBuffers(7); // +1 buffer - trend[]
   
   SetIndexBuffer(0,up);
   SetIndexBuffer(1,down);
   SetIndexBuffer(2,atrlo);
   SetIndexBuffer(3,atrhi);
   SetIndexBuffer(4,arrup);
   SetIndexBuffer(5,arrdwn);
   SetIndexBuffer(6,trend);

   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(6,0.0);


   if(ShowLine)
   {
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   }
   else
   {
   SetIndexStyle(0,DRAW_NONE);
   SetIndexStyle(1,DRAW_NONE);
   }

   if(ShowBars)
   {
   SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexStyle(3,DRAW_HISTOGRAM);
   }
   else
   {
   SetIndexStyle(2,DRAW_NONE);
   SetIndexStyle(3,DRAW_NONE);
   }


   if(ShowArrows)
   {
   SetIndexStyle(4,DRAW_ARROW,STYLE_SOLID,arrowsSize); SetIndexArrow(4,arrowsUP);
   SetIndexStyle(5,DRAW_ARROW,STYLE_SOLID,arrowsSize); SetIndexArrow(5,arrowsDN);
   }
   else
   {
   SetIndexStyle(4,DRAW_NONE);
   SetIndexStyle(5,DRAW_NONE);
   } 

   nexttrend=0;
   minhighprice= High[Bars-1];
   maxlowprice = Low[Bars-1];
   return (0);
  }


class CFix { } ExtFix;


int start()
  {
   double atr,lowprice_i,highprice_i,lowma,highma;
   int workbar=0;
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = MathMin(Bars-counted_bars,Bars-1);


   for(int i=Bars-1; i>=0; i--)
     {
      lowprice_i=iLow(Symbol(),0,iLowest(Symbol(),0,seriesStart,Factor,i));
      highprice_i=iHigh(Symbol(),0,iHighest(Symbol(),0,seriesEnd,Factor,i));
      
      lowma=NormalizeDouble(iMA(NULL,0,MAperiod,MAshift,MAmode,MApriceStart,i),Digits());
      highma=NormalizeDouble(iMA(NULL,0,MAperiod,MAshift,MAmode,MApriceEnd,i),Digits());
      
      trend[i]=trend[i+1];
      atr=iATR(Symbol(),0,5,i)*ATRdelta;

      arrup[i]  = EMPTY_VALUE;
      arrdwn[i] = EMPTY_VALUE;

      if(nexttrend==1)
        {
         maxlowprice=MathMax(lowprice_i,maxlowprice);

         if(highma<maxlowprice && Close[i]<Low[i+1])
           {
            trend[i]=1.0;
            nexttrend=0;
            minhighprice=highprice_i;
           }
        }

      if(nexttrend==0)
        {
         minhighprice=MathMin(highprice_i,minhighprice);

         if(lowma>minhighprice && Close[i]>High[i+1])
           {
            trend[i]=0.0;
            nexttrend=1;
            maxlowprice=lowprice_i;
           }
        }

      if(trend[i]==0.0)
        {
         if(trend[i+1]!=0.0)
           {
            up[i]=down[i+1];
            up[i+1]=up[i];
            arrup[i] = up[i] - 2*atr;
           }
           
         else
           {
            up[i]=MathMax(maxlowprice,up[i+1]);
           }
         atrhi[i] = up[i] - atr;
         atrlo[i] = up[i];
         down[i]=0.0;
        }

      else
        {
         if(trend[i+1]!=1.0)
           {
            down[i]=up[i+1];
            down[i+1]=down[i];
            arrdwn[i] = down[i] + 2*atr;           
           }
         else
         
           {
            down[i]=MathMin(minhighprice,down[i+1]);
           }
         atrhi[i] = down[i] + atr;
         atrlo[i] = down[i];
         up[i]=0.0;
        }
     }
 
 if(AlertsMessageBarUpDn || AlertsSoundBarUpDn)
  { 
   string message1 = (WindowExpertName()+" - "+Symbol()+"  "+PeriodString()+" - Signal Bar Up");
   string message2 = (WindowExpertName()+" - "+Symbol()+"  "+PeriodString()+" - Signal Bar Dn");
       
    if(TimeBar!=Time[0] && Close[1]>atrlo[1] && Open[1]<atrlo[1])
     { 
        if (AlertsMessageBarUpDn) Alert(message1);
        if (AlertsSoundBarUpDn)   PlaySound("alert2.wav");
        TimeBar=Time[0];
     }
    if(TimeBar!=Time[0] && Close[1]<atrlo[1] && Open[1]>atrlo[1])
     { 
        if (AlertsMessageBarUpDn) Alert(message2);
        if (AlertsSoundBarUpDn)   PlaySound("alert2.wav");
        TimeBar=Time[0];
    }
  }

     manageAlerts();
   return (0);
  }


void manageAlerts()
{
   if (alertsOn)
   {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1; 
         if (arrup[whichBar]  != EMPTY_VALUE) doAlert(whichBar,"up");
         if (arrdwn[whichBar] != EMPTY_VALUE) 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 =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," HalfTrend signal ",doWhat);
          if (alertsMessage) Alert(message);
          if (alertsEmail)   SendMail(StringConcatenate(Symbol(),"HalfTrend "),message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}



string PeriodString()
{
    switch (_Period) 
     {
        case PERIOD_M1:  return("M1");
        case PERIOD_M5:  return("M5");
        case PERIOD_M15: return("M15");
        case PERIOD_M30: return("M30");
        case PERIOD_H1:  return("H1");
        case PERIOD_H4:  return("H4");
        case PERIOD_D1:  return("D1");
        case PERIOD_W1:  return("W1");
        case PERIOD_MN1: return("MN1");
     }    
   return("M" + string(_Period));
}
