Ultimate Oscillator in NinjaTrader — NinjaScript (C#) Source

A custom three-timeframe Ultimate Oscillator for NinjaTrader 8

Ultimate Oscillator in NinjaTrader
Ultimate Oscillator in NinjaTrader

The Ultimate Oscillator in NinjaScript keeps buying pressure and true range in Series<double> and sums them over three windows. See the explainer.

What you’ll need

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

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 AlgoGenUO : Indicator
    {
        private Series<double> bp, tr;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name        = "AlgoGen Ultimate Oscillator";
                Description = "Ultimate Oscillator (7/14/28)";
                S1 = 7; S2 = 14; S3 = 28;
                IsOverlay   = false;

                AddPlot(new Stroke(Brushes.DodgerBlue, 2), PlotStyle.Line, "UO");
                AddLine(Brushes.Gray, 70, "Overbought");
                AddLine(Brushes.Gray, 30, "Oversold");
            }
            else if (State == State.DataLoaded)
            {
                bp = new Series<double>(this);
                tr = new Series<double>(this);
            }
        }

        private double Sum(Series<double> s, int period)
        {
            double sum = 0;
            for (int i = 0; i < period; i++) sum += s[i];
            return sum;
        }

        protected override void OnBarUpdate()
        {
            if (CurrentBar == 0) { bp[0] = 0; tr[0] = High[0] - Low[0]; return; }

            double trueLow = Math.Min(Low[0], Close[1]);
            bp[0] = Close[0] - trueLow;
            tr[0] = Math.Max(High[0], Close[1]) - trueLow;

            if (CurrentBar < S3) return;
            double a1 = Sum(bp, S1) / Sum(tr, S1);
            double a2 = Sum(bp, S2) / Sum(tr, S2);
            double a3 = Sum(bp, S3) / Sum(tr, S3);
            Value[0] = 100.0 * (4 * a1 + 2 * a2 + a3) / 7.0;
        }

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

Compile & apply

  1. Press F5 to compile.
  2. Add AlgoGen Ultimate Oscillator to a chart; it draws in its own panel between 0 and 100 with the 30/70 lines, matching the output chart.

Gotchas

  • bp/tr as Series. Storing buying pressure and true range as Series<double> lets the window sums look back and survive reloads.
  • True low/high from Close[1]. The prior close in the min/max gives the true range, matching ATR.
  • Sum, then divide. Sum(bp)/Sum(tr) per window; the 4/2/1 weighting blends the three.

That’s the five-language set: Python, MQL5, Pine Script, EasyLanguage, and this one. Now test a UO rule 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