DMI alert
Download scriptThis script is a technical analysis tool designed for the MetaTrader platform to help traders identify market trends and volatility using the DMI (Directional Movement Index) system. Rather than just showing simple price movement, it breaks down price action into specific components to help users understand whether the market is moving up, down, or sideways with strength.
Core Logic & Functionality
1. Trend Identification (+DI and -DI) The script monitors the "movement" of price by comparing the highs and lows of current bars against previous ones.
- It calculates a Plus Directional Indicator (+DI) to measure upward pressure.
- It calculates a Minus Directional Indicator (-DI) to measure downward pressure. By comparing these two, a trader can see which direction the market is currently favoring.
2. Trend Strength (ADX and ADXR) While +DI and -DI tell you the direction, the script also calculates indices that tell you the strength of that trend:
- ADX (Average Directional Index): This measures the overall intensity of the trend. A rising ADX suggests a strengthening trend, while a falling one suggests a weakening movement.
- ADXR: This is a smoothed version of the ADX, used to provide a secondary layer of trend stability analysis.
3. Smoothing and Calculation The script utilizes a "Smoothing" parameter (defaulting to 14). This ensures that the data isn't erratic; it averages out the price movements over a specific window of time to provide a cleaner, more readable line on your chart. It uses a cumulative calculation method to ensure that the historical data remains consistent and accurate as new bars form.
4. Visual Customization The tool is designed to be flexible for the user's visual preferences. It allows you to:
- Toggle specific components on or off (such as hiding the DX, ADX, or ADXR lines).
- Define specific color coding for different trend elements.
- Set visual boundaries (levels) on the indicator window to help identify key thresholds.
5. Automated Alerts One of the primary functional features of this script is its notification system. It monitors the relationship between the +DI and -DI lines in real-time:
- Cross-over Detection: If the +DI line crosses over the -DI line (indicating a shift from bearish to bullish sentiment, or vice versa), the script triggers an alert.
- Notification Types: Depending on your settings, it can provide a pop-up alert message and play an audio file simultaneously to ensure you don't miss a potential change in market momentum.
//+------------------------------------------------------------------+
//| DMI alert.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 bool AlertsEnabled = false;
extern string AlertsSound = "alert.wav";
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
//---- NOTICE that these arrays must be included in ArraySetAsSeries()
double dm_p_avg[];
double dm_m_avg[];
double tr_avg[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void 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;
}
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("DMI alert(" + 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);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
static datetime AlertTime = 0;
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;
}
if (AlertsEnabled && i == 0 && AlertTime != Time[0]) {
if ((b_di_p[0] > b_di_m[0] && b_di_p[1] <= b_di_m[1]) || (b_di_p[0] < b_di_m[0] && b_di_p[1] >= b_di_m[1])) {
AlertTime = Time[0];
Alert("DMI Indicator! ", Symbol(), " M", Period());
if (StringLen(AlertsSound) > 0)
PlaySound(AlertsSound);
}
}
} // for
}
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