public MoneyBalanceOverTime StartEvaluation(Action <int> setProgress, int startPercentage, int endPercentage) { if (_CachedData.ContainsKey(this)) { return(_CachedData[this]); } DateTime currentDate = StartDate; if (Method.StrategyEndDate > HistoricalData.DataEndDate) { EndDate = HistoricalData.DataEndDate; } DateTime nextInvestmentDate = DateTimeUtilities.GetNextInvestmentDate(currentDate, Method.InvestmentSchedule.InputInterval); MoneyDaily previousDailyMoney = new MoneyDaily(currentDate.AddDays(-1)) { CashOnHand = Method.InvestmentSchedule.InitialAmount }; while (currentDate < EndDate) { decimal cashInvested = 0; // Check for any incoming money from investing if (currentDate.IsSameDay(nextInvestmentDate)) { if (Method.InvestmentSchedule.AdjustInputForInflation) { var initialAmount = Method.InvestmentSchedule.SupplyAmount; var inflationAdjustedAmount = Method.InvestmentSchedule.GetInflationAdjustmentBetweenTwoDates(StartDate, initialAmount, currentDate); cashInvested = inflationAdjustedAmount; } else { cashInvested = Method.InvestmentSchedule.SupplyAmount; } nextInvestmentDate = DateTimeUtilities.GetNextInvestmentDate(currentDate, Method.InvestmentSchedule.InputInterval); } // Get action for the day var investmentAction = Method.GetActionForDay(currentDate, HistoricalData); MoneyDaily currentDailyMoney = new MoneyDaily(previousDailyMoney, HistoricalData.GetDataForDate(currentDate), cashInvested, investmentAction); DailyMoneyLogs.Add(currentDailyMoney); previousDailyMoney = currentDailyMoney; currentDate = currentDate.AddDays(1); if (setProgress != null) { var totalDays = (EndDate - StartDate).TotalDays; if (totalDays > 0) { var currentDaysProcessed = (currentDate - StartDate).TotalDays; int range = endPercentage - startPercentage; var percentage = range * (currentDaysProcessed / totalDays); percentage = startPercentage + percentage; setProgress((int)percentage); } } } if (setProgress != null) { setProgress(endPercentage); } var result = new MoneyBalanceOverTime(this.Method.InvestmentSchedule, this.Method, DailyMoneyLogs); _CachedData[this] = result; return(result); }