Ichimoku in NinjaTrader — NinjaScript (C#) Source

Computing the five lines, with notes on plotting the cloud

Ichimoku in NinjaTrader
Ichimoku in NinjaTrader

Ichimoku in NinjaScript is mostly midpoint math, with the wrinkle that plotting a line into the future isn’t something a normal plot does — so we compute all five lines and handle displacement with plot offsets. See the explainer for the components.

What you’ll need

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

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 AlgoGenIchimoku : Indicator
    {
        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name        = "AlgoGen Ichimoku";
                Description = "Ichimoku Kinko Hyo";
                Tenkan = 9; Kijun = 26; SenkouBLen = 52; Displacement = 26;
                IsOverlay = true;

                AddPlot(new Stroke(Brushes.OrangeRed, 2), PlotStyle.Line, "TenkanLine");
                AddPlot(new Stroke(Brushes.MediumPurple, 2), PlotStyle.Line, "KijunLine");
                AddPlot(new Stroke(Brushes.MediumSeaGreen, 1), PlotStyle.Line, "SenkouA");
                AddPlot(new Stroke(Brushes.IndianRed, 1), PlotStyle.Line, "SenkouB");
                AddPlot(new Stroke(Brushes.SeaGreen, 1), PlotStyle.Line, "Chikou");
            }
        }

        private double Mid(int len)
        {
            double hh = High[0], ll = Low[0];
            for (int i = 1; i < len; i++)
            {
                if (High[i] > hh) hh = High[i];
                if (Low[i]  < ll) ll = Low[i];
            }
            return (hh + ll) / 2.0;
        }

        protected override void OnBarUpdate()
        {
            if (CurrentBar < SenkouBLen) return;

            double tenkan = Mid(Tenkan);
            double kijun  = Mid(Kijun);
            TenkanLine[0] = tenkan;
            KijunLine[0]  = kijun;

            // Senkou spans: value computed now, displayed Displacement bars FORWARD.
            SenkouA[0] = (tenkan + kijun) / 2.0;
            SenkouB[0] = Mid(SenkouBLen);

            // Chikou: current close displayed Displacement bars BACK.
            Chikou[0] = Close[0];
        }

        #region Properties
        [NinjaScriptProperty][System.ComponentModel.DataAnnotations.Range(1,int.MaxValue)]
        public int Tenkan { get; set; }
        [NinjaScriptProperty][System.ComponentModel.DataAnnotations.Range(1,int.MaxValue)]
        public int Kijun { get; set; }
        [NinjaScriptProperty][System.ComponentModel.DataAnnotations.Range(1,int.MaxValue)]
        public int SenkouBLen { get; set; }
        [NinjaScriptProperty][System.ComponentModel.DataAnnotations.Range(0,int.MaxValue)]
        public int Displacement { get; set; }

        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> TenkanLine => Values[0];
        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> KijunLine  => Values[1];
        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> SenkouA    => Values[2];
        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> SenkouB    => Values[3];
        [Gui.Browsable(false)][System.Xml.Serialization.XmlIgnore] public Series<double> Chikou     => Values[4];
        #endregion
    }
}

Handling the displacement

The code computes the correct values; displaying them shifted is the last step. In NinjaTrader you set a plot’s displacement with Plots[index].Displacement:

// In State.Configure, after the AddPlot calls:
Plots[2].Displacement =  Displacement;   // Senkou A forward
Plots[3].Displacement =  Displacement;   // Senkou B forward
Plots[4].Displacement = -Displacement;   // Chikou back

Gotchas

  • Compute now, display shifted. Don’t try to write future values into [0] — compute the span value on the current bar and let the plot’s Displacement push it forward; use a negative displacement for the Chikou.
  • The cloud fill. NinjaTrader can shade between two plots with Draw regions or a PlotStyle fill; the exact approach depends on your version, but the two span values above are what you fill between.
  • Warm-up. Guard CurrentBar < SenkouBLen so the 52-period midpoint has data.

That’s the five-language set: Python, MQL5, Pine Script, EasyLanguage, and this one. Now test an Ichimoku system 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. Ichimoku: At a Glance (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