Author: Copyright � 2006, Fernando Gomes.
DMI_001

This script is designed to provide traders with a comprehensive view of market trends by calculating and visualizing several key technical indicators simultaneously. It breaks down price movement into specific components to help identify the strength, direction, and momentum of the market.

Core Logic Overview

The script processes historical price data (highs, lows, and closes) to generate five distinct visual elements. Here is how it interprets the market:

1. Trend Direction (+DI and -DI) The tool first separates upward pressure from downward pressure. It looks at the range of each price bar to determine if the movement was primarily toward the "high" or the "low."

  • +DI (Positive Directional Index): Represents the strength of the upward movement.
  • -DI (Negative Directional Index): Represents the strength of the downward movement. By comparing these two, a trader can see which way the market is currently leaning.

2. Trend Magnitude (DX) The script then calculates the DX, which measures the relative difference between the upward and downward forces. Instead of just showing you where the price is going, this helps show the separation between the buying and selling pressure.

3. Trend Strength (ADX) One of the primary functions of this script is calculating the ADX (Average Directional Index). Unlike the DI lines, the ADX does not care if the market is going up or down; it only measures how strong the current trend is.

  • A rising ADX suggests a strong, trending market (whether bullish or bearish).
  • A falling ADX suggests a weak, ranging, or sideways market.

4. Trend Rate of Change (ADXR) Finally, the script calculates the ADXR, which is essentially a smoothed version of the ADX. This acts as a "rate of change" indicator, helping to filter out minor fluctuations and provide a cleaner look at how the trend's strength is evolving over time.

How the Data is Processed

To ensure the information is smooth and readable rather than jagged, the script employs several mathematical techniques:

  • Smoothing: It uses a user-defined "Smooth" parameter to weight recent price actions more heavily than older data, creating flowing lines on the chart.
  • True Range (TR): The script calculates the "True Range" of each bar—which considers not just the high and low of the current period, but also the relationship between the previous day's closing price and the current day's extremes. This ensures that gaps in price are accounted for accurately.
  • Dynamic Calculation: The script is designed to handle "initialization" logic, meaning it performs a heavy calculation at the start of the data set to establish a baseline before moving forward with real-time updates.

Summary for the User

When you view this on your platform, you are seeing a multi-layered analysis of market momentum. You can use it to distinguish between a strong trend (high ADX) and a weak one, see which side of the market is winning (+DI vs -DI), and observe the rate at which that strength is increasing or decreasing (ADXR).

Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
DMI_001
//+------------------------------------------------------------------+

//|                                                          DMI.mq4 |

//|                                Copyright © 2006, Fernando Gomes. |

//|                                    http://www.ciavox.com/~fgomes |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2006, Fernando Gomes."

#property link      "http://www.ciavox.com/~fgomes"



//---- indicator settings

#property  indicator_separate_window

#property  indicator_buffers 5

#property  indicator_color1  Lime

#property  indicator_color2  Red

#property  indicator_color3  Yellow

#property  indicator_color4  DeepSkyBlue

#property  indicator_color5  Blue



#property  indicator_minimum 0

#property  indicator_level1  20

#property  indicator_level2  25

#property  indicator_maximum 60



//---- indicator parameters

extern int Smooth   = 13;

extern bool Hide_DI_Plus  = False;

extern bool Hide_DI_Minus = False;

extern bool Hide_DX   = False;

extern bool Hide_ADX  = False;

extern bool Hide_ADXR = False;



//---- indicator buffers

double b_di_p[];     // buffer +DI

double b_di_m[];     // buffer -DI

double b_dmi[];      // buffer DMI

double b_adx[];      // buffer Average Directional indeX

double b_adxr[];     // buffer Average Directional indeX Rate



//---- non-indicator buffers

//---- NOTICE that these arrays must be included in ArraySetAsSeries()

double dm_p_avg[];

double dm_m_avg[];

double tr_avg[];





//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int init() {

   //---- indicator buffers mapping

   IndicatorBuffers(8);

   if (   !SetIndexBuffer(0,b_di_p)

       && !SetIndexBuffer(1,b_di_m)

       && !SetIndexBuffer(2,b_dmi)

       && !SetIndexBuffer(3,b_adx)

       && !SetIndexBuffer(4,b_adxr)

       && !SetIndexBuffer(5,dm_p_avg)

       && !SetIndexBuffer(6,dm_m_avg)

       && !SetIndexBuffer(7,tr_avg)

      ) { Print("cannot set indicator buffers!"); return(-1); }

   //---- name for DataWindow and indicator subwindow label

   IndicatorShortName("DMI("+Smooth+")");

   SetIndexLabel(0,"+DI");

   SetIndexLabel(1,"-DI");

   SetIndexLabel(2,"DX");

   SetIndexLabel(3,"ADX");

   SetIndexLabel(4,"ADXR");

   //----

   SetIndexStyle(0, DRAW_LINE+Hide_DI_Plus*DRAW_NONE, STYLE_SOLID, 1,
indicator_color1);

   SetIndexStyle(1, DRAW_LINE+Hide_DI_Minus*DRAW_NONE, STYLE_SOLID, 1,
indicator_color2);

   SetIndexStyle(2, DRAW_LINE+Hide_DX*DRAW_NONE, STYLE_SOLID, 1,
indicator_color3);

   SetIndexStyle(3, DRAW_LINE+Hide_ADX*DRAW_NONE, STYLE_SOLID, 1,
indicator_color4);

   SetIndexStyle(4, DRAW_LINE+Hide_ADXR*DRAW_NONE, STYLE_SOLID, 1,
indicator_color5);

   

   //----

   SetIndexDrawBegin(0,Smooth);

   SetIndexDrawBegin(1,Smooth);

   SetIndexDrawBegin(2,Smooth);

   SetIndexDrawBegin(3,2*Smooth);

   SetIndexDrawBegin(4,3*Smooth);

   

   return(0);

}

//+------------------------------------------------------------------+

//| Custor indicator deinitialization function                       |

//+------------------------------------------------------------------+

int deinit() {

   return(0);

}



//+------------------------------------------------------------------+

//| Custom indicator iteration function                              |

//+------------------------------------------------------------------+

int start() {

  int counted_bars=IndicatorCounted();

  if (counted_bars<0) return(-1);

  if (Bars < 2) return(-1);

  if (Smooth < 2) return(-1);

  int limit=Bars-1-counted_bars;

  

  double smooth = 1.0 / (Smooth * 1.0);



  int firstDMI  = Bars-1-Smooth;

  int firstADX  = Bars-1-(2*Smooth);

  int firstADXR = Bars-1-(3*Smooth);

  

  for (int i=limit; i>=0; i--) {

    double high;

    double low;

    double dm_p;

    double dm_m;

    

    if (i<firstDMI) {

      high = High[i]  - High[i+1];

      low  = Low[i+1] - Low[i];

      dm_p = 0.0;

      dm_m = 0.0;

      if ((high > low) && (high > 0.0))

        dm_p = high;

      else if ((low > high) && (low > 0.0))

        dm_m = low;

      // calculate averages (cumulative formula)

      dm_p_avg[i] = dm_p_avg[i+1] - ( smooth * dm_p_avg[i+1] ) + dm_p;

      dm_m_avg[i] = dm_m_avg[i+1] - ( smooth * dm_m_avg[i+1] ) + dm_m;

      tr_avg[i]   = tr_avg[i+1]   - ( smooth * tr_avg[i+1] )   +
calcTR(i);

    } else if (i==firstDMI) {

      double sum_dm_p = 0.0;

      double sum_dm_m = 0.0;

      double sum_tr   = 0.0;

      for (int j=i; j<i+Smooth; j++) {

        high = High[j]  - High[j+1];

        low  = Low[j+1] - Low[j];

        dm_p = 0.0 ;

        dm_m = 0.0 ;

        if ((high > low) && (high > 0.0))

          dm_p = high;

        else if ((low > high) && (low > 0.0))

          dm_m = low;

        sum_dm_p = sum_dm_p + dm_p;

        sum_dm_m = sum_dm_m + dm_m;

        sum_tr   = sum_tr   + calcTR(j);

      }

      // define current values

      dm_p_avg[i] = sum_dm_p * smooth;

      dm_m_avg[i] = sum_dm_m * smooth;

      tr_avg[i]   = sum_tr   * smooth;

    } else {

      tr_avg[i] = 0.0;

    }



    // Calculate +DI and -DI

    if (tr_avg[i] > 0.0) {

      b_di_p[i] = 100.0 * dm_p_avg[i] / tr_avg[i];

      b_di_m[i] = 100.0 * dm_m_avg[i] / tr_avg[i];

    } else {

      b_di_p[i] = 0.0;

      b_di_m[i] = 0.0;

    }



    // calcule DMI

    double sum  = b_di_p[i] + b_di_m[i];

    double diff = MathAbs( b_di_p[i] - b_di_m[i] );

    if (sum > 0.0) {

        b_dmi[i] = 100.0 *  diff / sum;

    } else {

        b_dmi[i] = 0.0 ;

    }



    // Calculate ADX

    if (i<firstADX) {   

      b_adx[i] = smooth*(b_adx[i+1]*(Smooth-1) + b_dmi[i]);

    } else if (i==firstADX) {

      double sum_dmi = 0.0;

      for (int k=i+Smooth+1; k>i; k--) {

        sum_dmi = sum_dmi + b_dmi[k];

      }

      b_adx[i] = smooth * sum_dmi;

    } else {

      b_adx[i] = 0.0;

    }

    

    // Calculate ADXR

    if (i<=firstADXR) {   

      b_adxr[i] = (b_adx[i] + b_adx[i+Smooth]) / 2;

    } else {

      b_adxr[i] = 0.0;

    }

    

  } // for



  return(0);

}



double calcTR(int bar) {

  double a = High[bar] - Low[bar];              // A = Today's High -Today's Low

  double b = MathAbs(Close[bar+1] - High[bar]); // B = Yesterday's Close - Today's High

  double c = MathAbs(Close[bar+1] - Low[bar]);  // C = Yesterday's Close - Today's Low

  return(MathMax(MathMax(a,b),c));

}



//+------------------------------------------------------------------+

Comments