Created
August 9, 2017 13:06
-
-
Save Jay-Jay-D/22195105915c065eb748c5466fafca11 to your computer and use it in GitHub Desktop.
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
using MathNet.Numerics; | |
using MathNet.Numerics.Distributions; | |
using MathNet.Numerics.Statistics; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace Optimization | |
{ | |
public class DeflatedSharpeRatio | |
{ | |
//number of trials | |
protected double N; | |
protected double MeanSharpeRatio; | |
//variance of results | |
protected double V; | |
protected double Kurtosis; | |
protected double Skewness; | |
//sample length. | |
protected double T; | |
private double e = Constants.E; | |
private double gamma = Constants.EulerMascheroni; | |
public double ExpectedMaximum => MeanSharpeRatio + SharpeRatioSubZero; | |
public double SharpeRatioSubZero => Math.Sqrt(V) * ((1 - gamma) * ZInverse(1 - 1 / N) + gamma * ZInverse(1 - 1 / (N * e))); | |
protected Dictionary<string, double> ReturnsData { get; set; } | |
protected Dictionary<string, double> SharpeData { get; set; } | |
public virtual void Initialize(IOptimizerConfiguration config) | |
{ | |
var fullResults = OptimizerAppDomainManager.GetResults(AppDomain.CurrentDomain); | |
ReturnsData = fullResults.ToDictionary(k => k.Key, v => (double)v.Value["CompoundingAnnualReturn"]); | |
SharpeData = fullResults.Where(s => s.Value["SharpeRatio"] != 0) | |
.ToDictionary(k => k.Key, v => (double)v.Value["SharpeRatio"]); | |
var statistics = new DescriptiveStatistics(SharpeData.Select(d => d.Value)); | |
N = statistics.Count; | |
MeanSharpeRatio = statistics.Mean; | |
V = statistics.Variance; | |
Skewness = statistics.Skewness; | |
Kurtosis = statistics.Kurtosis; | |
T = (config.EndDate - config.StartDate).Value.TotalDays; | |
} | |
public double Calculate(IOptimizerConfiguration config) | |
{ | |
Initialize(config); | |
return CalculateDeflatedSharpeRatio(ExpectedMaximum); | |
} | |
public double CalculateDeflatedSharpeRatio(double sharpeRatioZero) | |
{ | |
var nonAnnualized = (MeanSharpeRatio / Math.Sqrt(250)); | |
var top = (nonAnnualized - sharpeRatioZero) * Math.Sqrt(T - 1); | |
var bottom = Math.Sqrt(1 - (Skewness) * nonAnnualized + ((Kurtosis - 1) / 4) * Math.Pow(nonAnnualized, 2)); | |
return Z(top / bottom); | |
} | |
private double Z(double x) | |
{ | |
return Normal.CDF(0, 1, x); | |
} | |
//cumulative standard normal distribution inverse | |
private double ZInverse(double x) | |
{ | |
return Normal.InvCDF(0, 1, x); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment