#region Using declarations using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using System.ComponentModel.DataAnnotations; using System.Windows.Media; #endregion namespace NinjaTrader.NinjaScript.Indicators { public class ATRTrailingStop : Indicator { private ATR atr; private Series atrHighs; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"ATR Trailing Stop"; Name = "ATR Trailing Stop"; Calculate = Calculate.OnPriceChange; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = true; AtrPeriod = 5; HighestHighPeriod = 9; Multiplier = 2.0; AddPlot(new Stroke(Brushes.LimeGreen, DashStyleHelper.Solid, 3), PlotStyle.Line, "ATR Trailing Stop"); } else if (State == State.DataLoaded) { atr = ATR(AtrPeriod); atrHighs = new Series(this); } else if (State == State.Historical) { SetZOrder(-1); // Display behind bars on chart. } } protected override void OnBarUpdate() { if (CurrentBar < AtrPeriod) return; atrHighs[0] = High[0] - atr[0] * Multiplier; Value[0] = MAX(atrHighs, HighestHighPeriod)[0]; if (Close[0] > Value[0]) PlotBrushes[0][0] = Brushes.LimeGreen; else if (Close[0] < Value[0]) PlotBrushes[0][0] = Brushes.Red; } public override string DisplayName { get { return Name; } } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "ATR Period", Order = 1, GroupName = "ATR Trailing Stop")] public int AtrPeriod { get; set; } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "Highest High Period", Order = 2, GroupName = "ATR Trailing Stop")] public int HighestHighPeriod { get; set; } [Range(1, double.MaxValue), NinjaScriptProperty] [Display(Name = "Multiplier", Order = 3, GroupName = "ATR Trailing Stop")] public double Multiplier { get; set; } } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private ATRTrailingStop[] cacheATRTrailingStop; public ATRTrailingStop ATRTrailingStop(int atrPeriod, int highestHighPeriod, double multiplier) { return ATRTrailingStop(Input, atrPeriod, highestHighPeriod, multiplier); } public ATRTrailingStop ATRTrailingStop(ISeries input, int atrPeriod, int highestHighPeriod, double multiplier) { if (cacheATRTrailingStop != null) for (int idx = 0; idx < cacheATRTrailingStop.Length; idx++) if (cacheATRTrailingStop[idx] != null && cacheATRTrailingStop[idx].AtrPeriod == atrPeriod && cacheATRTrailingStop[idx].HighestHighPeriod == highestHighPeriod && cacheATRTrailingStop[idx].Multiplier == multiplier && cacheATRTrailingStop[idx].EqualsInput(input)) return cacheATRTrailingStop[idx]; return CacheIndicator(new ATRTrailingStop(){ AtrPeriod = atrPeriod, HighestHighPeriod = highestHighPeriod, Multiplier = multiplier }, input, ref cacheATRTrailingStop); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.ATRTrailingStop ATRTrailingStop(int atrPeriod, int highestHighPeriod, double multiplier) { return indicator.ATRTrailingStop(Input, atrPeriod, highestHighPeriod, multiplier); } public Indicators.ATRTrailingStop ATRTrailingStop(ISeries input , int atrPeriod, int highestHighPeriod, double multiplier) { return indicator.ATRTrailingStop(input, atrPeriod, highestHighPeriod, multiplier); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.ATRTrailingStop ATRTrailingStop(int atrPeriod, int highestHighPeriod, double multiplier) { return indicator.ATRTrailingStop(Input, atrPeriod, highestHighPeriod, multiplier); } public Indicators.ATRTrailingStop ATRTrailingStop(ISeries input , int atrPeriod, int highestHighPeriod, double multiplier) { return indicator.ATRTrailingStop(input, atrPeriod, highestHighPeriod, multiplier); } } } #endregion