Complete .mq5 source code

ADX MQL5 Indicator Code: Trend Strength Measurement with DI Cross

Read the ADX, +DI and -DI buffers in MQL5 and plot them in a separate indicator window. This educational example adds configurable DI crossover and ADX threshold alerts. It does not place orders or establish a profitable strategy; compile and inspect its output against the built-in ADX on the same chart before relying on it.

How the indicator signal works

Calculation and signal conditions

The example alerts when +DI crosses above -DI while ADX exceeds the chosen threshold and rises over three consecutive comparisons. The defaults 14, 20 and 55 are illustrative settings, not validated entry or exhaustion levels. Alert checks use the forming bar, so a condition can change before the bar closes. A trading EA should define closed-bar confirmation and risk rules separately.

Interpretation and limitations

A bearish alert uses the opposite DI crossover with the same ADX and slope filter. A separate alert reports ADX at or above the chosen upper threshold; high ADX alone does not predict a reversal. This indicator neither opens nor closes positions. Alerts can recur after the DI-distance reset condition, so test their timing before connecting downstream automation.

MQL5 Custom Indicator Code

//+------------------------------------------------------------------+
//|  ADX_TrendStrength.mq5                                            |
//|  ADX +DI/-DI display and alerts (Pineify.app)                     |
//|  Educational indicator; no verified performance results.         |
//+------------------------------------------------------------------+
#property copyright "Pineify.app"
#property link      "https://pineify.app"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3

#property indicator_label1  "ADX"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDeepPink
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#property indicator_label2  "+DI"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrLimeGreen
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#property indicator_label3  "-DI"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrangeRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

input int      ADX_Period        = 14;       // ADX period
input double   ADX_Threshold     = 20.0;     // Min ADX for trending
input double   OverextendLevel   = 55.0;     // Max ADX before reversal
input bool     EnableAlerts      = true;

int    g_adxHandle   = INVALID_HANDLE;
bool   g_alertedDI   = false;
bool   g_alertedOver = false;
double adxBuffer[], pdiBuffer[], ndiBuffer[];

//+------------------------------------------------------------------+
int OnInit()
  {
   if(ADX_Period < 2) return INIT_PARAMETERS_INCORRECT;
   SetIndexBuffer(0, adxBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, pdiBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, ndiBuffer, INDICATOR_DATA);
   PlotIndexSetString(0, PLOT_LABEL, "ADX(" + IntegerToString(ADX_Period) + ")");
   PlotIndexSetString(1, PLOT_LABEL, "+DI(" + IntegerToString(ADX_Period) + ")");
   PlotIndexSetString(2, PLOT_LABEL, "-DI(" + IntegerToString(ADX_Period) + ")");
   g_adxHandle = iADX(_Symbol, PERIOD_CURRENT, ADX_Period);
   if(g_adxHandle == INVALID_HANDLE) return INIT_FAILED;
   Print("ADX init OK | Period=", ADX_Period);
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(g_adxHandle != INVALID_HANDLE) IndicatorRelease(g_adxHandle);
  }

//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(rates_total < ADX_Period + 4) return 0;

   int copied;
   copied = CopyBuffer(g_adxHandle, 0, 0, rates_total, adxBuffer);
   if(copied != rates_total) return 0;
   copied = CopyBuffer(g_adxHandle, 1, 0, rates_total, pdiBuffer);
   if(copied != rates_total) return 0;
   copied = CopyBuffer(g_adxHandle, 2, 0, rates_total, ndiBuffer);
   if(copied != rates_total) return 0;

   ArraySetAsSeries(adxBuffer, true);
   ArraySetAsSeries(pdiBuffer, true);
   ArraySetAsSeries(ndiBuffer, true);

   if(prev_calculated > 0 && EnableAlerts)
     {
      bool adxRising = (adxBuffer[0] > adxBuffer[1] &&
                        adxBuffer[1] > adxBuffer[2] &&
                        adxBuffer[2] > adxBuffer[3]);
      bool crossAbove = (pdiBuffer[1] <= ndiBuffer[1] && pdiBuffer[0] > ndiBuffer[0]);
      bool crossBelow = (pdiBuffer[1] >= ndiBuffer[1] && pdiBuffer[0] < ndiBuffer[0]);
      bool trending   = (adxBuffer[0] >= ADX_Threshold);
      bool overext    = (adxBuffer[0] >= OverextendLevel);

      if(crossAbove && trending && adxRising && !g_alertedDI)
        {
         Alert(StringFormat("%s +DI ABOVE -DI | ADX=%.1f", _Symbol, adxBuffer[0]));
         g_alertedDI = true;
        }
      if(crossBelow && trending && adxRising && !g_alertedDI)
        {
         Alert(StringFormat("%s +DI BELOW -DI | ADX=%.1f", _Symbol, adxBuffer[0]));
         g_alertedDI = true;
        }
      if(MathAbs(pdiBuffer[0] - ndiBuffer[0]) > 3.0) g_alertedDI = false;
      if(overext && !g_alertedOver)
        {
         Alert(StringFormat("%s ADX=%.1f OVEREXTENDED", _Symbol, adxBuffer[0]));
         g_alertedOver = true;
        }
      if(adxBuffer[0] < OverextendLevel - 5.0) g_alertedOver = false;
     }

   return rates_total;
  }
//+------------------------------------------------------------------+

Copy this code into MetaEditor, save it in the MQL5/Indicators folder, and compile with F7.

Change the settings or add your own signal filter

Describe the inputs, buffers, alerts, visual style, or confirmation filter you want. Pineify generates editable MQL5 source code that you can inspect and compile in MetaEditor.

Frequently Asked Questions

Related MQL5 pages

Technical references

Risk and testing note

These educational examples require independent compilation and testing. A compile pass or an illustrative setting does not establish execution correctness or profitability. Any reported performance must be supported by reproducible data and test settings; past results do not predict future returns. Trading involves significant risk of loss. This content is not financial advice.