Below is the code for the Hull Moving Average converted to work with RE2008. It is still in C#, but when you compile it to a DLL, it should work fine with systems written in VB.NET. If you prefer, a C# to VB converter would probably work fine on it.
Thanks,
Daniel
using System;
using System.Collections.Generic;
using System.Text;
using RightEdge.Common;
using RightEdge.Indicators;
namespace DoQ_Indicators
{
[
YYEIndicatorAttribute
(
System.Drawing.KnownColor.Blue,
YYEIndicatorAttribute.EIndicatorGroup.Other,
Author = "DoQ",
CompanyName = "www.TradeEngineer.com",
DefaultDrawingPane = "Price Pane",
Description = "Hull moving Average",
GroupName = "DoQ-Indicators",
HelpText = "",
Id = "2a272648-0661-4886-b4c6-7149f9ceb44d",
Name = "HullMA",
Version = "1.0"
)
]
[Serializable]
[SeriesInputAttribute("Input", 1, Value = BarElement.Close)]
public class HullMA : SeriesCalculatorBaseWithValues
{
private int _Period = 20;
private List<double> WMADiffValues;
[ConstructorArgument(Name = "Period",
Type = ConstructorArgumentType.Integer,
Value = "20",
Order = 1)]
public HullMA(int Period, int series)
: base(1)
{
if (Period <= 0)
{
throw new ArgumentException("Period must be greater than zero");
}
_Period = Period;
WMADiffValues = new List<double>();
}
private double WeightedMovingAverage(int lookBack, int periods, ISeries series)
{
//A 4 bar weighted moving average with prices of
//1.2900, 1.2900, 1.2903, and 1.2904 would give a moving average of 1.2903
//using the calculation
//((4 * 1.2904) + (3 * 1.2903) + (2 * 1.2900) + (1 * 1.2900)) / (4 + 3 + 2+ 1) = 1.2903
double Numerator = 0.0;
int Denominator = 0;
for (int i = 0; i < periods; i++)
{
Numerator += (series.LookBack(i + lookBack) * (periods - i));
Denominator += (periods - i);
}
return Numerator / Denominator;
}
// This method is where you calculate the indicator value for a given bar.
protected override double CalcNewValue(int lookBack)
{
int index = inputs[0].Count - lookBack - 1;
if (index < _Period - 1)
{
return double.NaN;
}
//Full Period
double WMAPeriod = WeightedMovingAverage(lookBack, _Period, inputs[0]);
//Half Period
double WMAHalfPeriod = WeightedMovingAverage(lookBack, _Period / 2, inputs[0]);
//store result with appropriate formula
//HMA = waverage(2*waverage(close,period/2)-waverage(close,period), SquareRoot(Period))
WMADiffValues.Add((2 * WMAHalfPeriod) - WMAPeriod);
//SQRT Period
int CurrentPeriod = (int)System.Math.Sqrt(_Period);
if (WMADiffValues.Count < CurrentPeriod)//not enough collected data
{
return double.NaN;
}
int index2 = WMADiffValues.Count - 1;
double WMASQRTPeriod = 0.0;
double Denominator = 0;
for (int i = index2 - CurrentPeriod + 1; i <= index2; i++)
{
WMASQRTPeriod += (WMADiffValues[i] * (i - (index2 - CurrentPeriod + 1) + 1));
Denominator += (i - (index2 - CurrentPeriod + 1) + 1);
}
WMASQRTPeriod /= Denominator;
return WMASQRTPeriod;
//HMA = waverage(2*waverage(close,period/2)-waverage(close,period), SquareRoot(Period))
}
protected override void Reset()
{
// This method is called when the series needs to be recalculated.
// If you save any state between calls to CalcNewValue(), you should
// reset that state in this method.
WMADiffValues.Clear();
}
}
}