#region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.SuperDom; using NinjaTrader.Gui.Tools; using NinjaTrader.Data; using NinjaTrader.NinjaScript; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.DrawingTools; #endregion //This namespace holds Indicators in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Indicators { public class RSIDetrended : Indicator { private RSI rsi; private SMA sma; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Detrended RSI indicator"; Name = "RSI Detrended"; Calculate = Calculate.OnPriceChange; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = true; RSIPeriod = 2; MAPeriod = 20; AddPlot(new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3), PlotStyle.Line, "RSI Detrended"); } else if (State == State.DataLoaded) { rsi = RSI(Close, RSIPeriod, 3); sma = SMA(rsi, MAPeriod); } } protected override void OnBarUpdate() { if (CurrentBar < RSIPeriod || CurrentBar < MAPeriod) return; double detrendedRsi = rsi[0] - sma[0]; Value[0] = detrendedRsi; } public override string DisplayName { get { return Name; } } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "RSI Period", Description = "Period for the RSI calculation", Order = 1, GroupName = "RSI Detrended")] public int RSIPeriod { get; set; } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "MA Period", Description = "Period for the moving average calculation", Order = 2, GroupName = "RSI Detrended")] public int MAPeriod { get; set; } } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private RSIDetrended[] cacheRSIDetrended; public RSIDetrended RSIDetrended(int rSIPeriod, int mAPeriod) { return RSIDetrended(Input, rSIPeriod, mAPeriod); } public RSIDetrended RSIDetrended(ISeries input, int rSIPeriod, int mAPeriod) { if (cacheRSIDetrended != null) for (int idx = 0; idx < cacheRSIDetrended.Length; idx++) if (cacheRSIDetrended[idx] != null && cacheRSIDetrended[idx].RSIPeriod == rSIPeriod && cacheRSIDetrended[idx].MAPeriod == mAPeriod && cacheRSIDetrended[idx].EqualsInput(input)) return cacheRSIDetrended[idx]; return CacheIndicator(new RSIDetrended(){ RSIPeriod = rSIPeriod, MAPeriod = mAPeriod }, input, ref cacheRSIDetrended); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.RSIDetrended RSIDetrended(int rSIPeriod, int mAPeriod) { return indicator.RSIDetrended(Input, rSIPeriod, mAPeriod); } public Indicators.RSIDetrended RSIDetrended(ISeries input , int rSIPeriod, int mAPeriod) { return indicator.RSIDetrended(input, rSIPeriod, mAPeriod); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.RSIDetrended RSIDetrended(int rSIPeriod, int mAPeriod) { return indicator.RSIDetrended(Input, rSIPeriod, mAPeriod); } public Indicators.RSIDetrended RSIDetrended(ISeries input , int rSIPeriod, int mAPeriod) { return indicator.RSIDetrended(input, rSIPeriod, mAPeriod); } } } #endregion