//+------------------------------------------------------------------+
//|                                                    ExTrendv2.mq4 |
//|                           Copyright © 2006, Alex Sidd (Executer) |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Alex Sidd (Executer)"
#property link      "mailto:work_st@mail.ru"
//----
#property indicator_separate_window
#property indicator_buffers 4
#property  indicator_color1  Green
#property  indicator_color2  Red
//----
double TrBufferUp[];
double TrBufferDn[];
double FrBufferUp[];
double FrBufferDn[];
//----
double FractUp1 = 0;
double FractUp2 = 0;
double FractDn1 = 0;
double FractDn2 = 0;
datetime FTimeUp1, FTimeUp2, FTimeDn1, FTimeDn2, curTime;
//+------------------------------------------------------------------+
//| ExTrend initialization function                                  |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
//----   
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, TrBufferUp);
   SetIndexDrawBegin(0, 1);
   SetIndexLabel(0, "Up_Line");
//----   
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, TrBufferDn);
   SetIndexDrawBegin(1, 1);
   SetIndexLabel(1, "Down_Line");
//----   
   SetIndexStyle(2, DRAW_ARROW);
   SetIndexBuffer(2, FrBufferUp);
   SetIndexDrawBegin(2, 1);
   SetIndexLabel(2, "Up_Fractal");
   SetIndexArrow(2, 217);
//----   
   SetIndexStyle(3, DRAW_ARROW);
   SetIndexBuffer(3, FrBufferDn);
   SetIndexDrawBegin(3, 1);
   SetIndexLabel(3, "DownFractal");
   SetIndexArrow(3, 218);
//----
   short_name="ExTrend";
   IndicatorShortName(short_name);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   ObjectDelete("FractalLineUp");
   ObjectDelete("FractalLineDn");   
   return(0);
  }
//+------------------------------------------------------------------+
//| Level Calculate Function                                         |
//| функция взята из FractalLines Indicator                          |
//+------------------------------------------------------------------+
double LevelCalculate(double Price1, double Time1, double Price2,  
                      double Time2, double NewTime)
  {
   double level;
   if(Time2 != Time1) // На всякий случай, чтобы не было деления на 0.
       level = (NewTime - Time1)*(Price2 - Price1) / (Time2-Time1) + Price1;
   else
       return(Price2);
   return(level);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+  
double isUpFract(int i)
  {
   if(High[i+3] > High[i+2] && High[i+3] > High[i+4] && High[i+4] > High[i+5] && 
      High[i+2] > High[i+1]) 
       return(High[i+3]);
   else 
       return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double isDnFract(int i)
  {
   if(Low[i+3] < Low[i+2] && Low[i+3] < Low[i+4] && Low[i+4] < Low[i+5] && 
      Low[i+2] < Low[i+1]) 
       return(Low[i+3]);
   else 
       return(0);
  }
//+------------------------------------------------------------------+
//| Executer Trend Indicator                                         |
//+------------------------------------------------------------------+
int start()
  {
   int i, counted_bars = IndicatorCounted();
   i = Bars - 1;
   double Fup, Fdn, positive, negative;  
   while(i >= 0)
     {
       negative = 0;
       positive = 0;
       Fup = isUpFract(i);
       Fdn = isDnFract(i);
       if(Fup != 0) 
         {
           if(FractUp1 == 0&&FractUp2 == 0) 
             {
               FractUp1 = Fup; 
               FTimeUp1 = Time[i+3];
             }
           if(FractUp1 != 0 && FractUp2 == 0 && FTimeUp1 != Time[i+3]) 
             {
               FractUp2 = Fup; 
               FTimeUp2 = Time[i+3];
             }
           if(FractUp1 != 0 && FractUp2 != 0 && FTimeUp2 != Time[i+3])
             {
               FractUp1 = FractUp2;
               FTimeUp1 = FTimeUp2;
               FractUp2 = Fup;
               FTimeUp2 = Time[i+3];
             } 
         }
       if(Fdn != 0) 
         {
           if(FractDn1 == 0 && FractDn2 == 0) 
             {
               FractDn1 =Fdn; 
               FTimeDn1 = Time[i+3];
             }
           if(FractDn1 != 0 && FractDn2 == 0 && FTimeDn1 != Time[i+3]) 
             {
               FractDn2 = Fdn; 
               FTimeDn2 = Time[i+3];
             }
           if(FractDn1 !=0 && FractDn2 != 0 && FTimeDn2 != Time[i+3])
             {
               FractDn1 = FractDn2;
               FTimeDn1 = FTimeDn2;
               FractDn2 = Fdn;
               FTimeDn2 = Time[i+3];
             } 
         }
       if(FractUp1 != 0 && FractUp2 != 0)
         {
           double lvlup = LevelCalculate(FractUp1, FTimeUp1, FractUp2, FTimeUp2, 
                                         Time[i]);
           double lvlup_old = LevelCalculate(FractUp1, FTimeUp1, FractUp2, FTimeUp2,
                              Time[i+1]); 
           ObjectCreate("FractalLineUp", OBJ_TREND, 0, FTimeUp1, FractUp1, FTimeUp2,
                        FractUp2);
           ObjectSet("FractalLineUp", OBJPROP_TIME1, FTimeUp1);
           ObjectSet("FractalLineUp", OBJPROP_PRICE1, FractUp1);
           ObjectSet("FractalLineUp", OBJPROP_TIME2, FTimeUp2);
           ObjectSet("FractalLineUp", OBJPROP_PRICE2, FractUp2);
           double y = (FTimeUp2 - FTimeUp1) / (240*60);
           double x = (FractUp2 - FractUp1)*(240);
           if(y == 0) 
               y = 1;
           positive = MathArctan(x / y);
           if(Open[i+1] < lvlup_old && Close[i+1] > lvlup_old && Open[i] > lvlup) 
               FrBufferUp[i] = positive;
         }
       if(FractDn1 != 0 && FractDn2 != 0)
         {
           double lvldn = LevelCalculate(FractDn1, FTimeDn1, FractDn2, FTimeDn2, Time[i]);
           double lvldn_old = LevelCalculate(FractDn1, FTimeDn1, FractDn2, FTimeDn2, 
                                             Time[i+1]);
           ObjectCreate("FractalLineDn", OBJ_TREND, 0, FTimeDn1, FractDn1, FTimeDn2, 
                        FractDn2);
           ObjectSet("FractalLineDn", OBJPROP_TIME1, FTimeDn1);
           ObjectSet("FractalLineDn", OBJPROP_PRICE1, FractDn1);
           ObjectSet("FractalLineDn", OBJPROP_TIME2, FTimeDn2);
           ObjectSet("FractalLineDn", OBJPROP_PRICE2, FractDn2);
           double a = (FTimeDn2 - FTimeDn1) / (240*60);
           double b = (FractDn2 - FractDn1)*(240);
           if(a == 0) 
               a = 1; 
           negative = MathArctan(b / a);
           if(Open[i+1] > lvldn_old && Close[i+1] < lvldn_old && Open[i] < lvlup) 
               FrBufferDn[i] = negative;
         }
       TrBufferUp[i+3] = positive;
       TrBufferDn[i+3] = negative;      
       i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+