public void CovarianceOfFloatList_SourceIsEmptyCollection_InvalidOperationExceptionThrown() { IEnumerable <float> measure1 = new List <float>(); IEnumerable <float> measure2 = new List <float>(); Action comparison = () => { measure1.Covariance(measure2); }; comparison.ShouldThrow <InvalidOperationException>(); }
/// <summary> /// Algorithm "beta" statistic - the covariance between the algorithm and benchmark performance, divided by benchmark's variance /// </summary> /// <param name="algoPerformance">Collection of double values for algorithm daily performance.</param> /// <param name="benchmarkPerformance">Collection of double benchmark daily performance values.</param> /// <remarks>Invokes the variance and covariance extensions in the MathNet Statistics class</remarks> /// <returns>Value for beta</returns> public static double Beta(List <double> algoPerformance, List <double> benchmarkPerformance) { return(algoPerformance.Covariance(benchmarkPerformance) / benchmarkPerformance.Variance()); }
/// <summary> /// Initializes a new instance of the <see cref="PortfolioStatistics"/> class /// </summary> /// <param name="profitLoss">Trade record of profits and losses</param> /// <param name="equity">The list of daily equity values</param> /// <param name="listPerformance">The list of algorithm performance values</param> /// <param name="listBenchmark">The list of benchmark values</param> /// <param name="startingCapital">The algorithm starting capital</param> /// <param name="tradingDaysPerYear">The number of trading days per year</param> public PortfolioStatistics( SortedDictionary <DateTime, decimal> profitLoss, SortedDictionary <DateTime, decimal> equity, List <double> listPerformance, List <double> listBenchmark, decimal startingCapital, int tradingDaysPerYear = 252) { if (startingCapital == 0) { return; } var runningCapital = startingCapital; var totalProfit = 0m; var totalLoss = 0m; var totalWins = 0; var totalLosses = 0; foreach (var pair in profitLoss) { var tradeProfitLoss = pair.Value; if (tradeProfitLoss > 0) { totalProfit += tradeProfitLoss / runningCapital; totalWins++; } else { totalLoss += tradeProfitLoss / runningCapital; totalLosses++; } runningCapital += tradeProfitLoss; } AverageWinRate = totalWins == 0 ? 0 : totalProfit / totalWins; AverageLossRate = totalLosses == 0 ? 0 : totalLoss / totalLosses; ProfitLossRatio = AverageLossRate == 0 ? 0 : AverageWinRate / Math.Abs(AverageLossRate); WinRate = profitLoss.Count == 0 ? 0 : (decimal)totalWins / profitLoss.Count; LossRate = profitLoss.Count == 0 ? 0 : (decimal)totalLosses / profitLoss.Count; Expectancy = WinRate * ProfitLossRatio - LossRate; if (startingCapital != 0) { TotalNetProfit = equity.Values.LastOrDefault() / startingCapital - 1; } var fractionOfYears = (decimal)(equity.Keys.LastOrDefault() - equity.Keys.FirstOrDefault()).TotalDays / 365; CompoundingAnnualReturn = CompoundingAnnualPerformance(startingCapital, equity.Values.LastOrDefault(), fractionOfYears); Drawdown = DrawdownPercent(equity, 3); AnnualVariance = GetAnnualVariance(listPerformance, tradingDaysPerYear); AnnualStandardDeviation = (decimal)Math.Sqrt((double)AnnualVariance); var annualPerformance = GetAnnualPerformance(listPerformance, tradingDaysPerYear); SharpeRatio = AnnualStandardDeviation == 0 ? 0 : (annualPerformance - RiskFreeRate) / AnnualStandardDeviation; var benchmarkVariance = listBenchmark.Variance(); Beta = benchmarkVariance.IsNaNOrZero() ? 0 : (decimal)(listPerformance.Covariance(listBenchmark) / benchmarkVariance); Alpha = Beta == 0 ? 0 : annualPerformance - (RiskFreeRate + Beta * (GetAnnualPerformance(listBenchmark, tradingDaysPerYear) - RiskFreeRate)); var correlation = Correlation.Pearson(listPerformance, listBenchmark); var benchmarkAnnualVariance = benchmarkVariance * tradingDaysPerYear; TrackingError = correlation.IsNaNOrZero() || benchmarkAnnualVariance.IsNaNOrZero() ? 0 : (decimal)Math.Sqrt((double)AnnualVariance - 2 * correlation * (double)AnnualStandardDeviation * Math.Sqrt(benchmarkAnnualVariance) + benchmarkAnnualVariance); InformationRatio = TrackingError == 0 ? 0 : (annualPerformance - GetAnnualPerformance(listBenchmark, tradingDaysPerYear)) / TrackingError; TreynorRatio = Beta == 0 ? 0 : (annualPerformance - RiskFreeRate) / Beta; }
/// <summary> /// Algorithm "beta" statistic - the covariance between the algorithm and benchmark performance, divided by benchmark's variance /// </summary> /// <param name="algoPerformance">Collection of double values for algorithm daily performance.</param> /// <param name="benchmarkPerformance">Collection of double benchmark daily performance values.</param> /// <remarks>Invokes the variance and covariance extensions in the MathNet Statistics class</remarks> /// <returns>Value for beta</returns> public static double Beta(List<double> algoPerformance, List<double> benchmarkPerformance) { return algoPerformance.Covariance(benchmarkPerformance) / benchmarkPerformance.Variance(); }
////add Expectunity /// <summary> /// Initializes a new instance of the <see cref="PortfolioStatistics"/> class /// </summary> /// <param name="profitLoss">Trade record of profits and losses</param> /// <param name="equity">The list of daily equity values</param> /// <param name="listPerformance">The list of algorithm performance values</param> /// <param name="listBenchmark">The list of benchmark values</param> /// <param name="startingCapital">The algorithm starting capital</param> /// <param name="tradingDaysPerYear">The number of trading days per year</param> public PortfolioStatistics( SortedDictionary <DateTime, decimal> profitLoss, SortedDictionary <DateTime, decimal> equity, List <double> listPerformance, List <double> listBenchmark, decimal startingCapital, int tradingDaysPerYear = 252) { if (startingCapital == 0 // minimum amount of samples to calculate variance || listBenchmark.Count < 2 || listPerformance.Count < 2) { return; } var runningCapital = startingCapital; var totalProfit = 0m; var totalLoss = 0m; var totalWins = 0; var totalLosses = 0; var trades = 0; var averageTradeProfitLoss = 0m; var sumForVariance = 0m; var profitLossStandardDeviation = 0m; foreach (var pair in profitLoss) { var tradeProfitLoss = pair.Value; if (tradeProfitLoss > 0) { totalProfit += tradeProfitLoss / runningCapital; totalWins++; } else { totalLoss += tradeProfitLoss / runningCapital; totalLosses++; } runningCapital += tradeProfitLoss; trades = totalWins + totalLosses; var prevAverageTradeProfitLoss = averageTradeProfitLoss; averageTradeProfitLoss += (tradeProfitLoss - averageTradeProfitLoss) / trades; sumForVariance += (tradeProfitLoss - prevAverageTradeProfitLoss) * (tradeProfitLoss - averageTradeProfitLoss); var variance = trades > 1 ? sumForVariance / (trades - 1) : 0; profitLossStandardDeviation = (decimal)Math.Sqrt((double)variance); } AverageWinRate = totalWins == 0 ? 0 : totalProfit / totalWins; AverageLossRate = totalLosses == 0 ? 0 : totalLoss / totalLosses; ProfitLossRatio = AverageLossRate == 0 ? 0 : AverageWinRate / Math.Abs(AverageLossRate); WinRate = profitLoss.Count == 0 ? 0 : (decimal)totalWins / profitLoss.Count; LossRate = profitLoss.Count == 0 ? 0 : (decimal)totalLosses / profitLoss.Count; Expectancy = WinRate * ProfitLossRatio - LossRate; SignalToNoise = profitLossStandardDeviation == 0 ? 0 : Expectancy / profitLossStandardDeviation; SQNEstimateRaw = SignalToNoise == 0 ? 0 : SignalToNoise * (decimal)Math.Sqrt((double)trades); SQNEstimate100 = SignalToNoise == 0 ? 0 : SignalToNoise * 10; if (startingCapital != 0) { TotalNetProfit = equity.Values.LastOrDefault() / startingCapital - 1; } var fractionOfYears = (decimal)(equity.Keys.LastOrDefault() - equity.Keys.FirstOrDefault()).TotalDays / 365; CompoundingAnnualReturn = Statistics.CompoundingAnnualPerformance(startingCapital, equity.Values.LastOrDefault(), fractionOfYears); Drawdown = DrawdownPercent(equity, 3); AnnualVariance = GetAnnualVariance(listPerformance, tradingDaysPerYear); AnnualStandardDeviation = (decimal)Math.Sqrt((double)AnnualVariance); var benchmarkAnnualPerformance = GetAnnualPerformance(listBenchmark, tradingDaysPerYear); var annualPerformance = GetAnnualPerformance(listPerformance, tradingDaysPerYear); SharpeRatio = AnnualStandardDeviation == 0 ? 0 : (annualPerformance - RiskFreeRate) / AnnualStandardDeviation; var benchmarkVariance = listBenchmark.Variance(); Beta = benchmarkVariance.IsNaNOrZero() ? 0 : (decimal)(listPerformance.Covariance(listBenchmark) / benchmarkVariance); Alpha = Beta == 0 ? 0 : annualPerformance - (RiskFreeRate + Beta * (benchmarkAnnualPerformance - RiskFreeRate)); var correlation = Correlation.Pearson(listPerformance, listBenchmark); var benchmarkAnnualVariance = benchmarkVariance * tradingDaysPerYear; TrackingError = correlation.IsNaNOrZero() || benchmarkAnnualVariance.IsNaNOrZero() ? 0 : (decimal)Math.Sqrt((double)AnnualVariance - 2 * correlation * (double)AnnualStandardDeviation * Math.Sqrt(benchmarkAnnualVariance) + benchmarkAnnualVariance); InformationRatio = TrackingError == 0 ? 0 : (annualPerformance - benchmarkAnnualPerformance) / TrackingError; TreynorRatio = Beta == 0 ? 0 : (annualPerformance - RiskFreeRate) / Beta; // deannualize a 1 sharpe ratio var benchmarkSharpeRatio = 1.0d / Math.Sqrt(252); ProbabilisticSharpeRatio = Statistics.ProbabilisticSharpeRatio(listPerformance, benchmarkSharpeRatio).SafeDecimalCast(); }
/// <summary> /// Initializes a new instance of the <see cref="PortfolioStatistics"/> class /// </summary> /// <param name="profitLoss">Trade record of profits and losses</param> /// <param name="equity">The list of daily equity values</param> /// <param name="listPerformance">The list of algorithm performance values</param> /// <param name="listBenchmark">The list of benchmark values</param> /// <param name="startingCapital">The algorithm starting capital</param> /// <param name="tradingDaysPerYear">The number of trading days per year</param> public PortfolioStatistics( SortedDictionary<DateTime, decimal> profitLoss, SortedDictionary<DateTime, decimal> equity, List<double> listPerformance, List<double> listBenchmark, decimal startingCapital, int tradingDaysPerYear = 252) { if (startingCapital == 0) return; var runningCapital = startingCapital; var totalProfit = 0m; var totalLoss = 0m; var totalWins = 0; var totalLosses = 0; foreach (var pair in profitLoss) { var tradeProfitLoss = pair.Value; if (tradeProfitLoss > 0) { totalProfit += tradeProfitLoss / runningCapital; totalWins++; } else { totalLoss += tradeProfitLoss / runningCapital; totalLosses++; } runningCapital += tradeProfitLoss; } AverageWinRate = totalWins == 0 ? 0 : totalProfit / totalWins; AverageLossRate = totalLosses == 0 ? 0 : totalLoss / totalLosses; ProfitLossRatio = AverageLossRate == 0 ? 0 : AverageWinRate / Math.Abs(AverageLossRate); WinRate = profitLoss.Count == 0 ? 0 : (decimal)totalWins / profitLoss.Count; LossRate = profitLoss.Count == 0 ? 0 : (decimal)totalLosses / profitLoss.Count; Expectancy = WinRate * ProfitLossRatio - LossRate; if (profitLoss.Count > 0) { TotalNetProfit = (equity.Values.LastOrDefault() / startingCapital) - 1; } var fractionOfYears = (decimal)(equity.Keys.LastOrDefault() - equity.Keys.FirstOrDefault()).TotalDays / 365; CompoundingAnnualReturn = CompoundingAnnualPerformance(startingCapital, equity.Values.LastOrDefault(), fractionOfYears); Drawdown = DrawdownPercent(equity, 3); AnnualVariance = GetAnnualVariance(listPerformance, tradingDaysPerYear); AnnualStandardDeviation = (decimal)Math.Sqrt((double)AnnualVariance); var annualPerformance = GetAnnualPerformance(listPerformance, tradingDaysPerYear); SharpeRatio = AnnualStandardDeviation == 0 ? 0 : (annualPerformance - RiskFreeRate) / AnnualStandardDeviation; var benchmarkVariance = listBenchmark.Variance(); Beta = benchmarkVariance.IsNaNOrZero() ? 0 : (decimal)(listPerformance.Covariance(listBenchmark) / benchmarkVariance); Alpha = Beta == 0 ? 0 : annualPerformance - (RiskFreeRate + Beta * (GetAnnualPerformance(listBenchmark, tradingDaysPerYear) - RiskFreeRate)); var correlation = Correlation.Pearson(listPerformance, listBenchmark); var benchmarkAnnualVariance = benchmarkVariance * tradingDaysPerYear; TrackingError = correlation.IsNaNOrZero() || benchmarkAnnualVariance.IsNaNOrZero() ? 0 : (decimal)Math.Sqrt((double)AnnualVariance - 2 * correlation * (double)AnnualStandardDeviation * Math.Sqrt(benchmarkAnnualVariance) + benchmarkAnnualVariance); InformationRatio = TrackingError == 0 ? 0 : (annualPerformance - GetAnnualPerformance(listBenchmark, tradingDaysPerYear)) / TrackingError; TreynorRatio = Beta == 0 ? 0 : (annualPerformance - RiskFreeRate) / Beta; }
public EstimationResult EstimateAlgorithm(ISearchAlgorithm algorithm, object parameters = null) { if (algorithm == null) { throw new ArgumentNullException("algorithm"); } Dictionary <SHA1Hash, Dictionary <SHA1Hash, int> > AutoScores = new Dictionary <SHA1Hash, Dictionary <SHA1Hash, int> >(); List <Audio> Audios = Core.GetAudios().ToList(); List <Audio> ReferenceList = Audios.ToList(); foreach (Audio ReferenceAudio in ReferenceList) { IList <Audio> Series = Audios.Search(ReferenceAudio, algorithm, parameters) .Where(audio => HashMap.Contains(audio.GetHash())) .ToList(); SHA1Hash ReferenceHash = ReferenceAudio.GetHash(); AutoScores.Add(ReferenceHash, new Dictionary <SHA1Hash, int>()); int Rank = 0; foreach (Audio TargetAudio in Series) { AutoScores[ReferenceHash].Add(TargetAudio.GetHash(), TransformRankToScore(Rank++, Series.Count)); } } List <double> Errors = new List <double>(); List <double> ManualScoresList = new List <double>(); List <double> ReducedAutoScoresList = new List <double>(); foreach (SHA1Hash Reference in ManualScores.Keys) { foreach (SHA1Hash Target in ManualScores[Reference].Keys) { if (AutoScores.ContainsKey(Reference) && AutoScores[Reference].ContainsKey(Target)) { int ReferenceScore = ManualScores[Reference][Target]; int AutoScore = AutoScores[Reference][Target]; int Error = ReferenceScore - AutoScore; Errors.Add(Error); ManualScoresList.Add(ReferenceScore); ReducedAutoScoresList.Add(AutoScore); } } } double Mean = Errors.Mean(); double StandardDeviation = Errors.StandardDeviation(); double Covariance = ManualScoresList.Covariance(ReducedAutoScoresList); double PearsonCoeff = Correlation.Pearson(ManualScoresList, ReducedAutoScoresList); EstimationResult Result = new EstimationResult() { AlgorithmName = algorithm.DisplayName, Parameters = Convert.ToString(parameters), Mean = Mean, StandardDeviation = StandardDeviation, Covariance = Covariance, PearsonCoeff = PearsonCoeff, Scores = AutoScores }; return(Result); }