MACD in NinjaTrader — NinjaScript (C#) Source

A three-plot MACD with a coloured histogram for NinjaTrader 8

MACD in NinjaTrader
MACD in NinjaTrader

Building the MACD in NinjaScript is a good step up from the SMA: three plots, two intermediate EMA series, and a histogram you colour by sign. It’s still short, and it teaches the pattern you’ll reuse for every multi-line indicator. See the explainer for what we’re drawing.

What you’ll need

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

The source

We keep the two price EMAs and the signal EMA as Series<double> so their recursion survives reloads, then colour the histogram per bar.

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

namespace NinjaTrader.NinjaScript.Indicators
{
    public class AlgoGenMACD : Indicator
    {
        private Series<double> emaFast;
        private Series<double> emaSlow;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name        = "AlgoGen MACD";
                Description = "MACD line, signal and histogram";
                Fast = 12; Slow = 26; Signal = 9;
                IsOverlay = false;

                AddPlot(new Stroke(Brushes.MediumSeaGreen, 2), PlotStyle.Bar,  "Histogram");
                AddPlot(new Stroke(Brushes.DodgerBlue, 2),     PlotStyle.Line, "Macd");
                AddPlot(new Stroke(Brushes.OrangeRed, 2),      PlotStyle.Line, "Signal");
                AddLine(Brushes.Gray, 0, "Zero");
            }
            else if (State == State.DataLoaded)
            {
                emaFast = new Series<double>(this);
                emaSlow = new Series<double>(this);
            }
        }

        private static double Ema(double price, double prev, int period, bool first)
        {
            double k = 2.0 / (period + 1.0);
            return first ? price : price * k + prev * (1.0 - k);
        }

        protected override void OnBarUpdate()
        {
            bool first = CurrentBar == 0;
            emaFast[0] = Ema(Close[0], first ? 0 : emaFast[1], Fast, first);
            emaSlow[0] = Ema(Close[0], first ? 0 : emaSlow[1], Slow, first);

            Macd[0]   = emaFast[0] - emaSlow[0];
            Signal[0] = Ema(Macd[0], first ? 0 : Signal[1], SignalPeriod, first);
            Histogram[0] = Macd[0] - Signal[0];

            PlotBrushes[0][0] = Histogram[0] >= 0 ? Brushes.MediumSeaGreen : Brushes.IndianRed;
        }

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

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

        [NinjaScriptProperty] [System.ComponentModel.DataAnnotations.Range(1, int.MaxValue)]
        [System.ComponentModel.Display(Name = "Signal", GroupName = "Parameters", Order = 2)]
        public int SignalPeriod { get => Signal; set => Signal = value; }
        public int Signal { get; set; }

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

Compile & apply

  1. Press F5 to compile.
  2. Add AlgoGen MACD to a chart. It draws in its own panel: green/red histogram, blue MACD line, orange signal line — the output chart above.

Gotchas

  • Signal the plot vs Signal the input. NinjaScript gets prickly about name collisions; here the public SignalLine plot is Values[2] while the integer input is exposed via SignalPeriod. Rename freely, just keep them distinct.
  • PlotBrushes[plotIndex][barsAgo] is how you colour a single bar of a plot — index 0 is the histogram plot, bar 0 is the current bar.
  • EMA seeding. We seed each EMA with its first value; NinjaTrader’s built-in EMA()/MACD() may seed slightly differently, so expect tiny warm-up differences that vanish after ~30 bars.

That’s the five-language set: Python, MQL5, Pine Script, EasyLanguage, and this one. Now see whether a MACD cross beats buy-and-hold 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. Gerald Appel (CMT Association)
  2. 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