/// <summary> /// Calculate Hull Moving Average, as described here: /// <see href="https://alanhull.com/hull-moving-average"/> /// </summary> /// <param name="series">input time series</param> /// <param name="n">averaging length</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>HMA time series</returns> public static ITimeSeries <double> HMA(this ITimeSeries <double> series, int n, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); // http://www.incrediblecharts.com/indicators/weighted_moving_average.php // Integer(SquareRoot(Period)) WMA [2 x Integer(Period/2) WMA(Price) - Period WMA(Price)] int n2 = (int)Math.Round(n / 2.0); int n3 = (int)Math.Round(Math.Sqrt(n)); return(series .WMA(n2, cacheId) .Multiply(2.0, cacheId) .Subtract( series .WMA(n, cacheId), cacheId) .WMA(n3, cacheId)); }