public void AmortizeThirtyPaymentLoanWithAdditionalPaymentsTest()
        {
            //Amortize a loan with a 30 payments plus additional payments which result in the principal being paid off in 21 payments
            //Test data computed by '30 Payment LoanWith Additional Payments.xlsx'
            List<Payment> expectedPayments = CreateLoanPayments(
                new[]
                    {
                        new[] {1m, 0.61m, 10.00m, 1.00m, 98.39m},
                        new[] {2m, 0.77m, 9.84m, 1.00m, 96.62m},
                        new[] {3m, 0.95m, 9.66m, 1.00m, 94.67m},
                        new[] {4m, 1.14m, 9.47m, 1.00m, 92.53m},
                        new[] {5m, 1.36m, 9.25m, 1.00m, 90.17m},
                        new[] {6m, 1.59m, 9.02m, 1.00m, 87.58m},
                        new[] {7m, 1.85m, 8.76m, 1.00m, 84.73m},
                        new[] {8m, 2.14m, 8.47m, 1.00m, 81.59m},
                        new[] {9m, 2.45m, 8.16m, 1.00m, 78.14m},
                        new[] {10m, 2.80m, 7.81m, 1.00m, 74.34m},
                        new[] {11m, 3.18m, 7.43m, 1.00m, 70.16m},
                        new[] {12m, 3.59m, 7.02m, 1.00m, 65.57m},
                        new[] {13m, 4.05m, 6.56m, 1.00m, 60.52m},
                        new[] {14m, 4.56m, 6.05m, 1.00m, 54.96m},
                        new[] {15m, 5.11m, 5.50m, 1.00m, 48.85m},
                        new[] {16m, 5.72m, 4.89m, 1.00m, 42.13m},
                        new[] {17m, 6.40m, 4.21m, 1.00m, 34.73m},
                        new[] {18m, 7.14m, 3.47m, 1.00m, 26.59m},
                        new[] {19m, 7.95m, 2.66m, 1.00m, 17.64m},
                        new[] {20m, 8.85m, 1.76m, 1.00m, 7.79m},
                        new[] {21m, 7.79m, 0.78m, 0m, 0.00m}
                    }
                );

            var loan = new AmortizedLoan
                           {
                               NumPayments = 30,
                               Principal = 100,
                               InterestRate = 0.10m,
                               AdditionalPayment = 1m
                           };

            List<Payment> payments = loan.Amortize(Currency.UsDollars);
            DumpPayments(payments);
            VerifyPayments(expectedPayments, payments, Currency.UsDollars, 0.01m);
        }
        public void AmortizeTwelvePaymentWithCompundingEveryOtherPaymentLoanTest()
        {
            //Amortize a loan with a 12 payments with compounding every other payment
            //Test data computed by '10 Payment Loan With Compounding Every Other Payment.xlsx'
            var loan = new AmortizedLoan
            {
                NumPayments = 12,
                Principal = 100,
                InterestRate = 0.10m,
                PaymentsPerCompounding = 2
            };

            List<Payment> payments = loan.Amortize(Currency.UsDollars);

            List<Payment> expectedPayments = CreateLoanPayments(
                new[]
                    {
                        new[] {1m, 7.96m, 0.83m, 0m, 92.04m},
                        new[] {2m, 8.03m, 0.76m, 0m, 84.01m},
                        new[] {3m, 8.09m, 0.7m, 0m, 75.92m},
                        new[] {4m, 8.16m, 0.63m, 0m, 67.76m},
                        new[] {5m, 8.23m, 0.56m, 0m, 59.53m},
                        new[] {6m, 8.3m, 0.49m, 0m, 51.23m},
                        new[] {7m, 8.36m, 0.43m, 0m, 42.87m},
                        new[] {8m, 8.43m, 0.36m, 0m, 34.44m},
                        new[] {9m, 8.5m, 0.29m, 0m, 25.94m},
                        new[] {10m, 8.57m, 0.22m, 0m, 17.37m},
                        new[] {11m, 8.65m, 0.14m, 0m, 8.72m},
                        new[] {12m, 8.72m, 0.07m, 0m, 04m},
                    }
                );

            DumpPayments(payments);
            VerifyPayments(expectedPayments, payments, Currency.UsDollars, 0.01m);
        }
        private static void AmortizeSimpleThirtyPaymentLoanTestInternal(Currency currency,
                                                                 List<Payment> expectedPayments,
                                                                 decimal acceptableError)
        {
            var loan = new AmortizedLoan
            {
                NumPayments = 30,
                Principal = 100,
                InterestRate = 0.10m
            };

            List<Payment> payments = loan.Amortize(currency);
            DumpPayments(payments);
            VerifyPayments(expectedPayments, payments, currency, acceptableError);
        }
        public void AmortizeSimpleThreePaymentWithHugeAdditionalPaymentLoanTest()
        {
            //Amortize a loan with a 3 payments and an additional payment so large the third
            //payment isn't necessary
            //Test data computed by '3 Payment Loan With huge Additional Payment.xlsx'
            var loan = new AmortizedLoan
            {
                NumPayments = 3,
                Principal = 100,
                InterestRate = 0.10m,
                AdditionalPayment = 50
            };

            List<Payment> payments = loan.Amortize(Currency.UsDollars);

            List<Payment> expectedPayments = CreateLoanPayments(
                new[]
                    {
                        new[] {1m, 30.21m, 10.0m, 50m, 19.79m},
                        new[] {2m, 19.79m, 1.98m, 0m, 0m}
                    }
                );

            DumpPayments(payments);
            VerifyPayments(expectedPayments, payments, Currency.UsDollars, 0.01m);
        }
        public void AmortizeTenPaymentWithIrregularAdditionalPaymentLoanTest()
        {
            //Amortize a loan with a 10 payments but sprinkle in some irregular additional
            //payments
            //Test data computed by '10 Payment Loan With Irregular Additional Payment.xlsx'
            var loan = new AmortizedLoan
            {
                NumPayments = 10,
                Principal = 100,
                InterestRate = 0.10m
            };

            var additionalPayments = new[]
                                         {
                                             new AdditionalPayment() { Ordinal = 3, Amount = 10},
                                             new AdditionalPayment() { Ordinal = 5, Amount = 1},
                                             new AdditionalPayment() { Ordinal = 6, Amount = 10}
                                         };

            List<Payment> payments = loan.Amortize(Currency.UsDollars, additionalPayments);

            List<Payment> expectedPayments = CreateLoanPayments(
                new[]
                    {
                        new[] {1m, 6.27m, 10.0m, 0m, 93.73m},
                        new[] {2m, 6.90m, 9.37m, 0m, 86.83m},
                        new[] {3m, 7.59m, 8.68m, 10m, 69.24m},
                        new[] {4m, 9.35m, 6.92m, 0m, 59.89m},
                        new[] {5m, 10.28m, 5.99m, 1m, 48.61m},
                        new[] {6m, 11.41m, 4.86m, 10m, 27.20m},
                        new[] {7m, 13.55m, 2.72m, 0m, 13.65m},
                        new[] {8m, 13.65m, 1.37m, 0m, 0m}
                    }
                );

            DumpPayments(payments);
            VerifyPayments(expectedPayments, payments, Currency.UsDollars, 0.01m);
        }
        public void AmortizeSimpleThreePaymentWithAdditionalPaymentLoanTest()
        {
            //Amortize a loan with a 3 payments
            //Test data computed by 'Simple 3 Payment Loan With Additional Payment.xlsx'
            var loan = new AmortizedLoan
            {
                NumPayments = 3,
                Principal = 100,
                InterestRate = 0.10m,
                AdditionalPayment = 5
            };

            List<Payment> payments = loan.Amortize(Currency.UsDollars);

            List<Payment> expectedPayments = CreateLoanPayments(
                new[]
                    {
                        new[] {1m, 30.21m, 10.0m, 5m, 64.79m},
                        new[] {2m, 33.73m, 6.48m, 5m, 26.06m},
                        new[] {3m, 26.06m, 2.61m, 0m, 0.0m},
                    }
                );

            DumpPayments(payments);
            VerifyPayments(expectedPayments, payments, Currency.UsDollars, 0.01m);
        }
        public void AmortizeSimpleThreePaymentLoanTest()
        {
            //Amortize a loan with a 3 payments
            //Test data computed by 'Simple 3 Payment Loan.xlsx'
            var loan = new AmortizedLoan
                           {
                               NumPayments = 3,
                               Principal = 100,
                               InterestRate = 0.10m
                           };

            List<Payment> payments = loan.Amortize(Currency.UsDollars);

            List<Payment> expectedPayments = CreateLoanPayments(
                new[]
                    {
                        new[] {1, 30.21m, 10.0m, 69.79m},
                        new[] {2, 33.23m, 6.98m, 36.56m},
                        new[] {3, 36.56m, 3.66m, 0.0m},
                    }
                );

            VerifyPayments(expectedPayments, payments, Currency.UsDollars, 0.01m);
        }
        public void AmortizeSinglePaymentWithAdditionalPaymentLoanTest()
        {
            //Amortize a loan with a single payment that includes an additional payment amount
            //Test data computed by 'Single Payment Loan.xlsx'
            var loan = new AmortizedLoan
            {
                NumPayments = 1,
                Principal = 100,
                InterestRate = 0.10m,
                AdditionalPayment = 20m
            };

            //Since there's only the one payment which covers the debt in full, the additional payment
            //is not applied
            List<Payment> payments = loan.Amortize(Currency.UsDollars);
            Assert.AreEqual(1, payments.Count);
            Assert.AreEqual(1, payments[0].Ordinal);
            Assert.AreEqual(100, payments[0].Principal);
            Assert.AreEqual(10, payments[0].Interest);
            Assert.AreEqual(0, payments[0].AdditionalPayment);
            Assert.AreEqual(0m, payments[0].OutstandingPrincipal);
        }
        public void AmortizeSinglePaymentLoanTest()
        {
            //Amortize a loan with a single payment
            //Test data computed by 'Single Payment Loan.xlsx'
            var loan = new AmortizedLoan
            {
                NumPayments = 1,
                Principal = 100,
                InterestRate = 0.10m
            };

            List<Payment> payments = loan.Amortize(Currency.UsDollars);
            Assert.AreEqual(1, payments.Count);
            Assert.AreEqual(1, payments[0].Ordinal);
            Assert.AreEqual(100, payments[0].Principal);
            Assert.AreEqual(10, payments[0].Interest);
            Assert.AreEqual(0, payments[0].OutstandingPrincipal);
        }
 public void AmortizeEmptyLoanTest()
 {
     var loan = new AmortizedLoan();
     loan.Amortize(Currency.UsDollars);
 }