/// <summary> /// Set the Algorithm instance for ths result. /// </summary> /// <param name="algorithm">Algorithm we're working on.</param> /// <param name="startingPortfolioValue">Algorithm starting capital for statistics calculations</param> /// <remarks>While setting the algorithm the backtest result handler.</remarks> public virtual void SetAlgorithm(IAlgorithm algorithm, decimal startingPortfolioValue) { Algorithm = algorithm; StartingPortfolioValue = startingPortfolioValue; PreviousUtcSampleTime = Algorithm.UtcTime; DailyPortfolioValue = StartingPortfolioValue; CumulativeMaxPortfolioValue = StartingPortfolioValue; AlgorithmCurrencySymbol = Currencies.GetCurrencySymbol(Algorithm.AccountCurrency); _capacityEstimate = new CapacityEstimate(Algorithm); //Get the resample period: var totalMinutes = (algorithm.EndDate - algorithm.StartDate).TotalMinutes; var resampleMinutes = totalMinutes < MinimumSamplePeriod * Samples ? MinimumSamplePeriod : totalMinutes / Samples; // Space out the sampling every ResamplePeriod = TimeSpan.FromMinutes(resampleMinutes); Log.Trace("BacktestingResultHandler(): Sample Period Set: " + resampleMinutes.ToStringInvariant("00.00")); //Setup the sampling periods: _jobDays = Algorithm.Securities.Count > 0 ? Time.TradeableDates(Algorithm.Securities.Values, algorithm.StartDate, algorithm.EndDate) : Convert.ToInt32((algorithm.EndDate.Date - algorithm.StartDate.Date).TotalDays) + 1; //Set the security / market types. var types = new List <SecurityType>(); foreach (var kvp in Algorithm.Securities) { var security = kvp.Value; if (!types.Contains(security.Type)) { types.Add(security.Type); } } SecurityType(types); ConfigureConsoleTextWriter(algorithm); }
/// <summary> /// Gets the algorithm runtime statistics /// </summary> protected Dictionary <string, string> GetAlgorithmRuntimeStatistics(Dictionary <string, string> summary, Dictionary <string, string> runtimeStatistics = null, CapacityEstimate capacityEstimate = null) { if (runtimeStatistics == null) { runtimeStatistics = new Dictionary <string, string>(); } if (summary.ContainsKey("Probabilistic Sharpe Ratio")) { runtimeStatistics["Probabilistic Sharpe Ratio"] = summary["Probabilistic Sharpe Ratio"]; } else { runtimeStatistics["Probabilistic Sharpe Ratio"] = "0%"; } var accountCurrencySymbol = Currencies.GetCurrencySymbol(Algorithm.AccountCurrency); runtimeStatistics["Unrealized"] = accountCurrencySymbol + Algorithm.Portfolio.TotalUnrealizedProfit.ToStringInvariant("N2"); runtimeStatistics["Fees"] = $"-{accountCurrencySymbol}{Algorithm.Portfolio.TotalFees.ToStringInvariant("N2")}"; runtimeStatistics["Net Profit"] = accountCurrencySymbol + Algorithm.Portfolio.TotalProfit.ToStringInvariant("N2"); runtimeStatistics["Return"] = GetNetReturn().ToStringInvariant("P"); runtimeStatistics["Equity"] = accountCurrencySymbol + Algorithm.Portfolio.TotalPortfolioValue.ToStringInvariant("N2"); runtimeStatistics["Holdings"] = accountCurrencySymbol + Algorithm.Portfolio.TotalHoldingsValue.ToStringInvariant("N2"); runtimeStatistics["Volume"] = accountCurrencySymbol + Algorithm.Portfolio.TotalSaleVolume.ToStringInvariant("N2"); if (capacityEstimate != null) { runtimeStatistics["Capacity"] = accountCurrencySymbol + capacityEstimate.Capacity.RoundToSignificantDigits(2).ToFinancialFigures(); } return(runtimeStatistics); }
/// <summary> /// Will generate the statistics results and update the provided runtime statistics /// </summary> protected StatisticsResults GenerateStatisticsResults(Dictionary <string, Chart> charts, SortedDictionary <DateTime, decimal> profitLoss = null, CapacityEstimate estimatedStrategyCapacity = null) { var statisticsResults = new StatisticsResults(); if (profitLoss == null) { profitLoss = new SortedDictionary <DateTime, decimal>(); } try { //Generates error when things don't exist (no charting logged, runtime errors in main algo execution) const string strategyEquityKey = "Strategy Equity"; const string equityKey = "Equity"; const string dailyPerformanceKey = "Daily Performance"; const string benchmarkKey = "Benchmark"; // make sure we've taken samples for these series before just blindly requesting them if (charts.ContainsKey(strategyEquityKey) && charts[strategyEquityKey].Series.ContainsKey(equityKey) && charts[strategyEquityKey].Series.ContainsKey(dailyPerformanceKey) && charts.ContainsKey(benchmarkKey) && charts[benchmarkKey].Series.ContainsKey(benchmarkKey)) { var equity = charts[strategyEquityKey].Series[equityKey].Values; var performance = charts[strategyEquityKey].Series[dailyPerformanceKey].Values; var totalTransactions = Algorithm.Transactions.GetOrders(x => x.Status.IsFill()).Count(); var benchmark = charts[benchmarkKey].Series[benchmarkKey].Values; var trades = Algorithm.TradeBuilder.ClosedTrades; statisticsResults = StatisticsBuilder.Generate(trades, profitLoss, equity, performance, benchmark, StartingPortfolioValue, Algorithm.Portfolio.TotalFees, totalTransactions, estimatedStrategyCapacity); } } catch (Exception err) { Log.Error(err, "BaseResultsHandler.GenerateStatisticsResults(): Error generating statistics packet"); } return(statisticsResults); }
/// <summary> /// Gets the algorithm runtime statistics /// </summary> protected SortedDictionary <string, string> GetAlgorithmRuntimeStatistics(Dictionary <string, string> summary, CapacityEstimate capacityEstimate = null) { var runtimeStatistics = new SortedDictionary <string, string>(); lock (RuntimeStatistics) { foreach (var pair in RuntimeStatistics) { runtimeStatistics.Add(pair.Key, pair.Value); } } if (summary.ContainsKey("Probabilistic Sharpe Ratio")) { runtimeStatistics["Probabilistic Sharpe Ratio"] = summary["Probabilistic Sharpe Ratio"]; } else { runtimeStatistics["Probabilistic Sharpe Ratio"] = "0%"; } runtimeStatistics["Unrealized"] = AlgorithmCurrencySymbol + Algorithm.Portfolio.TotalUnrealizedProfit.ToStringInvariant("N2"); runtimeStatistics["Fees"] = $"-{AlgorithmCurrencySymbol}{Algorithm.Portfolio.TotalFees.ToStringInvariant("N2")}"; runtimeStatistics["Net Profit"] = AlgorithmCurrencySymbol + Algorithm.Portfolio.TotalProfit.ToStringInvariant("N2"); runtimeStatistics["Return"] = GetNetReturn().ToStringInvariant("P"); runtimeStatistics["Equity"] = AlgorithmCurrencySymbol + Algorithm.Portfolio.TotalPortfolioValue.ToStringInvariant("N2"); runtimeStatistics["Holdings"] = AlgorithmCurrencySymbol + Algorithm.Portfolio.TotalHoldingsValue.ToStringInvariant("N2"); runtimeStatistics["Volume"] = AlgorithmCurrencySymbol + Algorithm.Portfolio.TotalSaleVolume.ToStringInvariant("N2"); if (capacityEstimate != null) { runtimeStatistics["Capacity"] = AlgorithmCurrencySymbol + capacityEstimate.Capacity.RoundToSignificantDigits(2).ToFinancialFigures(); } return(runtimeStatistics); }