ADX in NinjaTrader — NinjaScript (C#) Source

Using the built-in ADX and DM for a directional system

ADX in NinjaTrader
ADX in NinjaTrader

Given the ADX’s multi-stage math (see the explainer), NinjaTrader’s built-in ADX and DM indicators are the sensible building blocks — we compose them into a single directional-system indicator with a regime read.

What you’ll need

  • NinjaTrader 8
  • New → NinjaScript Editor → Indicators → New Indicator, name it AlgoGenADX

The source

#region Using declarations
using System;
using System.Windows.Media;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.Indicators;
#endregion

namespace NinjaTrader.NinjaScript.Indicators
{
    public class AlgoGenADX : Indicator
    {
        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name        = "AlgoGen ADX";
                Description = "ADX with +DI / -DI (directional system)";
                Period      = 14;
                TrendLevel  = 25;
                IsOverlay   = false;

                AddPlot(new Stroke(Brushes.DodgerBlue, 2),      PlotStyle.Line, "AdxLine");
                AddPlot(new Stroke(Brushes.MediumSeaGreen, 2),  PlotStyle.Line, "PlusDI");
                AddPlot(new Stroke(Brushes.IndianRed, 2),       PlotStyle.Line, "MinusDI");
                AddLine(Brushes.Gray, 25, "Trend");
            }
        }

        protected override void OnBarUpdate()
        {
            // DM(Period) exposes +DI and -DI; ADX(Period) exposes the strength line.
            AdxLine[0] = ADX(Period)[0];
            PlusDI[0]  = DM(Period).DiPlus[0];
            MinusDI[0] = DM(Period).DiMinus[0];
        }

        #region Properties
        [NinjaScriptProperty][System.ComponentModel.DataAnnotations.Range(1, int.MaxValue)]
        [System.ComponentModel.Display(Name = "Period", GroupName = "Parameters", Order = 0)]
        public int Period { get; set; }

        [NinjaScriptProperty]
        [System.ComponentModel.Display(Name = "TrendLevel", GroupName = "Parameters", Order = 1)]
        public double TrendLevel { get; set; }

        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> AdxLine => Values[0];
        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> PlusDI  => Values[1];
        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> MinusDI => Values[2];
        #endregion
    }
}

Using it as a regime filter

In a strategy, the ADX earns its keep by gating trend signals:

bool strongUp = ADX(14)[0] > 25 && DM(14).DiPlus[0] > DM(14).DiMinus[0];
if (strongUp && /* your entry trigger */)
    EnterLong();

The math, if you build from scratch

The full chain (identical to the Python post): +DM/−DM keep only the larger positive directional move; Wilder-smooth them and the ATR; form +DI and −DI as 100 × smoothed(DM) / ATR; compute DX = 100 × |+DI−−DI| / (+DI+−DI); Wilder-smooth DX into ADX. NinjaTrader’s ADX/DM implement this, so reusing them guarantees your values match the platform.

Gotchas

  • DM(Period).DiPlus / .DiMinus. The direction lines live on the DM indicator; ADX gives only the strength line. You need both.
  • Lag. Double smoothing makes ADX slow; treat it as a filter.
  • Warm-up. Built-ins handle their own warm-up, but early bars are still unreliable until the smoothing settles (~2×Period).

That’s the five-language set: Python, MQL5, Pine Script, EasyLanguage, and this one. Now test an ADX regime filter in AlgoGen.


This post is educational, not financial advice. Indicators describe the past; they don’t predict the future. Backtest anything before you risk real money on it.

Sources and further reading

  1. NinjaScript system indicator methods (NinjaTrader)

Historical research from the Algogen archive. Not investment advice.

Blog

Have a strategy idea?

Describe it in plain English, preview where your rules fire, then decide whether the evidence is worth a backtest.

Keep me postedHow it works