From fb506efbb7f781c56415ce5b25d26a11615ef7c2 Mon Sep 17 00:00:00 2001 From: moshferatu Date: Fri, 10 May 2024 05:32:37 -0700 Subject: [PATCH] Add Hull Moving Average indicator --- indicators/HullMovingAverage.cs | 124 ++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 indicators/HullMovingAverage.cs diff --git a/indicators/HullMovingAverage.cs b/indicators/HullMovingAverage.cs new file mode 100644 index 0000000..b2087b6 --- /dev/null +++ b/indicators/HullMovingAverage.cs @@ -0,0 +1,124 @@ +#region Using declarations +using System; +using System.ComponentModel.DataAnnotations; +using System.Windows.Media; +using NinjaTrader.Gui; +using NinjaTrader.Gui.Chart; +#endregion + +//This namespace holds Indicators in this folder and is required. Do not change it. +namespace NinjaTrader.NinjaScript.Indicators +{ + [CategoryOrder("Hull Moving Average", 1)] + [CategoryOrder("Plots", 2)] + public class HullMovingAverage : Indicator + { + private Series RawHMA; + + private WMA WMA1; + private WMA WMA2; + private WMA HMA; + + protected override void OnStateChange() + { + if (State == State.SetDefaults) + { + Description = @"An implementation of the Hull Moving Average"; + Name = "Hull Moving Average"; + Calculate = Calculate.OnPriceChange; + IsOverlay = true; + PaintPriceMarkers = true; + ScaleJustification = ScaleJustification.Right; + IsSuspendedWhileInactive = false; + Period = 10; + AddPlot(new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3), PlotStyle.Line, "Hull Moving Average"); + } + else if (State == State.DataLoaded) + { + RawHMA = new Series(this); + + WMA1 = WMA(Input, (int)Math.Round(Period / 2.0)); + WMA2 = WMA(Input, Period); + HMA = WMA(RawHMA, (int)Math.Round(Math.Sqrt(Period))); + } + else if (State == State.Historical) + { + SetZOrder(-1); // Display behind bars on chart. + } + } + + protected override void OnBarUpdate() + { + RawHMA[0] = 2 * WMA1[0] - WMA2[0]; + Value[0] = HMA[0]; + } + + public override string DisplayName + { + get { return Name; } + } + + #region Properties + [Range(1, int.MaxValue), NinjaScriptProperty] + [Display(Name = "Period", Order = 1, GroupName = "Hull Moving Average")] + public int Period { get; set; } + #endregion + } +} + +#region NinjaScript generated code. Neither change nor remove. + +namespace NinjaTrader.NinjaScript.Indicators +{ + public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase + { + private HullMovingAverage[] cacheHullMovingAverage; + public HullMovingAverage HullMovingAverage(int period) + { + return HullMovingAverage(Input, period); + } + + public HullMovingAverage HullMovingAverage(ISeries input, int period) + { + if (cacheHullMovingAverage != null) + for (int idx = 0; idx < cacheHullMovingAverage.Length; idx++) + if (cacheHullMovingAverage[idx] != null && cacheHullMovingAverage[idx].Period == period && cacheHullMovingAverage[idx].EqualsInput(input)) + return cacheHullMovingAverage[idx]; + return CacheIndicator(new HullMovingAverage(){ Period = period }, input, ref cacheHullMovingAverage); + } + } +} + +namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns +{ + public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase + { + public Indicators.HullMovingAverage HullMovingAverage(int period) + { + return indicator.HullMovingAverage(Input, period); + } + + public Indicators.HullMovingAverage HullMovingAverage(ISeries input , int period) + { + return indicator.HullMovingAverage(input, period); + } + } +} + +namespace NinjaTrader.NinjaScript.Strategies +{ + public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase + { + public Indicators.HullMovingAverage HullMovingAverage(int period) + { + return indicator.HullMovingAverage(Input, period); + } + + public Indicators.HullMovingAverage HullMovingAverage(ISeries input , int period) + { + return indicator.HullMovingAverage(input, period); + } + } +} + +#endregion