public RootVM() { InitMef(); CreateSeries(); Model = new PlotModel(); Model.Title = "Mortgage"; Model.Axes.Add(new LinearAxis { Position = AxisPosition.Left }); var dateAxis = new DateTimeAxis(); dateAxis.Position = AxisPosition.Bottom; dateAxis.Minimum = DateTimeAxis.ToDouble(MortgageConstants.GetDateFromMonthOfMortgage(0)); dateAxis.Maximum = DateTimeAxis.ToDouble(MortgageConstants.GetDateFromMonthOfMortgage(MortgageConstants.OriginalDurationInMonths)); Model.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom }); FinancialData = new FinancialData(Settings.Default.DataFile); GazelleVM = new GazelleVM(FinancialData); foreach (var seriesPair in _mefSeriesPlots) { Model.Series.Add(seriesPair.Value); } SavingsVM = new SavingsVM(FinancialData); }
public SavingsVM(FinancialData financialData) { _gazelleSeries = GazelleSeries.Instance; _financialData = financialData; Model = new PlotModel(); Model.Title = "Savings Over Time"; var valueAxis = new LinearAxis(); valueAxis.Position = AxisPosition.Left; valueAxis.Minimum = 0; Model.Axes.Add(valueAxis); var dateAxis = new DateTimeAxis(); dateAxis.Position = AxisPosition.Bottom; dateAxis.Minimum = DateTimeAxis.ToDouble(MortgageConstants.GetDateFromMonthOfMortgage(0)); dateAxis.Maximum = DateTimeAxis.ToDouble(MortgageConstants.GetDateFromMonthOfMortgage(MortgageConstants.OriginalDurationInMonths)); Model.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom }); InitSeries(); _financialData.DataChanged += OnFinancialDataChanged; RefreshSavingsSeries(); }
private static void PopulateSeriesData(LineSeries lineSeries, IMortgagePaydownSeries series) { var balance = series.StartValue; var startDate = series.StartDate; int m; for (m = 0; balance > 0; m++) { var date = MortgageConstants.GetDateFromMonthOfMortgage(m); if (date >= startDate) { lineSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(date), (double)balance)); balance = HandleMonth(balance, series.GetPayment(date, balance)); } } lineSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(MortgageConstants.GetDateFromMonthOfMortgage(m)), 0)); }
private void OnFinancialDataChanged(object sender, EventArgs e) { ExtraPayments.Clear(); var unallocatedBalances = new Dictionary <Account, Dictionary <DateTime, decimal> >(); var now = DateTime.Now; var currentMonth = new DateTime(now.Year, now.Month, 1); int currentMonthIndex = 0; var endMonth = MortgageConstants.GetDateFromMonthOfMortgage(MortgageConstants.OriginalDurationInMonths); int month = 0; // Get to this month for (; MortgageConstants.GetDateFromMonthOfMortgage(month) < currentMonth; month++) { ; } currentMonthIndex = ++month; var nextMonth = MortgageConstants.GetDateFromMonthOfMortgage(currentMonthIndex); foreach (var account in _financialData.Accounts) { var accountBalances = new Dictionary <DateTime, decimal>(); // For the rest of the term of the mortgage, get the current balance of the account for (month = currentMonthIndex; month < MortgageConstants.OriginalDurationInMonths; month++) { var date = MortgageConstants.GetDateFromMonthOfMortgage(month); accountBalances[date] = account.Value; // Account for each transaction we know about foreach (var transaction in _financialData.Transactions) { if (transaction.AccountName == account.Name && transaction.Payment.Date <= date) { if (string.IsNullOrEmpty(transaction.AllotmentName)) { accountBalances[date] += transaction.Payment.Amount; } } } } unallocatedBalances[account] = accountBalances; } // Merge all accounts together, then deal with allotments for account-agnostic stuff var mergedBalances = new Dictionary <DateTime, decimal>(); foreach (var account2 in unallocatedBalances.Keys) { for (month = currentMonthIndex; month < MortgageConstants.OriginalDurationInMonths; month++) { var date = MortgageConstants.GetDateFromMonthOfMortgage(month); if (mergedBalances.ContainsKey(date)) { mergedBalances[date] += unallocatedBalances[account2][date]; } else { mergedBalances[date] = unallocatedBalances[account2][date]; } } } foreach (var allotment in _financialData.Allotments) { for (month = currentMonthIndex; month < MortgageConstants.OriginalDurationInMonths; month++) { var date = MortgageConstants.GetDateFromMonthOfMortgage(month); if (allotment.Date <= date) { mergedBalances[date] -= allotment.Value; } } } var min = mergedBalances.Values.LastOrDefault(); // Walk backwards through the dates and keep the minimum balances foreach (var date in mergedBalances.Keys.Reverse()) { if (min > mergedBalances[date]) { min = mergedBalances[date]; } else { mergedBalances[date] = min; } } // Now walk forwards through the dates and make payments for every time the balance goes up var max = mergedBalances.Values.FirstOrDefault(); ExtraPayments.Add(new Payment(nextMonth, max)); foreach (var date in mergedBalances.Keys) { if (mergedBalances[date] > max) { ExtraPayments.Add(new Payment(date, mergedBalances[date] - max)); max = mergedBalances[date]; } } }