#region Using declarations using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Data; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Windows.Media; #endregion namespace NinjaTrader.NinjaScript.Indicators { public class ATRRegime : Indicator { private const int PrimaryBars = 0; private const int ADRBars = 1; private ATR atr; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @""; Name = "ATR Regime"; Calculate = Calculate.OnBarClose; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = true; ATRPeriod = 5; RankPeriod = 252; // Approximately 1 year in trading days. AddPlot(new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3), PlotStyle.Line, "ATR Regime"); } else if (State == State.Configure) { AddDataSeries(Instrument.FullName, new BarsPeriod { BarsPeriodType = BarsPeriodType.Day, Value = 1 }, RankPeriod * 2, Instrument.MasterInstrument.TradingHours.Name, Bars.IsResetOnNewTradingDay); } else if (State == State.DataLoaded) { atr = ATR(BarsArray[ADRBars], ATRPeriod); } } protected override void OnBarUpdate() { if (PrimaryBars != BarsInProgress) return; if (CurrentBars[ADRBars] < RankPeriod) return; List atrValues = new List(); for (int i = RankPeriod; i > 0; i--) atrValues.Add(atr[i]); double currentAtrValue = atr[0]; int rank = atrValues.Count(x => x <= currentAtrValue); Value[0] = (double)rank / RankPeriod; } public override string DisplayName { get { return Name; } } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "ATR Period", Description = "Period for the ATR calculation", GroupName = "ATR Regime", Order = 1)] public int ATRPeriod { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Rank Period", Description = "Period for the percent rank lookback", GroupName = "ATR Regime", Order = 2)] public int RankPeriod { get; set; } } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private ATRRegime[] cacheATRRegime; public ATRRegime ATRRegime(int aTRPeriod, int rankPeriod) { return ATRRegime(Input, aTRPeriod, rankPeriod); } public ATRRegime ATRRegime(ISeries input, int aTRPeriod, int rankPeriod) { if (cacheATRRegime != null) for (int idx = 0; idx < cacheATRRegime.Length; idx++) if (cacheATRRegime[idx] != null && cacheATRRegime[idx].ATRPeriod == aTRPeriod && cacheATRRegime[idx].RankPeriod == rankPeriod && cacheATRRegime[idx].EqualsInput(input)) return cacheATRRegime[idx]; return CacheIndicator(new ATRRegime(){ ATRPeriod = aTRPeriod, RankPeriod = rankPeriod }, input, ref cacheATRRegime); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.ATRRegime ATRRegime(int aTRPeriod, int rankPeriod) { return indicator.ATRRegime(Input, aTRPeriod, rankPeriod); } public Indicators.ATRRegime ATRRegime(ISeries input , int aTRPeriod, int rankPeriod) { return indicator.ATRRegime(input, aTRPeriod, rankPeriod); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.ATRRegime ATRRegime(int aTRPeriod, int rankPeriod) { return indicator.ATRRegime(Input, aTRPeriod, rankPeriod); } public Indicators.ATRRegime ATRRegime(ISeries input , int aTRPeriod, int rankPeriod) { return indicator.ATRRegime(input, aTRPeriod, rankPeriod); } } } #endregion