public List <PeriodDataModel> CalculateSchedule(AmortCalcModel model)
        {
            var terms = model.TermInMonths;
            var unpaidPrincipalBalance = model.PrincipalLoanAmount;
            var interestRate           = model.AnnualInterestRate;
            var monthlyIntRate         = ((interestRate / 100) / 12);

            var schedule = new List <PeriodDataModel>
            {
                new PeriodDataModel()
                {
                    EndOfPeriodBalance = unpaidPrincipalBalance
                }
            };

            for (int i = 1; i <= terms; i++)
            {
                var lastPeriod   = schedule[i - 1];
                var interestPaid = lastPeriod.EndOfPeriodBalance * monthlyIntRate;

                var power         = (double)Math.Pow(1.0 + (double)monthlyIntRate, terms - i + 1);
                var principalPaid = (lastPeriod.EndOfPeriodBalance * monthlyIntRate * power / (power - 1)) - interestPaid;
                var endBalance    = lastPeriod.EndOfPeriodBalance - principalPaid;

                schedule.Add(new PeriodDataModel()
                {
                    Period             = i,
                    EndOfPeriodBalance = Math.Round(endBalance, 2),
                    InterestPaid       = Math.Round(interestPaid, 2),
                    PrincipalPaid      = Math.Round(principalPaid, 2)
                });
            }

            return(schedule);
        }
        public double CalculateSingleInstalment(AmortCalcModel model)
        {
            var calculatedPrincipalLoanAmount = model.PrincipalLoanAmount - model.Deposit;
            var interestRate = (model.AnnualInterestRate / 100) / 12;
            var power        = Math.Pow((1 + interestRate), model.TermInMonths);
            var instalment   = calculatedPrincipalLoanAmount * power * interestRate / (power - 1);

            return(Math.Round(instalment, 2));
        }
        public void CalculateSchedule_valid_inputs_should_return_schedule()
        {
            // Arrange
            IAmortCalcService classUnderTest = new AmortCalcService();
            var amortCalcModel = new AmortCalcModel()
            {
                AnnualInterestRate  = 5.44,
                TermInMonths        = 3,
                PaymentFrequency    = PaymentFrequencyTypes.Monthly,
                Deposit             = 0,
                PrincipalLoanAmount = 5000
            };
            var expected = new List <PeriodDataModel>()
            {
                new PeriodDataModel()
                {
                    EndOfPeriodBalance = 5000,
                    InterestPaid       = 0,
                    Period             = 0,
                    PrincipalPaid      = 0
                },
                new PeriodDataModel()
                {
                    EndOfPeriodBalance = 3340.87,
                    InterestPaid       = 22.67,
                    Period             = 1,
                    PrincipalPaid      = 1659.13
                },
                new PeriodDataModel()
                {
                    EndOfPeriodBalance = 1674.21,
                    InterestPaid       = 15.15,
                    Period             = 2,
                    PrincipalPaid      = 1666.66
                },
                new PeriodDataModel()
                {
                    EndOfPeriodBalance = 0,
                    InterestPaid       = 7.59,
                    Period             = 3,
                    PrincipalPaid      = 1674.21
                }
            };

            // Act
            var actual = classUnderTest.CalculateSchedule(amortCalcModel);

            // Assert
            actual.Should().BeEquivalentTo(expected);
        }
        public void CalculateSingleInstalment_valid_inputs_should_return_instalment(double expected, double deposit)
        {
            // Arrange
            IAmortCalcService classUnderTest = new AmortCalcService();
            var amortCalcModel = new AmortCalcModel()
            {
                AnnualInterestRate  = 5.44,
                TermInMonths        = 360,
                PaymentFrequency    = PaymentFrequencyTypes.Monthly,
                Deposit             = deposit,
                PrincipalLoanAmount = 820000
            };

            // Act
            var actual = classUnderTest.CalculateSingleInstalment(amortCalcModel);

            // Assert
            Assert.AreEqual(expected, actual);
        }