DMI
Download scriptThis script is a technical analysis tool designed for the MetaTrader platform. It automatically calculates and visualizes several market sentiment indicators on a single chart window, helping traders identify trend strength, direction, and volatility.
Instead of just showing raw price movements, this tool processes historical data to provide a clearer picture of market dynamics through the following logic:
Core Components & Calculations
1. Directional Movement (+DI and -DI) The script first analyzes the "range" of each price candle (the distance between the high and low). It determines if the price moved more toward the top or the bottom of that range:
- +DI (Positive Directional Indicator): Measures the strength of upward movement.
- -DI (Negative Directional Indicator): Measures the strength of downward movement. The tool normalizes these values against the overall market volatility, allowing traders to see which direction has more "momentum" at any given time.
2. DMI (Directional Movement Index) By combining the +DI and -DI values, the script calculates the DMI. This provides a relative measure of the difference between upward and downward pressure. It essentially tells you how much the market is leaning in one direction versus the other.
3. ADX (Average Directional Index) The ADX is one of the most popular components of this script. It takes the DMI data and applies a smoothing process over time. Rather than showing the direction of the trend, the ADX measures the strength of the trend.
- A rising ADX suggests a strengthening trend (regardless of whether it is going up or down).
- A falling ADX suggests a weakening trend or a transition into a sideways, choppy market.
4. ADXR (Average Directional Index Rate) This is a secondary smoothing of the ADX. It provides an even "softer" look at the trend strength by averaging the current ADX with its past value. This helps filter out minor fluctuations to highlight more significant, long-term shifts in market behavior.
User Customization & Visualization
The script is designed to be highly flexible for the user's visual preference:
- Smoothing: Users can adjust the "Smooth" parameter to decide how much historical data should be factored into the calculations (higher numbers result in smoother, slower lines; lower numbers are more reactive).
- Visibility Toggles: The script includes specific settings that allow users to hide any of the individual components (like +DI, -DI, DX, ADX, or ADXR) if they only want to focus on specific data points.
- Visual Levels: It establishes pre-defined horizontal levels (20 and 25), which are commonly used by traders as "thresholds" to identify when a trend is becoming significant enough to act upon.
Summary of Workflow
The script looks at price history $\rightarrow$ determines the primary direction of movement $\rightarrow$ measures the intensity of that movement $\rightarrow$ smooths that data out over a user-defined period $\rightarrow$ plots several lines on your screen so you can instantly see if the market is trending strongly, weakly, or moving sideways.
//+------------------------------------------------------------------+
//| 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 DodgerBlue
#property indicator_color2 Magenta
#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 = 14;
extern bool Hide_DI_Plus = False;
extern bool Hide_DI_Minus = False;
extern bool Hide_DX = true;
extern bool Hide_ADX = true;
extern bool Hide_ADXR = true;
//---- 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