// Original concept by Mobius, converted by ChatGPT
region Using declarations
using System;
using NinjaTrader.Cbi;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript.Strategies;
using NinjaTrader.NinjaScript.Indicators;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class TMO : Indicator
{
private Series<double> rawMomentum;
private EMA ema1;
private EMA mainEMA;
private EMA signalEMA;
[NinjaScriptProperty]
[Range(1, int.MaxValue), Gui.Label("Length")]
public int Length { get; set; }
[NinjaScriptProperty]
[Range(1, int.MaxValue), Gui.Label("Calculation Length")]
public int CalcLength { get; set; }
[NinjaScriptProperty]
[Range(1, int.MaxValue), Gui.Label("Smooth Length")]
public int SmoothLength { get; set; }
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"TMO (True Momentum Oscillator) by Mobius";
Name = "TMO";
Calculate = MarketCalculate.OnBarClose;
IsOverlay = false;
Length = 14;
CalcLength = 5;
SmoothLength = 3;
AddPlot(Brushes.LimeGreen, "Main");
AddPlot(Brushes.Gray, "Signal");
}
else if (State == State.DataLoaded)
{
rawMomentum = new Series<double>(this);
ema1 = EMA(rawMomentum, CalcLength);
mainEMA = EMA(ema1, SmoothLength);
signalEMA = EMA(mainEMA, SmoothLength);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < Length)
return;
double sum = 0.0;
for (int i = 0; i <= Length && CurrentBar - i >= 0; i++)
{
double delta = Close[0] > Open[i] ? 1 : Close[0] < Open[i] ? -1 : 0;
sum += delta;
}
rawMomentum[0] = sum;
Values[0][0] = mainEMA[0]; // Main line
Values[1][0] = signalEMA[0]; // Signal line
}
}
}

Comment