private RealEstateBuilder AddHomeWithFixedRateMortgage(DateTime purchasedAt, decimal purchasePriceAtInitiation, IInflation inflation) { var purchasePriceWhenPurchased = new Money(purchasePriceAtInitiation, InitiatedAt) .GetValueAt(new CompoundYearlyInflation(0.05M), purchasedAt); var availableCash = Result.GetCashAt(inflation, purchasedAt); var downPaymentAmount = availableCash < purchasePriceAtInitiation ? availableCash : purchasePriceAtInitiation; var mortgage = Mortgages.GetFixedRateMortgage( new Money(purchasePriceWhenPurchased.Value - downPaymentAmount, purchasedAt), 0.0319M, 300, purchasedAt, new Money(downPaymentAmount, purchasedAt) ); var home = new Home( "foobar", purchasedAt, new Money(purchasePriceWhenPurchased, purchasedAt), new Money(downPaymentAmount, purchasedAt), mortgage ); Result.Buy(home, purchasedAt); Result.Buy(mortgage, purchasedAt); return(this); }
public void SetUp() { var purchasePrice = 1000000.00M; var downPayment = 300000.00M; var interestRate = 0.03M; var mortgage = Mortgages.GetFixedRateMortgage(purchasePrice, interestRate, 300, PurchasedAt, downPayment); Subject = new Home("foobar", PurchasedAt, purchasePrice, 300.00M, mortgage, MonthlyMaintenanceFeesAtPurchasePrice); }
private MagicEstateBuilder AddHomeWithFixedRateMortgageAtDownPaymentPercentage(string name, decimal appreciationRate, decimal purchasePriceAtInitiation, decimal downPaymentRate, decimal interestRate = 0.0319M) { if (purchasePriceAtInitiation < 0.00M) { throw new ArgumentOutOfRangeException(nameof(purchasePriceAtInitiation), purchasePriceAtInitiation, "Should be at or greater than 0.00"); } if (downPaymentRate < 0.00M || downPaymentRate > 1.00M) { throw new ArgumentOutOfRangeException(nameof(downPaymentRate), downPaymentRate, "Should be between 0.00 and 1.00 (inclusive)"); } // Baseline for prices var initiatedAt = At; var homeInflation = Inflations.CondoPriceIndex; var purchasedAt = new CashFinder( Result, initiatedAt ).HasAvailableCashAt( downPaymentRate * purchasePriceAtInitiation, homeInflation ); var downPaymentAmount = new Money( downPaymentRate * purchasePriceAtInitiation, initiatedAt ).GetValueAt(homeInflation, purchasedAt); var mortgageAmount = new Money( (1 - downPaymentRate) * purchasePriceAtInitiation, initiatedAt ).GetValueAt(homeInflation, purchasedAt); var fullAmount = new Money( purchasePriceAtInitiation, initiatedAt ).GetValueAt(homeInflation, purchasedAt); var mortgage = Mortgages.GetFixedRateMortgage( mortgageAmount, 0.0319M, 300, purchasedAt, downPaymentAmount ); var home = new Home( name, purchasedAt, fullAmount, downPaymentAmount, mortgage ); Result.Buy(home, purchasedAt); At = purchasedAt.GetNext(); return(this); }
public void Test_GetsFixedRateMortgage(decimal downPayment) { var actual = Mortgages.GetFixedRateMortgage( MortgageValue, InterestRate, AmortisationPeriodInMonths, PurchasedAt, downPayment ); Assert.That(actual, Is.TypeOf <FixedRateMortgage>()); }
public void Calculator() { IsBusy = true; try { InterestRate = Math.Pow((1 + (double.Parse(CanadianMortgageRate) / 100) / CompoundPeriod), (double)CompoundPeriod / PeriodsPerYear) - 1; Payment = Math.Round(-Financial.Pmt(InterestRate, AmortizationPeriod * PeriodsPerYear, double.Parse(LoanAmount)), 2); var nPer = AmortizationPeriod * PeriodsPerYear; var additionalPaymentList = Mortgages?.Where(x => x.AdditionalPayment > 0).ToList(); if (Mortgages == null) { Mortgages = new ObservableCollection <Mortgage>(); } else { Mortgages.Clear(); } Mortgage previousMortgage = new Mortgage() { No = 0, Balance = double.Parse(LoanAmount) }; while (previousMortgage.Balance != 0) { var mortgage = new Mortgage(); if (previousMortgage.No >= nPer || Math.Round(previousMortgage.Balance, 2) <= 0) { mortgage.No = 0; } else { mortgage.No = previousMortgage.No + 1; } if (mortgage.No != 0) { // Due date if (PeriodsPerYear == 26) { if (mortgage.No == 1) { mortgage.DueDate = FirstPaymentDate; } else { mortgage.DueDate = mortgage.DueDate.AddDays(14); } } else if (PeriodsPerYear == 52) { if (mortgage.No == 1) { mortgage.DueDate = FirstPaymentDate; } else { mortgage.DueDate = mortgage.DueDate.AddDays(7); } } else { mortgage.DueDate = new DateTime(FirstPaymentDate.Year, FirstPaymentDate.Month, FirstPaymentDate.Day); mortgage.DueDate = mortgage.DueDate.AddMonths((int)((mortgage.No - 1) * MonthsPerPeriod)); if (PeriodsPerYear == 24) { if (1 - (mortgage.No % 2) == 1) { mortgage.DueDate = mortgage.DueDate.AddDays(14); } else { mortgage.DueDate = new DateTime(mortgage.DueDate.Year, mortgage.DueDate.Month, FirstPaymentDate.Day); } } else { mortgage.DueDate = new DateTime(mortgage.DueDate.Year, mortgage.DueDate.Month, FirstPaymentDate.Day); } } // Payment if (mortgage.No == nPer || Payment > Math.Round((1 + InterestRate) * previousMortgage.Balance, 2)) { mortgage.Payment = Math.Round((1 + InterestRate) * previousMortgage.Balance, 2); } else { mortgage.Payment = Payment; } // Extra Payment if (previousMortgage.Balance <= Payment || mortgage.No == 0) { mortgage.ExtraPayments = 0; } else { if (double.Parse(ExtraAnnualPayment) > 0) { if (mortgage.No % PeriodsPerYear == 0) { mortgage.ExtraPayments = double.Parse(ExtraAnnualPayment); } else { mortgage.ExtraPayments = 0; } } else { mortgage.ExtraPayments = 0; } if (PaymentInterval == 0) { mortgage.ExtraPayments += 0; } else { if (mortgage.No % PaymentInterval == 0) { mortgage.ExtraPayments += double.Parse(ExtraPayment); } else { mortgage.ExtraPayments += 0; } } } // Additional Payment mortgage.AdditionalPayment = additionalPaymentList?.FirstOrDefault(x => x.No == mortgage.No)?.AdditionalPayment ?? 0; // Interest mortgage.Interest = Math.Round(InterestRate * previousMortgage.Balance, 2); // Principal mortgage.Principal = mortgage.Payment - mortgage.Interest + mortgage.AdditionalPayment + mortgage.ExtraPayments; // Balance mortgage.Balance = previousMortgage.Balance - mortgage.Principal; Mortgages.Add(mortgage); previousMortgage = mortgage; } else { break; } } // Fully Amortized TotalPayments = Mortgages.Sum(x => x.Interest) + Mortgages.Sum(x => x.Principal); TotalInterest = Mortgages.Sum(x => x.Interest); NumberOfPayments = Mortgages.Max(x => x.No); LastPaymentDate = Mortgages.Max(x => x.DueDate); NumberOfPaymentsYears = Math.Round((decimal)(NumberOfPayments / PeriodsPerYear), 2); // Balance at Term DateAtTerm = Mortgages.FirstOrDefault(x => x.No == (Term * PeriodsPerYear)).DueDate; InterestPaid = Mortgages.Where(x => x.No <= (Term * PeriodsPerYear)).Sum(x => x.Interest); PrincipalPaid = Mortgages.Where(x => x.No <= (Term * PeriodsPerYear)).Sum(x => x.Principal); OutstandingBalance = Mortgages.FirstOrDefault(x => x.No == (Term * PeriodsPerYear)).Balance; // Totals Assuming No Extra Payments if (TotalInterestWithNoExtraPayment - TotalInterest < 0) { InterestSavings = 0; } else { InterestSavings = TotalInterestWithNoExtraPayment - TotalInterest; } TotalPaymentsWithNoExtraPayment = TotalInterest + InterestSavings + double.Parse(LoanAmount); TotalInterestWithNoExtraPayment = TotalPaymentsWithNoExtraPayment - double.Parse(LoanAmount); //await Task.Delay(200); } catch (Exception ex) { Debug.WriteLine(ex.Message); } IsBusy = false; }