#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 TMASlope : Indicator { private SMA sma; private ATR atr; private Series tma; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Credit to @BestForexMethod for the inspiration"; Name = "TMA Slope"; Calculate = Calculate.OnPriceChange; IsOverlay = false; DisplayInDataBox = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = true; TMAPeriod = 13; ATRPeriod = 100; PositiveBrush = Brushes.LimeGreen; NegativeBrush = Brushes.Red; NeutralBrush = Brushes.DimGray; ArePlotsConfigurable = false; AddPlot(new Stroke(Brushes.Transparent, 0), PlotStyle.Bar, "Histogram"); } else if (State == State.DataLoaded) { sma = SMA(Close, TMAPeriod); atr = ATR(ATRPeriod); tma = new Series(this); } } protected override void OnBarUpdate() { if (CurrentBar < TMAPeriod * 2 || CurrentBar < ATRPeriod) return; tma[0] = SMA(sma, TMAPeriod)[0]; double slope = (tma[0] - tma[1]) / atr[0]; Histogram[0] = slope; if (slope > 0 && slope > Histogram[1]) PlotBrushes[0][0] = PositiveBrush; else if (slope < 0 && slope < Histogram[1]) PlotBrushes[0][0] = NegativeBrush; else PlotBrushes[0][0] = NeutralBrush; } protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); foreach (Plot plot in Plots) plot.Width = chartControl.GetBarPaintWidth(ChartBars); } public override string DisplayName { get { return Name; } } [Browsable(false)] [XmlIgnore] public Series Histogram { get { return Values[0]; } } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "TMA Period", Order = 1, GroupName = "TMA Slope")] public int TMAPeriod { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "ATR Period", Order = 2, GroupName = "TMA Slope")] public int ATRPeriod { get; set; } [XmlIgnore] [Display(Name = "Positive Value", Order = 3, GroupName = "TMA Slope")] public Brush PositiveBrush { get; set; } [Browsable(false)] public string PositiveBrushSerializable { get { return Serialize.BrushToString(PositiveBrush); } set { PositiveBrush = Serialize.StringToBrush(value); } } [XmlIgnore] [Display(Name = "Negative Value", Order = 4, GroupName = "TMA Slope")] public Brush NegativeBrush { get; set; } [Browsable(false)] public string NegativeBrushSerializable { get { return Serialize.BrushToString(NegativeBrush); } set { NegativeBrush = Serialize.StringToBrush(value); } } [XmlIgnore] [Display(Name = "Neutral Value", Order = 5, GroupName = "TMA Slope")] public Brush NeutralBrush { get; set; } [Browsable(false)] public string NeutralBrushSerializable { get { return Serialize.BrushToString(NeutralBrush); } set { NeutralBrush = Serialize.StringToBrush(value); } } } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private TMASlope[] cacheTMASlope; public TMASlope TMASlope(int tMAPeriod, int aTRPeriod) { return TMASlope(Input, tMAPeriod, aTRPeriod); } public TMASlope TMASlope(ISeries input, int tMAPeriod, int aTRPeriod) { if (cacheTMASlope != null) for (int idx = 0; idx < cacheTMASlope.Length; idx++) if (cacheTMASlope[idx] != null && cacheTMASlope[idx].TMAPeriod == tMAPeriod && cacheTMASlope[idx].ATRPeriod == aTRPeriod && cacheTMASlope[idx].EqualsInput(input)) return cacheTMASlope[idx]; return CacheIndicator(new TMASlope(){ TMAPeriod = tMAPeriod, ATRPeriod = aTRPeriod }, input, ref cacheTMASlope); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.TMASlope TMASlope(int tMAPeriod, int aTRPeriod) { return indicator.TMASlope(Input, tMAPeriod, aTRPeriod); } public Indicators.TMASlope TMASlope(ISeries input , int tMAPeriod, int aTRPeriod) { return indicator.TMASlope(input, tMAPeriod, aTRPeriod); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.TMASlope TMASlope(int tMAPeriod, int aTRPeriod) { return indicator.TMASlope(Input, tMAPeriod, aTRPeriod); } public Indicators.TMASlope TMASlope(ISeries input , int tMAPeriod, int aTRPeriod) { return indicator.TMASlope(input, tMAPeriod, aTRPeriod); } } } #endregion