| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
namespace QuantConnect.Algorithm.CSharp
{
public class HurstAlgorithm : QCAlgorithm
{
public string symbol = "EURUSD";
RollingWindow<double> LogPrices;
RollingWindow<double> LogReturns;
public double H;
public override void Initialize()
{
SetStartDate(2010, 01, 10);
SetEndDate(DateTime.Now);
SetCash(100000);
SetWarmup(300);
AddSecurity(SecurityType.Forex, symbol, Resolution.Daily);
LogPrices = new RollingWindow<double>(30);
LogReturns = new RollingWindow<double>(256);
}
double RoundToNearest(double n, double x)
{
return Math.Round(n / x) * x;
}
public void OnData(QuoteBars data)
{
LogPrices.Add((Convert.ToDouble(data[symbol].Close))); if (!LogPrices.IsReady) return;
LogReturns.Add(Math.Log(LogPrices[0]/LogPrices[1])); if (!LogReturns.IsReady) return;
if (IsWarmingUp) return;
double[] Xs = new double[6];
double[] Ys = new double[6];
Xs[0] = Math.Log(256,2); Xs[1] = Math.Log(128,2); Xs[2] = Math.Log(64,2);
Xs[3] = Math.Log(32,2); Xs[4] = Math.Log(16,2); Xs[5] = Math.Log(8,2);
Ys[0] = Hurst.ReScaledRange(LogReturns, 1); Ys[1] = Hurst.ReScaledRange(LogReturns, 2);
Ys[2] = Hurst.ReScaledRange(LogReturns, 4); Ys[3] = Hurst.ReScaledRange(LogReturns, 8);
Ys[4] = Hurst.ReScaledRange(LogReturns, 16); Ys[5] = Hurst.ReScaledRange(LogReturns, 32);
double slope;
Hurst.LinearRegression(Xs, Ys, 0, 6, out slope);
H = slope;
Plot("Hurst Exponent", "Exponent" , H);
}
}
}namespace QuantConnect
{
public static class Hurst
{
public static double CalculateStdDev(IEnumerable<double> values)
{
double ret = 0;
if (values.Count() > 0)
{
double avg = values.Average();
double sum = values.Sum(d => Math.Pow(d - avg, 2));
ret = Math.Sqrt((sum) / (values.Count()-1));
}
return ret;
}
public static void LinearRegression(double[] xVals, double[] yVals,
int inclusiveStart, int exclusiveEnd,
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);
slope = sCo / ssX;
}
public static double ReScaledRange(RollingWindow<double> values, int x)
{
double Ret = 0;
double[] RSRange = new double[x];
if (values.Count() > 0)
{
int value = values.Count()/x;
for (int i = 0; i <= x-1; i++)
{
int y = 0;
double[] Section = new double[value];
double[] Core = new double[value];
for (int ii = (value*i); ii <= (value*i)+(value-1); ii++)
{
Core[y] = values[ii];
Section[y] = values[ii];
if (y > 0){
Section[y] = Section[y-1] + values[ii];}
y = y+1;
}
double Range = Section.Max() - Section.Min();
double StDev = CalculateStdDev(Core);
RSRange[i] = Range/StDev;
}
Ret = Math.Log(RSRange.Average(),2);
}
return Ret;
}
}
}using MathNet.Numerics.Integration;
namespace QuantConnect
{
public static class Dist
{
public static double V(double O, double alpha, double beta)
{
double O0 = (1/alpha) * Math.Atan(beta * Math.Tan((Math.PI*alpha)/2));
double x1 = Math.Pow(Math.Cos(alpha * O0),(1/(alpha-1)));
double x2 = Math.Pow(Math.Cos(O)/(Math.Sin(alpha*(O+O0))),(alpha/(alpha-1)));
double x3 = Math.Cos((alpha*O0)+((alpha-1)*O))/Math.Cos(O);
return x1*x2*x3;
}
public static double C1(double alpha, double beta)
{
double Ret = 0;
double O0 = (1/alpha) * Math.Atan(beta * Math.Tan((Math.PI*alpha)/2));
if (alpha < 1)
{
Ret = (1/Math.PI) * ((Math.PI/2) - O0);
}
if (alpha == 1)
{
Ret = 0;
}
if (alpha > 1)
{
Ret = 1;
}
return Ret;
}
public static double C2(double X, double alpha, double beta)
{
double Ret = 0;
double S = -beta * Math.Tan((Math.PI*alpha)/2);
if (alpha != 1)
{
Ret = alpha / (Math.PI * Math.Abs(alpha-1) * (X-S));
}
if (alpha == 1)
{
Ret = 1 / (2 * Math.Abs(beta));
}
return Ret;
}
public static double C3(double alpha)
{
double Ret = 0;
if (alpha != 1)
{
Ret = Math.Sign(1-alpha) / Math.PI;
}
if (alpha == 1)
{
Ret = 1/Math.PI;
}
return Ret;
}
public static double G(double O, double X, double alpha, double beta)
{
double Ret = 0;
double S = -beta * Math.Tan((Math.PI*alpha)/2);
if (alpha != 1)
{
Ret = Math.Pow(X-S, (alpha/(alpha-1))) * V(O, alpha, beta);
}
if (alpha == 1)
{
Ret = Math.Exp(-(Math.PI * X)/(2*beta)) * V(O, 1, beta);
}
return Ret;
}
public static double F(double X, double alpha, double beta)
{
double Ret = 0;
double O0 = (1/alpha) * Math.Atan(beta * Math.Tan((Math.PI*alpha)/2));
if(!(alpha<=0 || alpha>2 || beta<-1 || beta>1))
{
Ret = C1(alpha, beta) + C3(alpha) * NewtonCotesTrapeziumRule.IntegrateAdaptive(x => Math.Exp(-G(x, X, alpha, beta)), -O0, Math.PI/2, 1e-5);
}
return Ret;
}
public static double f(double X, double alpha, double beta)
{
double Ret = 0;
double O0 = (1/alpha) * Math.Atan(beta * Math.Tan((Math.PI*alpha)/2));
if(!(alpha<=0 || alpha>2 || beta<-1 || beta>1))
{
Ret = C2(X, alpha, beta) * NewtonCotesTrapeziumRule.IntegrateAdaptive(x => G(x, X, alpha, beta) * Math.Exp(-G(x, X, alpha, beta)), -O0, Math.PI/2, 1e-5);
}
return Ret;
}
public static double CDF(double X, double alpha, double beta)
{
double Ret = 0;
double S = -beta * Math.Tan((Math.PI*alpha)/2);
double O0 = (1/alpha) * Math.Atan(beta * Math.Tan((Math.PI*alpha)/2));
if(X > S)
{
Ret = F(X, alpha, beta);
}
if(X == S)
{
Ret = (1/Math.PI) * ((Math.PI/2)- O0);
}
if(X < S)
{
Ret = 1 - F(-X, alpha, -beta);
}
return Ret;
}
public static double PDF(double X, double alpha, double beta)
{
double Ret = 0;
double S = -beta * Math.Tan((Math.PI*alpha)/2);
double O0 = (1/alpha) * Math.Atan(beta * Math.Tan((Math.PI*alpha)/2));
if(X > S)
{
Ret = f(X, alpha, beta);
}
if(X == S)
{
Ret = 1; //Noooo fucking clue what this says
}
if(X < S)
{
Ret = f(-X, alpha, -beta);
}
return Ret;
}
}
}