private EquityCurve EcFromEquitySummaries(Dictionary <DateTime, decimal> summaries, Dictionary <DateTime, decimal> depositsWithdrawals) { if (summaries.Count == 0) { return(new EquityCurve(100, summaries.First().Key)); } var ec = new EquityCurve(100, summaries.First().Key); decimal lastTotal = summaries.First().Value; bool first = true; foreach (var kvp in summaries) { if (first) { first = false; continue; } DateTime date = kvp.Key; decimal total = kvp.Value; decimal externalCashFlow = depositsWithdrawals.ContainsKey(date) ? depositsWithdrawals[date] : 0; if (lastTotal != 0) //make sure we avoid division by zero...equity can't change if we have 0 to start with anyway { double ret = (double)(((total - externalCashFlow) - lastTotal) / lastTotal); ec.AddReturn(ret, date); } lastTotal = total; } ec.CalcFinalValues(summaries.Last().Key); return(ec); }
private EquityCurve EcFromEquitySummaries(List <EquitySummary> summaries, Dictionary <DateTime, decimal> depositsWithdrawals) { if (summaries.Count == 0) { return(new EquityCurve()); } var ec = new EquityCurve(); decimal lastTotal = summaries[0].Total; for (int i = 1; i < summaries.Count; i++) { var es = summaries[i]; decimal externalCashFlow = depositsWithdrawals.ContainsKey(es.Date) ? depositsWithdrawals[es.Date] : 0; if (lastTotal != 0) //make sure we avoid division by zero...equity can't change if we have 0 to start with anyway { double ret = (double)(((es.Total - externalCashFlow) - lastTotal) / lastTotal); ec.AddReturn(ret, es.Date); } lastTotal = es.Total; } ec.CalcFinalValues(summaries.Last().Date); return(ec); }
/// <summary> /// Returns false is parsing failed. /// </summary> /// <returns></returns> public bool Import() { var dates = new List <DateTime>(); var equityValues = new List <double>(); int count = 0; foreach (var kvp in RawSplitData) { DateTime date; if (!DateTime.TryParseExact(kvp.Key, DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) { _dialogService.ShowMessageAsync("Parsing error.", string.Format("Failed to date value at line {0}: {1}", count, kvp.Key)); return(false); } dates.Add(date); double equity; if (!double.TryParse(kvp.Value, out equity)) { _dialogService.ShowMessageAsync("Parsing error.", string.Format("Failed to parse equity value at line {0}: {1}", count, kvp.Value)); return(false); } equityValues.Add(equity); count++; } //Make sure there's sufficient data if (dates.Count <= 1) { _dialogService.ShowMessageAsync("Parsing error.", "Parsed backtest data too short."); EquityCurve = null; return(false); } //Then generate an EquityCurve using the data EquityCurve = new EquityCurve(100, dates[0]); for (int i = 1; i < dates.Count; i++) { EquityCurve.AddReturn(equityValues[i] / equityValues[i - 1] - 1, dates[i]); } return(true); }
/// <summary> /// Returns false is parsing failed. /// </summary> /// <returns></returns> public bool Import() { var dates = new List<DateTime>(); var equityValues = new List<double>(); int count = 0; foreach(var kvp in RawSplitData) { DateTime date; if(!DateTime.TryParseExact(kvp.Key, DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) { _dialogService.ShowMessageAsync(this, "Parsing error.", string.Format("Failed to date value at line {0}: {1}", count, kvp.Key)); return false; } dates.Add(date); double equity; if(!double.TryParse(kvp.Value, out equity)) { _dialogService.ShowMessageAsync(this, "Parsing error.", string.Format("Failed to parse equity value at line {0}: {1}", count, kvp.Value)); return false; } equityValues.Add(equity); count++; } //Make sure there's sufficient data if (dates.Count <= 1) { _dialogService.ShowMessageAsync(this, "Parsing error.", "Parsed backtest data too short."); EquityCurve = null; return false; } //Then generate an EquityCurve using the data EquityCurve = new EquityCurve(100, dates[0]); for (int i = 1; i < dates.Count; i++) { EquityCurve.AddReturn(equityValues[i] / equityValues[i - 1] - 1, dates[i]); } return true; }
/// <summary> /// generate EC and other curves for a benchmark /// </summary> public static EquityCurve GetBenchmarkReturns( int benchmarkID, DBContext context, List<DateTime> datesInPeriod, IDataSourcer dataSourcer, out Dictionary<DateTime, double> benchmarkSeries, out List<double> benchmarkReturns) { Logger logger = LogManager.GetCurrentClassLogger(); List<BenchmarkComponent> components = context.BenchmarkComponents.Where(x => x.BenchmarkID == benchmarkID).ToList(); DateTime earliestDate = datesInPeriod[0].Date; DateTime latestDate = datesInPeriod.Last(); Dictionary<int, TimeSeries> data = components .ToDictionary( component => component.QDMSInstrumentID, component => new TimeSeries( dataSourcer.GetExternalData(component.QDMSInstrumentID, earliestDate, latestDate))); Dictionary<int, decimal> weights = components.ToDictionary(x => x.QDMSInstrumentID, x => (decimal)x.Weight); benchmarkSeries = new Dictionary<DateTime, double>(); benchmarkReturns = new List<double>(); var benchmarkEC = new EquityCurve(1, null); decimal equity = 1; bool first = true; foreach (DateTime today in datesInPeriod) { decimal ret = 0; foreach (var kvp in data) { var ts = kvp.Value; ts.ProgressTo(today); if (ts.CurrentBar > 0) { decimal todayClose = ts[0].AdjClose.HasValue ? ts[0].AdjClose.Value : ts[0].Close; decimal lastClose = ts[1].AdjClose.HasValue ? ts[1].AdjClose.Value : ts[1].Close; ret += weights[kvp.Key] * (todayClose / lastClose - 1); #if DEBUG logger.Log(LogLevel.Trace, "Benchmark component: Date: {0} Close: {1} PrevClose: {2} Ret: {3}", today, todayClose, lastClose, ret); #endif } } benchmarkEC.AddReturn((double)ret, today); if (first) { first = false; benchmarkReturns.Add((double)(1 + ret)); benchmarkSeries.Add(today, (double)equity); continue; } equity *= 1 + ret; benchmarkReturns.Add((double)(1 + ret)); benchmarkSeries.Add(today, (double)equity); } return benchmarkEC; }
/// <summary> /// generate EC and other curves for a benchmark /// </summary> public static EquityCurve GetBenchmarkReturns( int benchmarkID, DBContext context, List <DateTime> datesInPeriod, IDataSourcer dataSourcer, out Dictionary <DateTime, double> benchmarkSeries, out List <double> benchmarkReturns) { Logger logger = LogManager.GetCurrentClassLogger(); List <BenchmarkComponent> components = context.BenchmarkComponents.Where(x => x.BenchmarkID == benchmarkID).ToList(); DateTime earliestDate = datesInPeriod[0].Date; DateTime latestDate = datesInPeriod.Last(); Dictionary <int, TimeSeries> data = components .ToDictionary( component => component.QDMSInstrumentID, component => new TimeSeries( dataSourcer.GetExternalData(component.QDMSInstrumentID, earliestDate, latestDate))); Dictionary <int, decimal> weights = components.ToDictionary(x => x.QDMSInstrumentID, x => (decimal)x.Weight); benchmarkSeries = new Dictionary <DateTime, double>(); benchmarkReturns = new List <double>(); var benchmarkEC = new EquityCurve(1); decimal equity = 1; bool first = true; foreach (DateTime today in datesInPeriod) { decimal ret = 0; foreach (var kvp in data) { var ts = kvp.Value; ts.ProgressTo(today); if (ts.CurrentBar > 0) { decimal todayClose = ts[0].AdjClose.HasValue ? ts[0].AdjClose.Value : ts[0].Close; decimal lastClose = ts[1].AdjClose.HasValue ? ts[1].AdjClose.Value : ts[1].Close; ret += weights[kvp.Key] * (todayClose / lastClose - 1); #if DEBUG logger.Log(LogLevel.Trace, "Benchmark component: Date: {0} Close: {1} PrevClose: {2} Ret: {3}", today, todayClose, lastClose, ret); #endif } } benchmarkEC.AddReturn((double)ret, today); if (first) { first = false; benchmarkReturns.Add((double)(1 + ret)); benchmarkSeries.Add(today, (double)equity); continue; } equity *= 1 + ret; benchmarkReturns.Add((double)(1 + ret)); benchmarkSeries.Add(today, (double)equity); } return(benchmarkEC); }
private EquityCurve EcFromEquitySummaries(Dictionary<DateTime, decimal> summaries, Dictionary<DateTime, decimal> depositsWithdrawals) { if (summaries.Count == 0) return new EquityCurve(100, DateTime.Now); var ec = new EquityCurve(100, summaries.First().Key); decimal lastTotal = summaries.First().Value; bool first = true; foreach(var kvp in summaries) { if (first) { first = false; continue; } DateTime date = kvp.Key; decimal total = kvp.Value; decimal externalCashFlow = depositsWithdrawals.ContainsKey(date) ? depositsWithdrawals[date] : 0; if (lastTotal != 0) //make sure we avoid division by zero...equity can't change if we have 0 to start with anyway { double ret = (double)(((total - externalCashFlow) - lastTotal) / lastTotal); ec.AddReturn(ret, date); } lastTotal = total; } ec.CalcFinalValues(summaries.Last().Key); return ec; }