Author: Copyright � 2006, Alex Sidd (Executer)
ExTrendv2

The ExTrendv2 script is a technical analysis tool designed to identify and visualize market trends by automatically detecting specific price "fractals" and calculating the momentum of the resulting trend lines. Instead of simply plotting basic moving averages, this script looks for structural turning points in the price history to draw dynamic trend lines.

Core Logic and Functionality

1. Fractal Detection (Identifying Turning Points) The foundation of the script is its ability to identify "Fractals"—specific peaks and valleys in price action.

  • Upper Fractals: The script scans for a high point that is higher than the candles immediately preceding and following it. This represents a local peak in price.
  • Lower Fractals: Conversely, it looks for a low point that is lower than the surrounding candles, representing a local valley or "floor" in price action.

2. Dynamic Trend Line Construction Once the script identifies these fractal points, it automatically links them to form trend lines:

  • It tracks the two most recent significant peaks to draw an Upper Trend Line.
  • It tracks the two most recent significant valleys to draw a Lower Trend Line.
  • These lines are calculated mathematically to project forward from the historical data points, providing a visual boundary for current market movement.

3. Trend Momentum and Crossings The script doesn't just draw lines; it analyzes how the price interacts with them. It calculates the "angle" or intensity of these trend lines using trigonometric math (Arctan). This helps determine the strength of the current trend.

4. Signal Generation (Buffer Logic) The script provides specific signals based on "breakouts" or interactions with these calculated lines:

  • Positive Signals: When the price moves from below a projected upper trend line to above it, and then maintains that position, the script identifies a bullish sentiment.
  • Negative Signals: When the price drops from above a projected lower trend line to below it, and stays there, the script identifies a bearish sentiment.

Visual Representation

To make this data actionable for the user, the script renders three distinct elements on the trading platform:

  • Trend Lines: Visual boundaries showing the current path of least resistance.
  • Up/Down Indicators: Visual markers (arrows) that appear when the price satisfies the specific "breakout" conditions mentioned above.
  • Separate Window Tracking: The script maintains a buffer to track these values accurately across the timeline, ensuring that historical data remains consistent as new candles form.
Miscellaneous
Implements a curve of type %1
7 Views
0 Downloads
0 Favorites
ExTrendv2
//+------------------------------------------------------------------+
//|                                                    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);
  }
//+------------------------------------------------------------------+

Comments