private static PaymentSchedule RoundPayments(PaymentSchedule paymentSchedule, int digitsAfterZero) { var resultPaymentSchedule = new PaymentSchedule(); var deltaMainDebt = 0M; var deltaInterest = 0M; var deltaOverdueMainDebt = 0M; var deltaOverdueInterest = 0M; if (paymentSchedule.Payments.Any()) { var lastPmt = paymentSchedule.Payments.Last(); foreach (var payment in paymentSchedule.Payments) { if (payment == null) { continue; } var newMainDebt = 0M; var newInterest = 0M; var newOverdueMainDebt = 0M; var newOverdueInterest = 0M; if (payment != lastPmt) { newMainDebt = Math.Round(payment.MainDebtAmount, digitsAfterZero); newInterest = Math.Round(payment.AccruedInterestAmount, digitsAfterZero); newOverdueMainDebt = Math.Round(payment.OverdueMainDebtAmount, digitsAfterZero); newOverdueInterest = Math.Round(payment.OverdueInterestAmount, digitsAfterZero); deltaMainDebt += payment.MainDebtAmount - newMainDebt; deltaInterest += payment.AccruedInterestAmount - newInterest; deltaOverdueMainDebt += payment.OverdueMainDebtAmount - newOverdueMainDebt; deltaOverdueInterest += payment.OverdueInterestAmount - newOverdueInterest; } else { newMainDebt = Math.Round(payment.MainDebtAmount + deltaMainDebt, digitsAfterZero); newInterest = Math.Round(payment.AccruedInterestAmount + deltaInterest, digitsAfterZero); newOverdueMainDebt = Math.Round(payment.OverdueMainDebtAmount + deltaOverdueMainDebt, digitsAfterZero); newOverdueInterest = Math.Round(payment.OverdueInterestAmount + deltaOverdueInterest, digitsAfterZero); } resultPaymentSchedule.AddPayment(new Payment { MainDebtAmount = newMainDebt, AccruedInterestAmount = newInterest, OverdueMainDebtAmount = newOverdueMainDebt, OverdueInterestAmount = newOverdueInterest, AccruedOn = payment.AccruedOn, ShouldBePaidBefore = payment.ShouldBePaidBefore, }); } } return(resultPaymentSchedule); }
public static PaymentSchedule CalculateAnnuitySchedule(Tariff tariff, decimal loanAmount, int term, DateTime?startDate) { var rate = tariff.InterestRate * tariff.PmtFrequency / 12; var helpCoeff = PowDecimal(1 + rate, term); var annuityCoeff = (rate * helpCoeff) / (helpCoeff - 1); var monthlyPayment = loanAmount * annuityCoeff; var schedule = new PaymentSchedule(); var remainMainDebt = loanAmount; for (var i = 0; i < term; i++) { var pmtInterest = remainMainDebt * rate; var pmtMainDebt = monthlyPayment - pmtInterest; var accruedDate = CalculateAccrualDate(startDate, i + 1); var payBefore = CalculatePaymentDate(startDate, i + 1); if (startDate.HasValue && payBefore > startDate.Value.AddMonths(term)) { payBefore = startDate.Value.AddMonths(term); } if (i == 0 && startDate.HasValue) { pmtInterest *= ((30 - startDate.Value.Day + 1) / 30M); } if (i + 1 == term && startDate.HasValue) { pmtInterest += pmtInterest * ((startDate.Value.Day - 1) / 30M); } var pmt = new Payment { MainDebtAmount = pmtMainDebt, AccruedInterestAmount = pmtInterest, AccruedOn = accruedDate, ShouldBePaidBefore = payBefore }; schedule.AddPayment(pmt); remainMainDebt -= pmtMainDebt; } return(RoundPayments(schedule, 2)); }
private static PaymentSchedule CalculateStandardSchedule(Tariff tariff, decimal loanAmount, int term, DateTime?startDate) { var rate = tariff.InterestRate * tariff.PmtFrequency / 12; var pmtMainDebt = loanAmount / term; var schedule = new PaymentSchedule(); var remainMainDebt = loanAmount; for (var i = 0; i < term; i++) { var pmtInterest = remainMainDebt * rate; var payBefore = CalculatePaymentDate(startDate, i + 1); if (i == 0 && startDate.HasValue) { pmtInterest *= ((30 - startDate.Value.Day + 1) / 30M); } if (i + 1 == term && startDate.HasValue) { pmtInterest += pmtInterest * ((startDate.Value.Day - 1) / 30M); } if (startDate.HasValue && payBefore > startDate.Value.AddMonths(term)) { payBefore = startDate.Value.AddMonths(term); } var pmt = new Payment { MainDebtAmount = pmtMainDebt, AccruedInterestAmount = pmtInterest, AccruedOn = CalculateAccrualDate(startDate, i), ShouldBePaidBefore = payBefore }; schedule.AddPayment(pmt); remainMainDebt -= pmtMainDebt; } return(RoundPayments(schedule, 2)); }