This script is a specialized technical analysis tool designed to measure and visualize market trends by evaluating the strength and direction of price movements. It modifies the traditional Average Directional Index (ADX) logic to provide a clearer picture of how momentum shifts between buying and selling pressures.
Core Logic Overview
The script functions by breaking down price action into three distinct components: movement direction, volatility, and trend intensity. It processes historical data to determine whether the market is trending strongly in one direction or moving sideways with no clear bias.
Key Processing Steps
1. Directional Movement Tracking The logic first examines every candle to identify "True Range" (the maximum price movement) and distinguishes between upward and downward movement.
- It calculates how much the high of the current candle exceeds the high of the previous one.
- It simultaneously calculates how much the low of the current candle drops below the previous low.
- Crucially, it only recognizes a move as "positive" or "negative" if it significantly outweighs the movement in the opposite direction.
2. Smoothing and Normalization To prevent the data from being too "noisy," the script applies Exponential Moving Averages (EMA). It smoothes out both the directional movements and the volatility data over specific timeframes. These smoothed values are then divided by the average volatility to create standardized indicators (+DI and -DI), which represent the relative strength of buyers versus sellers.
3. The DX and ADX Calculation The script combines the buyer and seller strengths into a single value called DX (Directional Index). This represents the percentage of trend strength regardless of direction. Finally, it applies another smoothing layer to create the primary ADX line.
Visual Indicators and Alerts
The script goes beyond just showing a single line; it categorizes market behavior into two visual outputs:
- Trend Identification: The tool compares the current trend value against its previous value. If the trend strength is increasing, it plots a positive movement on the histogram.
- Momentum Shifts: When the trend strength begins to decrease (meaning the move is losing steam or reversing), the logic captures this "Otkat" (potential reversal/weakness) by shifting the visual focus to show that the momentum is fading.
Summary for Traders
Instead of just telling you if the price is going up or down, this script helps you see how much effort is being put into that move. By highlighting where trend strength is growing and where it is beginning to collapse, it serves as a visual guide to help identify strong trends and potential points of exhaustion in the market.
//+------------------------------------------------------------------+
//| ADXdon.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_color1 Green
#property indicator_color2 LimeGreen
#property indicator_color3 Red
#property indicator_color8 Lime
#property indicator_level1 35
#property indicator_level2 15
#property indicator_level3 5
//#property indicator_level4 10
//#property indicator_level5 12.5
#property indicator_maximum 50
#property indicator_minimum -10
//---- input parameters
extern int ADXPeriod=14, DiPlusPeriod = 34, DiMinusPeriod=34;
extern double levelADX=15.0;
//---- buffers
double ADXBufferTrend[];
double ADXBufferOtkat[];
double PlusDiBuffer[];
double MinusDiBuffer[];
double PlusSdiBuffer[];
double MinusSdiBuffer[];
double TRBuffer[];
double TempBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- 3 additional buffers are used for counting.
IndicatorBuffers(8);
//---- indicator buffers
SetIndexBuffer(0,ADXBufferTrend);
SetIndexBuffer(1,PlusDiBuffer);
SetIndexBuffer(2,MinusDiBuffer);
SetIndexBuffer(3,PlusSdiBuffer);
SetIndexBuffer(4,MinusSdiBuffer);
SetIndexBuffer(5,TempBuffer);
SetIndexBuffer(6, TRBuffer );
SetIndexBuffer(7,ADXBufferOtkat);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("ADX("+ADXPeriod+", DI-: "+DiMinusPeriod+", DI+: "+DiPlusPeriod+")");
SetIndexLabel(0,"ADX");
SetIndexLabel(1,"+DI");
SetIndexLabel(2,"-DI");
//----
SetIndexDrawBegin(0,ADXPeriod);
SetIndexDrawBegin(1,ADXPeriod);
SetIndexDrawBegin(2,ADXPeriod);
//----
SetIndexStyle(0, DRAW_HISTOGRAM,0,2);
SetIndexStyle(7, DRAW_HISTOGRAM,0,2);
SetIndexStyle(1, DRAW_NONE);
SetIndexStyle(2, DRAW_NONE);
return(0);
}
//+------------------------------------------------------------------+
//| Average Directional Movement Index |
//+------------------------------------------------------------------+
int start()
{
double tmp=0.0, tmpold=0.0;
double pdm,mdm,tr;
double price_high,price_low;
int starti,i,counted_bars=IndicatorCounted();
//----
//int limit=Bars-2;
int limit=Bars-counted_bars;
if(counted_bars>0) limit++;
i = limit;
starti = i;
//----
while(i>=0)
{
price_low=Low[i];
price_high=High[i];
//----
pdm = 0.0;
mdm = 0.0;
if ( price_high > High[i+1] )
pdm = price_high - High[i+1];
if ( price_low < Low[i+1] )
mdm = Low[i+1] - price_low;
if ( pdm < mdm )
pdm = 0.0;
else if ( mdm < pdm )
mdm = 0.0;
//---- absolute true range
double num1=MathAbs(price_high-price_low);
double num2=MathAbs(price_high-Close[i+1]);
double num3=MathAbs(price_low-Close[i+1]);
tr=MathMax(num1,num2);
tr=MathMax(tr,num3);
//---- counting plus/minus direction
PlusSdiBuffer[i]=pdm;
MinusSdiBuffer[i]=mdm;
TRBuffer[i] = tr;
//----
i--;
}
//---- apply EMA to +DI
for(i=0; i<limit; i++) {
//---- apply EMA to TR
TRBuffer[i]=iMAOnArray(TRBuffer,0,ADXPeriod,0,MODE_EMA,i);
PlusDiBuffer[i] = PlusDiBuffer[i+1];
MinusDiBuffer[i] = MinusDiBuffer[i+1];
if ( TRBuffer[i] != 0 ) {
PlusDiBuffer[i]=iMAOnArray(PlusSdiBuffer,Bars,DiPlusPeriod,0,MODE_EMA,i) / TRBuffer[i];
//---- apply EMA to -DI
MinusDiBuffer[i]=iMAOnArray(MinusSdiBuffer,Bars,DiMinusPeriod,0,MODE_EMA,i) / TRBuffer[i];
}
}
//---- Directional Movement (DX)
i=Bars-2;
//TempBuffer[i+1]=0;
i=starti;
while(i>=0)
{
double div=MathAbs(PlusDiBuffer[i]+MinusDiBuffer[i]);
if(div==0.00) TempBuffer[i]=TempBuffer[i+1];
else TempBuffer[i]=MathAbs(PlusDiBuffer[i]-MinusDiBuffer[i]) / div;
i--;
}
//---- ADX is exponential moving average on DX
for(i=0; i<limit; i++) {
tmp=(iMAOnArray(TempBuffer,0,ADXPeriod,0,MODE_EMA,i) * 100.0)-levelADX;
if (tmp>tmpold){
ADXBufferTrend[i]=tmp;
ADXBufferOtkat[i]=0.0;
}
if (tmp<=tmpold){
ADXBufferTrend[i]=0.0;
ADXBufferOtkat[i]=tmp;
}
tmpold=tmp;
// PlusDiBuffer[i] = PlusDiBuffer[i] * 100.0;
// MinusDiBuffer[i] = MinusDiBuffer[i] * 100.0;
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments