Back

Adjusted Slope = Exponential Slope --> Annualized Slope * R-squuared = Adjusted Slope

Super newbie here and as per this thread am working on developing the code to back test a momentum strategy. I believe I was able to track down the code the author used on this page. Based on my rudimentary analysis of this code, I believe it will get me to an adjusted slope which is essentially an annualized exponential slope number * r-squared. Have I read that right?

P.S. There will be errors in here as I have not defined the periods.

//Determine the Adjusted Slope for each stock in the defined universe which is the exponential slope * R-squared for each stock in the defined universe.
public double GetSlope()
{
double n = this.periods -1;
double x, y;
double[] xVals;
double[] yVals;
xVals = new double[this.periods];
yVals = new double[this.periods];


for (int i = 0; i < this.periods ; i++)
{
x = ((int)n- i);
y = Math.Log(inputs[0].LookBack(i));
xVals = x;
yVals = y;
}

double rsquared, yintercept, slope;

LinearRegression(xVals,yVals,0,this.periods - 1,out rsquared, out yintercept,out slope);

double annualSlope;
double dayCount = 250;

annualSlope = ((Math.Pow(Math.Exp(slope), dayCount))-1) *100; // Annualized percentage

//
annualSlope = annualSlope *rsquared;

return annualSlope;
}

public static void LinearRegression(double[] xVals, double[] yVals,
int inclusiveStart, int exclusiveEnd,
out double rsquared, out double yintercept,
out double slope)
{

double sumOfX = 0;
double sumOfY = 0;
double sumOfXSq = 0;
double sumOfYSq = 0;
double ssX = 0;
double ssY = 0;
double sumCodeviates = 0;
double sCo = 0;
double count = exclusiveEnd - inclusiveStart;

for (int ctr = inclusiveStart; ctr < exclusiveEnd; ctr++)
{
double x = xVals[ctr];
double y = yVals[ctr];
sumCodeviates += x * y;
sumOfX += x;
sumOfY += y;
sumOfXSq += x * x;
sumOfYSq += y * y;
}
ssX = sumOfXSq - ((sumOfX * sumOfX) / count);
ssY = sumOfYSq - ((sumOfY * sumOfY) / count);
double RNumerator = (count * sumCodeviates) - (sumOfX * sumOfY);
double RDenom = (count * sumOfXSq - (sumOfX * sumOfX))
* (count * sumOfYSq - (sumOfY * sumOfY));
sCo = sumCodeviates - ((sumOfX * sumOfY) / count);

double meanX = sumOfX / count;
double meanY = sumOfY / count;
double dblR = RNumerator / Math.Sqrt(RDenom);
rsquared = dblR * dblR;
yintercept = meanY - ((sCo / ssX) * meanX);
slope = sCo / ssX;
}
Update Backtest








Hey Jeremy, I took the code provided and modified it to use the supported MathNet.Numerics library. It has built in functions for things like linear regression and rsquared values. Have a peak at the AnnualizedExponentialSlope indicator I wrote.

Be sure to run it and take a peak at the AdjSlope chart, it seems reasonable to me, let me know what you think!
1

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Hi,

Is it possible to use an indicator on the fly dynamically and fill it with history data? I have a universe which is dynamically.

J.

RegisterIndicator("SPY", adjustedSlope, Resolution.Daily, Field.Close);
0

its a little old but check the post august 2015 a slope indicator was used:

https://www.quantconnect.com/forum/discussion/695/adjusted-slope--exponential-slope----annualized-slope--r-squuared--adjusted-slope
0

My algo runs into an algoritmic overflow error as the double is too large to fit the decimal. This happens because of the power of 252 days. If the slope is 2, the number of the power is huge. I tested with this unit test:

public void AESIComputesCorrectlyUptrend()
{
var aesi = new AnnualizedExponentialSlopeIndicator(4);
var data = new[] { 0m, 5m, 10m, 15m, 20m, 25m, 30m };

var seen = new List<decimal>();
for (int i = 0; i < data.Length; i++)
{
var datum = data[i];
seen.Add(datum);
aesi.Update(new IndicatorDataPoint(DateTime.Now.AddSeconds(i), datum));
}
Assert.Greater(aesi.Current.Value, 0m);
}

my indicator is:

using MathNet.Numerics;
using QuantConnect.Indicators;
using System;
using System.Linq;

//Copied from this forum:
//href https://www.quantconnect.com/forum/discussion/695/adjusted-slope--exponential-slope----annualized-slope--r-squuared--adjusted-slope/p1

namespace QuantConnect.Algorithm.CSharp.Helpers
{
public class AnnualizedExponentialSlopeIndicator : WindowIndicator<IndicatorDataPoint>
{
public AnnualizedExponentialSlopeIndicator(int period)
: base("AdjustedSlope" + period, period)
{
}

public AnnualizedExponentialSlopeIndicator(string name, int period)
: base(name, period)
{
}

protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
{
if (window.Count < 3) return 0m;

var xVals = new double[window.Count];
var yVals = new double[window.Count];

// load input data for regression
for (int i = 0; i < window.Count; i++)
{
xVals[i] = i;
// we want the log of our y values
yVals[i] = Math.Log((double)window[window.Count - i - 1].Value);
}

//http://numerics.mathdotnet.com/Regression.html

// solves y=a + b*x via linear regression
var fit = Fit.Line(xVals, yVals);
var intercept = fit.Item1;
var slope = fit.Item2;

// compute rsquared
var rsquared = GoodnessOfFit.RSquared(xVals.Select(x => intercept + slope * x), yVals);

// anything this small can be viewed as flat
if (double.IsNaN(slope) || Math.Abs(slope) < 1e-25) return 0m;

// trading days per year for us equities
const int dayCount = 252;

// annualize dy/dt
var annualSlope = ((Math.Pow(Math.Exp(slope), dayCount)) - 1) * 100;

// scale with rsquared
//annualSlope = annualSlope * Math.Pow(rsquared, 2);
annualSlope = annualSlope * rsquared;

return Convert.ToDecimal(annualSlope);

}
}
}

So this breaks the algorithm:

// trading days per year for us equities
const int dayCount = 252;

// annualize dy/dt
var annualSlope = ((Math.Pow(Math.Exp(slope), dayCount)) - 1) * 100;

Any idea how to avoid this?

0

my fault sorry....dont calculate it, try to use the indicator quantconnect built:

https://www.quantconnect.com/forum/discussion/1839/identifying-triangle-patterns/p1/comment-5707
0

Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed