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

The ExTrend indicator is designed to help traders visualize and measure market momentum by identifying specific structural "turning points" in price action. Rather than looking at every minor price fluctuation, the script focuses on significant peaks and valleys to determine the prevailing trend direction.

Core Logic and Functionality

1. Identification of Key Structural Points (Fractals) The script scans historical price data to identify "Fractals"—these are specific points where the price reaches a high or low relative to the bars immediately surrounding it.

  • Upper Fractals: These represent local peaks in the market.
  • Lower Fractals: These represent local troughs in the market.

2. Tracking Sequential Movements The logic is built to recognize a sequence of these points. Instead of just marking a single peak, the script tracks the two most recent confirmed upper and lower fractals. By keeping track of these two specific points for both directions, the tool can establish a clear line of movement between them.

3. Trend Line Projection and Calculation Once the script identifies two consecutive peaks (or troughs), it performs several background calculations:

  • Linear Mapping: It establishes a geometric connection between these two points. This effectively "connects the dots" to show the trajectory of the price movement.
  • Slope Analysis: The script calculates the mathematical angle (slope) of these trend lines. This is done by comparing the change in price against the amount of time elapsed between the two points.

4. Visual Representation The indicator translates this complex mathematical data into a visual format that is easy to read on a chart:

  • Trend Lines: It automatically draws trend lines connecting the identified fractals, allowing you to see the physical path of the market's " xương sống" (backbone).
  • Momentum Buffers: The script also processes these angles into data buffers. These represent the intensity of the trend—essentially quantifying how steep or shallow the current price movement is.

Summary for the User

In simple terms, ExTrend removes the "noise" of the market by ignoring minor price wiggles and focusing on major structural shifts. It automatically identifies the most recent significant highs and lows, draws lines between them to show you the current direction of the trend, and calculates the strength (angle) of those trends so you can better understand the market's momentum at a glance.

Indicators Used
Fractals
Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
ExTrend
//+------------------------------------------------------------------+
//|                                                      ExTrend.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_minimum -0.5
#property indicator_maximum 0.5
#property indicator_buffers 2
#property  indicator_color1  Green
#property  indicator_color2  Red
//----
double TrBufferUp[];
double TrBufferDn[];
//----
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;
   IndicatorBuffers(2);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, TrBufferUp);
   SetIndexDrawBegin(0, 1);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, TrBufferDn);
   SetIndexDrawBegin(1, 1);
   short_name = "ExTrend";
   IndicatorShortName(short_name);
   SetIndexLabel(0, "Up_Line");
   SetIndexLabel(1, "Down_Line");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| 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);
  }
//+------------------------------------------------------------------+
//| 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 = iFractals(NULL, 0, MODE_UPPER, i + 3);
       Fdn = iFractals(NULL, 0, MODE_LOWER, i + 3);
       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]);
           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(x==0) x=1;
           positive = MathArctan(x / y);  //*180/3.14; //)
         }
       if(FractDn1 != 0 && FractDn2 != 0)
         {
           double lvldn = LevelCalculate(FractDn1, FTimeDn1, FractDn2, FTimeDn2, Time[i]);
           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(b==0) b=1;
           negative = MathArctan(b / a);  //*180/3.14;
         }
       TrBufferUp[i+3] = positive;  //+negative;
       TrBufferDn[i+3] = negative;      
       i--;
     }
   return(0);
  }
//+------------------------------------------------------------------+

Comments