Created
May 17, 2017 17:31
-
-
Save mikewlange/12780acee4629e6c9732bf0398566da0 to your computer and use it in GitHub Desktop.
Lin Reg Slope w/ Exp Weighting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Using declarations | |
using System; | |
using System.ComponentModel; | |
using System.Diagnostics; | |
using System.Drawing; | |
using System.Drawing.Drawing2D; | |
using System.Xml.Serialization; | |
using NinjaTrader.Cbi; | |
using NinjaTrader.Data; | |
using NinjaTrader.Gui.Chart; | |
#endregion | |
// This namespace holds all indicators and is required. Do not change it. | |
namespace NinjaTrader.Indicator | |
{ | |
/// <summary> | |
/// Linear regression slope - w/ exponential weighting option | |
/// </summary> | |
[Description("Linear regression slope - w/ exponential weighting option")] | |
public class mlLinRegSlope : Indicator | |
{ | |
#region Variables | |
// Wizard generated variables | |
private int period = 8; // Default setting for Period | |
private bool exponential = false; // Default setting for Exponential | |
private int returnval = 0; // Default setting for returnval | |
// exponential moving regression slope variables | |
private int nn = 0; | |
private double n, w, sumX, sumX2, sumY1, sumXY1, correction; | |
// super fast linear regression slope variables | |
private double m1, m2, sumP, sumIP; | |
// public results, updated each bar | |
public double slope, yvalue, err; | |
#endregion | |
/// <summary> | |
/// This method is used to configure the indicator and is called once before any bar data is loaded. | |
/// </summary> | |
protected override void Initialize() | |
{ | |
Add(new Plot(Color.FromKnownColor(KnownColor.MediumBlue), PlotStyle.Line, "SlopeSFX")); | |
Add(new Line(Color.FromKnownColor(KnownColor.DarkOliveGreen), 0, "Zero")); | |
CalculateOnBarClose = true; | |
Overlay = false; | |
PriceTypeSupported = true; | |
} | |
/// <summary> | |
/// Called on each bar update event (incoming tick) | |
/// </summary> | |
protected override void OnBarUpdate() | |
{ | |
double rtn; | |
int ix; | |
if (exponential) { | |
// Super optimised calulations. very fast. | |
double denom, sumY = 0.0, sumXY = 0.0; | |
if (period != nn || CurrentBar < 1) { | |
nn = period; | |
n = (nn-1.0)*0.75 + 1.0; | |
sumX = 0.5 * n*(n-1.0); | |
sumX2 = (n-1.0)*n*(2.0*n-1.0)/6.0; | |
sumY = Input[0] * n; | |
sumXY = sumX*Input[0]; | |
w = 2.0 / (n + 1.0); | |
correction = (n+1.0) / (3.0*n); | |
if (CurrentBar < 1) { | |
sumY1 = sumY; | |
sumXY1 = sumXY; | |
} | |
} else { | |
sumY = w*Input[0]*n + (1.0-w)*sumY1; | |
sumXY = Input[0]*(n-1.0) + sumXY1*(n-2.0)/n; | |
sumY1 = sumY; | |
sumXY1 = sumXY; | |
} | |
denom = n*sumX2 - sumX*sumX; | |
if (denom < 0.00001) denom = 0.00001; | |
slope = correction * n*(n*sumXY - sumX*sumY) / denom; | |
yvalue = sumY/n + slope * 0.5*n; | |
} | |
else { | |
int ix1; | |
if (CurrentBar < period || nn != period || CurrentBar % 10000 == 0) { | |
nn = period; | |
m1 = 6.0 / ((double)period * ((double)period + 1.0)); | |
m2 = 2.0 / ((double)period - 1.0); | |
sumP = 0.0; sumIP = 0.0; | |
for (ix = 0; ix < period; ++ix) { | |
ix1 = (ix < CurrentBar) ? ix : CurrentBar; | |
sumP += Input[ix1]; | |
sumIP += (ix1 * Input[ix1]); | |
} | |
} else { | |
sumIP += (sumP - period * Input[period]); | |
sumP += (Input[0] - Input[period]); | |
} | |
slope = m1 * (sumP - m2 * sumIP); | |
yvalue = sumP/period + slope * period * 0.5; | |
} | |
switch (returnval) { | |
case 3: | |
rtn = 0.0; | |
if (CurrentBar > 1) { | |
for (ix = 0; ix < ((CurrentBar <= period) ? CurrentBar+1 : period); ++ix) { | |
rtn = (Input[ix] - (-slope * ix + yvalue)); | |
err += rtn*rtn; | |
} | |
rtn = err = Math.Sqrt(err/ix); | |
} | |
break; | |
case 2: rtn = yvalue; break; | |
default: rtn = slope; break; | |
} | |
SlopeSFX.Set(rtn); // result | |
} | |
#region Properties | |
[Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove | |
[XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove | |
public DataSeries SlopeSFX | |
{ | |
get { return Values[0]; } | |
} | |
[Description("Lookback interval")] | |
[Category("Parameters")] | |
public int Period | |
{ | |
get { return period; } | |
set { period = Math.Max(1, value); } | |
} | |
[Description("true=exponential moving slope, false=normal weighting")] | |
[Category("Parameters")] | |
public bool Exponential | |
{ | |
get { return exponential; } | |
set { exponential = value; } | |
} | |
[Description("Return value 1=slope, 2=LinReg value, 3=average error")] | |
[Category("Parameters")] | |
public int Returnval | |
{ | |
get { return returnval; } | |
set { returnval = Math.Max(1, value); } | |
} | |
#endregion | |
} | |
} | |
#region NinjaScript generated code. Neither change nor remove. | |
// This namespace holds all indicators and is required. Do not change it. | |
namespace NinjaTrader.Indicator | |
{ | |
public partial class Indicator : IndicatorBase | |
{ | |
private mlLinRegSlope[] cachemlLinRegSlope = null; | |
private static mlLinRegSlope checkmlLinRegSlope = new mlLinRegSlope(); | |
/// <summary> | |
/// Linear regression slope - super fast calc with exponential weighting option | |
/// </summary> | |
/// <returns></returns> | |
public mlLinRegSlope mlLinRegSlope(bool exponential, int period, int returnval) | |
{ | |
return mlLinRegSlope(Input, exponential, period, returnval); | |
} | |
/// <summary> | |
/// Linear regression slope - super fast calc with exponential weighting option | |
/// </summary> | |
/// <returns></returns> | |
public mlLinRegSlope mlLinRegSlope(Data.IDataSeries input, bool exponential, int period, int returnval) | |
{ | |
if (cachemlLinRegSlope != null) | |
for (int idx = 0; idx < cachemlLinRegSlope.Length; idx++) | |
if (cachemlLinRegSlope[idx].Exponential == exponential && cachemlLinRegSlope[idx].Period == period && cachemlLinRegSlope[idx].Returnval == returnval && cachemlLinRegSlope[idx].EqualsInput(input)) | |
return cachemlLinRegSlope[idx]; | |
lock (checkmlLinRegSlope) | |
{ | |
checkmlLinRegSlope.Exponential = exponential; | |
exponential = checkmlLinRegSlope.Exponential; | |
checkmlLinRegSlope.Period = period; | |
period = checkmlLinRegSlope.Period; | |
checkmlLinRegSlope.Returnval = returnval; | |
returnval = checkmlLinRegSlope.Returnval; | |
if (cachemlLinRegSlope != null) | |
for (int idx = 0; idx < cachemlLinRegSlope.Length; idx++) | |
if (cachemlLinRegSlope[idx].Exponential == exponential && cachemlLinRegSlope[idx].Period == period && cachemlLinRegSlope[idx].Returnval == returnval && cachemlLinRegSlope[idx].EqualsInput(input)) | |
return cachemlLinRegSlope[idx]; | |
mlLinRegSlope indicator = new mlLinRegSlope(); | |
indicator.BarsRequired = BarsRequired; | |
indicator.CalculateOnBarClose = CalculateOnBarClose; | |
#if NT7 | |
indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256; | |
indicator.MaximumBarsLookBack = MaximumBarsLookBack; | |
#endif | |
indicator.Input = input; | |
indicator.Exponential = exponential; | |
indicator.Period = period; | |
indicator.Returnval = returnval; | |
Indicators.Add(indicator); | |
indicator.SetUp(); | |
mlLinRegSlope[] tmp = new mlLinRegSlope[cachemlLinRegSlope == null ? 1 : cachemlLinRegSlope.Length + 1]; | |
if (cachemlLinRegSlope != null) | |
cachemlLinRegSlope.CopyTo(tmp, 0); | |
tmp[tmp.Length - 1] = indicator; | |
cachemlLinRegSlope = tmp; | |
return indicator; | |
} | |
} | |
} | |
} | |
// This namespace holds all market analyzer column definitions and is required. Do not change it. | |
namespace NinjaTrader.MarketAnalyzer | |
{ | |
public partial class Column : ColumnBase | |
{ | |
/// <summary> | |
/// Linear regression slope - super fast calc with exponential weighting option | |
/// </summary> | |
/// <returns></returns> | |
[Gui.Design.WizardCondition("Indicator")] | |
public Indicator.mlLinRegSlope mlLinRegSlope(bool exponential, int period, int returnval) | |
{ | |
return _indicator.mlLinRegSlope(Input, exponential, period, returnval); | |
} | |
/// <summary> | |
/// Linear regression slope - super fast calc with exponential weighting option | |
/// </summary> | |
/// <returns></returns> | |
public Indicator.mlLinRegSlope mlLinRegSlope(Data.IDataSeries input, bool exponential, int period, int returnval) | |
{ | |
return _indicator.mlLinRegSlope(input, exponential, period, returnval); | |
} | |
} | |
} | |
// This namespace holds all strategies and is required. Do not change it. | |
namespace NinjaTrader.Strategy | |
{ | |
public partial class Strategy : StrategyBase | |
{ | |
/// <summary> | |
/// Linear regression slope - super fast calc with exponential weighting option | |
/// </summary> | |
/// <returns></returns> | |
[Gui.Design.WizardCondition("Indicator")] | |
public Indicator.mlLinRegSlope mlLinRegSlope(bool exponential, int period, int returnval) | |
{ | |
return _indicator.mlLinRegSlope(Input, exponential, period, returnval); | |
} | |
/// <summary> | |
/// Linear regression slope - super fast calc with exponential weighting option | |
/// </summary> | |
/// <returns></returns> | |
public Indicator.mlLinRegSlope mlLinRegSlope(Data.IDataSeries input, bool exponential, int period, int returnval) | |
{ | |
if (InInitialize && input == null) | |
throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method"); | |
return _indicator.mlLinRegSlope(input, exponential, period, returnval); | |
} | |
} | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment