public List <Installment> CalculateInstallments(bool changeDate) { List <Installment> schedule = new List <Installment>(); OCurrency olb = _contract.Amount; OCurrency totalInterestsRepayment = _contract.Amount * Convert.ToDecimal(_contract.InterestRate) * (_contract.NbOfInstallments - _contract.GracePeriod.Value); decimal decCr = 0; decimal decIr = 0; for (int number = 1; number <= _contract.NbOfInstallments; number++) { Installment installment = new Installment { Number = number, FeesUnpaid = 0, OLB = olb }; if (changeDate) { installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number); } else { installment = _contract.GetInstallment(number - 1); } if (number <= _contract.GracePeriod) { if (!_contract.Product.ChargeInterestWithinGracePeriod) { installment.InterestsRepayment = 0; } installment.CapitalRepayment = 0; installment.InterestsRepayment = Math.Round(installment.OLB.Value * Convert.ToDecimal(_contract.InterestRate) + decIr, _roundingPoint); decIr = _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) - installment.InterestsRepayment.Value; } else { ExoticInstallment exoInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(number - _contract.GracePeriod.Value - 1); OCurrency cr = Convert.ToDecimal(exoInstallment.PrincipalCoeff) * _contract.Amount.Value + decCr; installment.CapitalRepayment = Math.Round(cr.Value, _roundingPoint); decCr = cr.Value - installment.CapitalRepayment.Value; OCurrency ir = totalInterestsRepayment.Value * Convert.ToDecimal(exoInstallment.InterestCoeff) + decIr; installment.InterestsRepayment = Math.Round(ir.Value, _roundingPoint); decIr = ir.Value - installment.InterestsRepayment.Value; } olb -= installment.CapitalRepayment.Value; if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue) { installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint); } schedule.Add(installment); } return(schedule); }
/// <summary> /// This method recalculates installments for a declining rate exotic loan in case of over payment. /// </summary> public void RepayNextInstallments(ref OCurrency amountPaid, ref OCurrency interestEvent, ref OCurrency interestPrepayment, ref OCurrency principalEvent, ref OCurrency feesEvent, ref OCurrency commissionsEvent) { OCurrency totalAmount = 0; bool firstInstallmentToRepay = false; double baseTocalculatePrincipalCoeff = 0; if (amountPaid > 0) { for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment installment = _contract.GetInstallment(i); if (installment.IsRepaid && installment.Number > _contract.GracePeriod) { baseTocalculatePrincipalCoeff += _contract.Product.ExoticProduct.GetExoticInstallment(i - _contract.GracePeriod.Value).PrincipalCoeff; } } baseTocalculatePrincipalCoeff = 1 - baseTocalculatePrincipalCoeff; for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment installment = _contract.GetInstallment(i); if (!installment.IsRepaid && installment.Number <= _contract.GracePeriod) //during Grace Period { installment.OLB -= amountPaid; installment.CapitalRepayment = 0; installment.InterestsRepayment = Math.Round(installment.OLB.Value * Convert.ToDecimal(_contract.InterestRate), 2); } else if (!installment.IsRepaid && !firstInstallmentToRepay) { ExoticInstallment exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i - _contract.GracePeriod.Value); firstInstallmentToRepay = true; installment.OLB -= amountPaid; totalAmount = installment.OLB; installment.CapitalRepayment = Math.Round(totalAmount.Value * Convert.ToDecimal(exoticInstallment.PrincipalCoeff / baseTocalculatePrincipalCoeff), 2); installment.InterestsRepayment = Math.Round(installment.OLB.Value * Convert.ToDecimal(_contract.InterestRate), 2); } else if (!installment.IsRepaid) { ExoticInstallment exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i - _contract.GracePeriod.Value); Installment _installment = _contract.GetInstallment(i - 1); installment.OLB = _installment.OLB - _installment.CapitalRepayment; installment.CapitalRepayment = Math.Round(totalAmount.Value * Convert.ToDecimal(exoticInstallment.PrincipalCoeff / baseTocalculatePrincipalCoeff), 2); installment.InterestsRepayment = Math.Round(installment.OLB.Value * Convert.ToDecimal(_contract.InterestRate), 2); } _paidInstallments.Add(installment); } principalEvent += amountPaid; amountPaid = 0; } }
public void TestGetSumOfInterestCoeffWhenSumIsNull() { ExoticInstallment exoticInstallment1 = new ExoticInstallment(); ExoticInstallment exoticInstallment2 = new ExoticInstallment(); ExoticInstallmentsTable product = new ExoticInstallmentsTable(); product.Add(exoticInstallment1); product.Add(exoticInstallment2); Assert.AreEqual(0, product.SumOfInterestCoeff); }
public void PackageExoticProductCorrectlySetAndRetrieved() { ExoticInstallmentsTable exoticProduct = new ExoticInstallmentsTable(); ExoticInstallment e1 = new ExoticInstallment(); e1.Number = 1; e1.PrincipalCoeff = 0.23; e1.InterestCoeff = 0.15; exoticProduct.Add(e1); package.ExoticProduct = exoticProduct; Assert.IsTrue(package.ExoticProduct.Equals(exoticProduct)); }
public void TestSumForDecliningInterestRateType() { var i1 = new ExoticInstallment() { PrincipalCoeff = 0.7, InterestCoeff = 0 }; var i2 = new ExoticInstallment() { PrincipalCoeff = 0.3, InterestCoeff = 0 }; var exotic = new ExoticInstallmentsTable(); exotic.Add(i1); exotic.Add(i2); Assert.IsTrue(exotic.CheckIfSumIsOk(OLoanTypes.DecliningFixedPrincipal)); }
public void TestGetSumOfInterestCoeff() { ExoticInstallment exoticInstallment1 = new ExoticInstallment(); exoticInstallment1.InterestCoeff = 123; ExoticInstallment exoticInstallment2 = new ExoticInstallment(); exoticInstallment2.InterestCoeff = 100; ExoticInstallmentsTable product = new ExoticInstallmentsTable(); product.Add(exoticInstallment1); product.Add(exoticInstallment2); Assert.AreEqual(223, product.SumOfInterestCoeff); }
public void TestIsExoticProductForDecliningRatePackage() { exoticProduct = new ExoticInstallmentsTable(); e1 = new ExoticInstallment(); e1.Number = 1; e1.PrincipalCoeff = 0.4; e1.InterestCoeff = null; e2 = new ExoticInstallment(); e2.Number = 2; e2.PrincipalCoeff = 0.3; e2.InterestCoeff = null; exoticProduct.Add(e1); exoticProduct.Add(e2); Assert.IsTrue(exoticProduct.IsExoticProductForDecliningRatePackage); }
public void SetUp() { exoticProduct = new ExoticInstallmentsTable(); exoticProduct.Id = 1; exoticProduct.Name = "proportional interest rate with 6 installments"; e1 = new ExoticInstallment(); e1.Number = 1; e1.PrincipalCoeff = 0.4; e1.InterestCoeff = 0.2; e2 = new ExoticInstallment(); e2.Number = 2; e2.PrincipalCoeff = 0.3; e2.InterestCoeff = 0.15; exoticProduct.Add(e1); exoticProduct.Add(e2); }
public void CheckSumOfInterestAndPrincipal_InterestCoefEgal90_PrincipalCoeffEgal10() { ExoticInstallment exoticInstallment1 = new ExoticInstallment(); exoticInstallment1.InterestCoeff = 70; exoticInstallment1.PrincipalCoeff = 0; ExoticInstallment exoticInstallment2 = new ExoticInstallment(); exoticInstallment2.InterestCoeff = 20; exoticInstallment2.PrincipalCoeff = 10; ExoticInstallmentsTable product = new ExoticInstallmentsTable(); product.Add(exoticInstallment1); product.Add(exoticInstallment2); Assert.IsFalse(product.CheckIfSumIsOk(OLoanTypes.Flat)); }
public void Add(ExoticInstallment pExoticInstallment) { pExoticInstallment.Number = _installmentList.Count + 1; _installmentList.Add(pExoticInstallment); }
public void RepayNextInstallments(ref OCurrency amountPaid, ref OCurrency interestEvent, ref OCurrency interestPrepayment, ref OCurrency principalEvent, ref OCurrency feesEvent, ref OCurrency commissionsEvent) { if (amountPaid > 0) { OCurrency totalInterest = 0; OCurrency totalPrincipal = 0; double nbInterest = 0; double nbPrincipal = 0; foreach (Installment _installment in _contract.InstallmentList) { if (_installment.InterestsRepayment - _installment.PaidInterests > 0) { totalInterest += (_installment.InterestsRepayment - _installment.PaidInterests); if (!_contract.GracePeriod.HasValue) { nbInterest += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1).InterestCoeff.Value; } else if (_installment.Number > _contract.GracePeriod.Value) { nbInterest += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1 - _contract.GracePeriod.Value).InterestCoeff.Value; } } if (_installment.CapitalRepayment - _installment.PaidCapital > 0) { totalPrincipal += (_installment.CapitalRepayment - _installment.PaidCapital); if (!_contract.GracePeriod.HasValue) { nbPrincipal += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1).PrincipalCoeff; } else if (_installment.Number > _contract.GracePeriod.Value) { nbPrincipal += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1 - _contract.GracePeriod.Value).PrincipalCoeff; } } } if (AmountComparer.Compare(amountPaid, totalInterest) > 0) { amountPaid -= totalInterest; interestEvent += totalInterest; interestPrepayment += totalInterest; totalInterest = 0; } else { totalInterest -= amountPaid; interestEvent += amountPaid; interestPrepayment += amountPaid; amountPaid = 0; } if (AmountComparer.Compare(amountPaid, totalPrincipal) > 0) { amountPaid -= totalPrincipal; principalEvent += totalPrincipal; totalPrincipal = 0; } else { totalPrincipal -= amountPaid; principalEvent += amountPaid; amountPaid = 0; } if (totalInterest != 0) { totalInterest = totalInterest / (Convert.ToDecimal(nbInterest) * 10); } if (totalPrincipal != 0) { totalPrincipal = totalPrincipal / (Convert.ToDecimal(nbPrincipal) * 10); } for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment _installment = _contract.GetInstallment(i); if (!_installment.IsRepaid) { ExoticInstallment exoticInstallment = null; if (!_contract.GracePeriod.HasValue) { exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i); _installment.InterestsRepayment = Convert.ToDecimal(exoticInstallment.InterestCoeff.Value) * totalInterest * (double)10; _installment.CapitalRepayment = Convert.ToDecimal(exoticInstallment.PrincipalCoeff) * totalPrincipal * (double)10; } else if (_installment.Number > _contract.GracePeriod.Value) { exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i - _contract.GracePeriod.Value); _installment.InterestsRepayment = Convert.ToDecimal(exoticInstallment.InterestCoeff.Value) * totalInterest * (double)10; _installment.CapitalRepayment = Convert.ToDecimal(exoticInstallment.PrincipalCoeff) * totalPrincipal * (double)10; } else { _installment.InterestsRepayment = totalInterest * Convert.ToDecimal(_contract.InterestRate); _installment.CapitalRepayment = 0; } } } } }