Example #1
0
 /// <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();
 }
Example #2
0
        /// <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;
        }