Example #1
0
        private OCurrency CalculateInterestRepayment(TrancheOptions to, OCurrency remainsInterestAmount, OCurrency remainingOlb, OCurrency olb)
        {
            OCurrency result = 0;

            if (to.ApplyNewInterestOnOLB)
            {
                result = (olb + remainingOlb) * to.InterestRate + remainsInterestAmount;
            }
            else
            {
                if (_currentLoan.UseCents)
                {
                    OCurrency previousCapitalRepayment =
                        Math.Round(remainingOlb.Value * _currentLoan.GivenTranches[to.Number - 1].InterestRate.Value,
                                   2, MidpointRounding.AwayFromZero);
                    OCurrency newCapitalRepayment = Math.Round(olb.Value * to.InterestRate, 2,
                                                               MidpointRounding.AwayFromZero);

                    result = newCapitalRepayment + previousCapitalRepayment + remainsInterestAmount;
                }
                else
                {
                    OCurrency previousCapitalRepayment =
                        Math.Round(remainingOlb.Value * _currentLoan.GivenTranches[to.Number - 1].InterestRate.Value,
                                   0, MidpointRounding.AwayFromZero);
                    OCurrency newCapitalRepayment = Math.Round(olb.Value * to.InterestRate, 0,
                                                               MidpointRounding.AwayFromZero);

                    result = newCapitalRepayment + previousCapitalRepayment + remainsInterestAmount;
                }
            }
            result = RoundResult(_currentLoan.UseCents, result);
            return(result);
        }
Example #2
0
        private OCurrency CalculateCapitalRepayment(TrancheOptions to, Installment installment)
        {
            OCurrency result = to.TrancheAmount / to.CountOfNewInstallments + _previousSchedule[installment.Number - 1].CapitalRepayment;

            result = RoundResult(_currentLoan.UseCents, result);
            return(result);
        }
Example #3
0
        public void AddTranche_Annuity_ApplyNewInterest_Accrual()
        {
            ApplicationSettings.GetInstance("").UpdateParameter(OGeneralSettings.ACCOUNTINGPROCESS, OAccountingProcesses.Accrual);
            Loan loan = _GetLoan(_GetAnnuityProduct(), 1000, 0.025m, 4, new DateTime(2010, 5, 11));
            loan.Disburse(new DateTime(2010, 5, 11), true, false);
            loan.Repay(1, new DateTime(2010, 6, 11), 266m, false, true);
            loan.Repay(2, new DateTime(2010, 7, 9), 266m, false, true);
            Assert.AreEqual(loan.GetInstallment(0).IsRepaid, true);
            Assert.AreEqual(loan.GetInstallment(1).IsRepaid, true);

            TrancheOptions to = new TrancheOptions
            {
                TrancheDate = new DateTime(2010, 7, 15),
                CountOfNewInstallments = 4,
                TrancheAmount = 1000,
                InterestRate = 0.03m,
                ApplyNewInterestOnOLB = true
            };

             loan.AddTranche(loan.CalculateTranche(to));

            _AssertInstallment(loan, 2, "2010-08-16", 46m, 362m);
            _AssertInstallment(loan, 3, "2010-09-15", 35m, 372m);
            _AssertInstallment(loan, 4, "2010-10-15", 23m, 384m);
            _AssertInstallment(loan, 5, "2010-11-15", 12m, 394m);
        }
Example #4
0
 private void CheckAndCorrectSumOfCapitalRepayments(TrancheOptions to, Installment installment)
 {
     if (installment.Number == _currentLoan.InstallmentList.Count)
     {
         OCurrency sumOfCapitalRepayment = 0;
         foreach (Installment item in _currentLoan.InstallmentList)
         {
             sumOfCapitalRepayment += item.CapitalRepayment;
         }
         installment.CapitalRepayment += _currentLoan.Amount + to.TrancheAmount - sumOfCapitalRepayment;
     }
 }
Example #5
0
        private OCurrency CalculateInterestRepaymentWithNewInterest(TrancheOptions to, OCurrency remainsInterestAmount, OCurrency remainingOlb, OCurrency olb, OCurrency interestAmount)
        {
            OCurrency result;

            if (to.ApplyNewInterestOnOLB)
            {
                result = (olb + remainingOlb) * to.InterestRate + remainsInterestAmount;
            }
            else
            {
                result = olb * to.InterestRate + interestAmount;
            }
            result = RoundResult(_currentLoan.UseCents, result);
            return(result);
        }
Example #6
0
        public TrancheEvent AddTranche(TrancheOptions trancheOptions)
        {
            _trancheEvent = new TrancheEvent
            {
                Date         = trancheOptions.TrancheDate,
                InterestRate = trancheOptions.InterestRate,
                Amount       = trancheOptions.TrancheAmount,
                Maturity     = trancheOptions.CountOfNewInstallments,
                StartDate    = trancheOptions.TrancheDate,
                Number       = _currentLoan.GivenTranches.Count
            };

            trancheOptions.Number = _trancheEvent.Number;

            switch (_currentLoan.Product.LoanType)
            {
            case OLoanTypes.Flat:
            {
                AddFlatTranche(trancheOptions);
            }
            break;

            case OLoanTypes.DecliningFixedPrincipal:
            {
                AddFixedPrincipalTranche(trancheOptions);
            }
            break;

            case OLoanTypes.DecliningFixedInstallments:
            {
                AddFixedInstallmentTranche(trancheOptions);
            }
            break;
            }

            _currentLoan.CalculateStartDates();
            return(_trancheEvent);
        }
Example #7
0
        public TrancheEvent AddTranche(TrancheOptions trancheOptions)
        {
            _trancheEvent = new TrancheEvent
                                {
                                    Date = trancheOptions.TrancheDate,
                                    InterestRate = trancheOptions.InterestRate,
                                    Amount = trancheOptions.TrancheAmount,
                                    Maturity = trancheOptions.CountOfNewInstallments,
                                    StartDate = trancheOptions.TrancheDate,
                                    Number = _currentLoan.GivenTranches.Count
                                };

            trancheOptions.Number = _trancheEvent.Number;

            switch (_currentLoan.Product.LoanType)
            {
                case OLoanTypes.Flat:
                    {
                        AddFlatTranche(trancheOptions);
                    }
                    break;

                case OLoanTypes.DecliningFixedPrincipal:
                    {
                        AddFixedPrincipalTranche(trancheOptions);
                    }
                    break;

                case OLoanTypes.DecliningFixedInstallments:
                    {
                        AddFixedInstallmentTranche(trancheOptions);
                    }
                    break;
            }

            _currentLoan.CalculateStartDates();
            return _trancheEvent;
        }
Example #8
0
        public Loan AddTranche(Loan pContract, IClient pClient, DateTime pDate, int pNbOfMaturity, int pTrancheAmount, bool pApplyNewInterestOnOLB, decimal pNewInterestRate)
        {
            using (SqlConnection conn = _loanManager.GetConnection())
            using (SqlTransaction sqlTransaction = conn.BeginTransaction())
            {
                try
                {
                    CheckTranche(pDate, pContract, pTrancheAmount);

                    Loan copyOfLoan = pContract.Copy();

                    TrancheOptions to = new TrancheOptions
                                            {
                                                TrancheDate = pDate,
                                                CountOfNewInstallments = pNbOfMaturity,
                                                TrancheAmount = pTrancheAmount,
                                                InterestRate = pNewInterestRate,
                                                ApplyNewInterestOnOLB = pApplyNewInterestOnOLB
                                            };

                    TrancheEvent trancheEvent = pContract.CalculateTranche(to);
                    trancheEvent.User = _user;

                    //insert into table TrancheEvent
                    _ePs.FireEvent(trancheEvent, pContract, sqlTransaction);

                    ArchiveInstallments(copyOfLoan, trancheEvent, sqlTransaction);

                    //delete all the old installments of the table Installments
                    _instalmentManager.DeleteInstallments(pContract.Id, sqlTransaction);

                    //insert all the new installments in the table Installments
                    _instalmentManager.AddInstallments(pContract.InstallmentList, pContract.Id, sqlTransaction);

                    //Activate the contract if it's closed because of new tranch
                    if (pContract.Closed)
                    {
                        pContract.ContractStatus = OContractStatus.Active;
                        pContract.Closed = false;
                        _loanManager.UpdateLoan(pContract, sqlTransaction);
                    }
                    //in the feature might be combine UpdateLoan + UpdateLoanWithinTranche
                    _loanManager.UpdateLoanWithinTranche(to.InterestRate, pContract.NbOfInstallments, pContract,
                                                         sqlTransaction);
                    pContract.Events.Add(trancheEvent);
                    pContract.GivenTranches.Add(trancheEvent);
                    sqlTransaction.Commit();

                    SetClientStatus(pContract, pClient);
                    return pContract;
                }
                catch (Exception ex)
                {
                    if (sqlTransaction != null)
                        sqlTransaction.Rollback();

                    throw ex;
                }
            }
        }
Example #9
0
        private void AddFixedInstallmentTranche(TrancheOptions to)
        {
            OCurrency remainsAmount = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    remainsAmount += installment.CapitalRepayment - installment.PaidCapital;
                }
            }

            OCurrency remainsInterestAmount = _generalSettings.AccountingProcesses == OAccountingProcesses.Accrual
                                                  ? GenerateEvents.Accrual.CalculateRemainingInterests(_currentLoan, to.TrancheDate)
                                                  : GenerateEvents.Cash.CalculateRemainingInterests(_currentLoan, to.TrancheDate);

            remainsInterestAmount = _currentLoan.UseCents ? remainsInterestAmount : Math.Round(remainsInterestAmount.Value, 0, MidpointRounding.AwayFromZero);

            TrancheExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);

            OCurrency olb;
            OCurrency newAmountVpm;
            OCurrency priviousAmountVpm = 0;

            if (to.ApplyNewInterestOnOLB)
            {
                olb = to.TrancheAmount + remainsAmount;

                newAmountVpm = _currentLoan.UseCents
                                   ? _currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate)
                                   : Math.Round(_currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate).Value, 0, MidpointRounding.AwayFromZero);
                remainsAmount = 0;
            }
            else
            {
                olb = to.TrancheAmount;

                newAmountVpm = _currentLoan.UseCents
                                   ? _currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate)
                                   : Math.Round(_currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate).Value, 0,
                                                MidpointRounding.AwayFromZero);
                priviousAmountVpm = _currentLoan.UseCents
                                        ? _currentLoan.VPM(remainsAmount, to.CountOfNewInstallments,
                                                           (_currentLoan.GivenTranches[to.Number - 1].InterestRate.Value))
                                        : Math.Round((_currentLoan.VPM(remainsAmount, to.CountOfNewInstallments,
                                                                       (_currentLoan.GivenTranches[to.Number - 1].InterestRate.Value))).Value, 0,
                                                     MidpointRounding.AwayFromZero);
            }

            OCurrency _OLB = olb + remainsAmount;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    installment.InterestsRepayment = _currentLoan.UseCents
                                   ? Math.Round(olb.Value * to.InterestRate, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(olb.Value * to.InterestRate, 0, MidpointRounding.AwayFromZero);

                    OCurrency interestAmountForPriviousOlb = _currentLoan.UseCents
                                   ? remainsAmount * _currentLoan.GivenTranches[to.Number - 1].InterestRate
                                   : Math.Round((remainsAmount * _currentLoan.GivenTranches[to.Number - 1].InterestRate).Value, 0, MidpointRounding.AwayFromZero);

                    installment.CapitalRepayment = newAmountVpm.Value - installment.InterestsRepayment.Value;

                    installment.InterestsRepayment += _currentLoan.UseCents
                                   ? Math.Round(interestAmountForPriviousOlb.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(interestAmountForPriviousOlb.Value, 0, MidpointRounding.AwayFromZero);

                    olb -= installment.CapitalRepayment;

                    installment.CapitalRepayment = _currentLoan.UseCents
                                   ? Math.Round(installment.CapitalRepayment.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(installment.CapitalRepayment.Value, 0, MidpointRounding.AwayFromZero);


                    OCurrency priviousCapital = priviousAmountVpm - interestAmountForPriviousOlb;

                    installment.CapitalRepayment += _currentLoan.UseCents
                                   ? Math.Round(priviousCapital.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(priviousCapital.Value, 0, MidpointRounding.AwayFromZero);


                    remainsAmount -= priviousCapital;

                    installment.InterestsRepayment += _currentLoan.UseCents
                                   ? Math.Round(remainsInterestAmount.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(remainsInterestAmount.Value, 0, MidpointRounding.AwayFromZero);

                    remainsInterestAmount     = 0;
                    installment.PaidCapital   = 0;
                    installment.PaidInterests = 0;
                }
            }

            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment +=
                _currentLoan.UseCents
                    ? Math.Round(olb.Value + remainsAmount.Value, 2, MidpointRounding.AwayFromZero)
                    : Math.Round(olb.Value + remainsAmount.Value, 0, MidpointRounding.AwayFromZero);

            //OLB calculation
            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    installment.OLB = _OLB;
                    _OLB           -= installment.CapitalRepayment;
                }
            }

            _currentLoan.Amount = _currentLoan.Amount + to.TrancheAmount;
            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment +=
                _currentLoan.UseCents
                    ? Math.Round(_OLB.Value, 2, MidpointRounding.AwayFromZero)
                    : Math.Round(_OLB.Value, 0, MidpointRounding.AwayFromZero);
        }
Example #10
0
        private OCurrency RecalculateInterestForFirstNotPaidInstallment(Installment installment, OCurrency remainingOlb, TrancheOptions to)
        {
            OCurrency newInterest = 0;

            if (installment.ExpectedDate > _previousSchedule[installment.Number - 1].ExpectedDate)
            {
                if (installment.Number == 1)
                {
                    int daysBeforeTranche = (to.TrancheDate - _currentLoan.StartDate).Days;
                    int oldQuantityOfDays =
                        (_previousSchedule[installment.Number - 1].ExpectedDate - _currentLoan.StartDate).Days;
                    newInterest = remainingOlb * _currentLoan.GivenTranches[to.Number - 1].InterestRate / oldQuantityOfDays * daysBeforeTranche
                                  + _previousSchedule[installment.Number - 1].InterestsRepayment;
                }
                else
                {
                    int daysBeforeTranche =
                        (to.TrancheDate - _previousSchedule[installment.Number - 2].ExpectedDate).Days;
                    int oldQuantityOfDays =
                        (_previousSchedule[installment.Number - 1].ExpectedDate -
                         _previousSchedule[installment.Number - 2].ExpectedDate).Days;
                    newInterest = remainingOlb * _currentLoan.GivenTranches[to.Number - 1].InterestRate / oldQuantityOfDays * daysBeforeTranche
                                  + _previousSchedule[installment.Number - 1].InterestsRepayment;
                }
            }
            else
            {
                newInterest = remainingOlb * _currentLoan.GivenTranches[to.Number - 1].InterestRate;
            }
            newInterest = RoundResult(_currentLoan.UseCents, newInterest);
            return(newInterest);
        }
Example #11
0
        private void AddFlatTranche(TrancheOptions to)
        {
            OCurrency remainsInterestAmount = 0;
            OCurrency remainsAmount = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    if (to.TrancheDate > _currentLoan.InstallmentList[installment.Number - 2].ExpectedDate)
                    {
                        remainsInterestAmount += installment.InterestsRepayment *
                                                 (to.TrancheDate - _currentLoan.InstallmentList[installment.Number - 2].ExpectedDate).Days /
                                                 _currentLoan.NumberOfDaysInTheInstallment(installment.Number, to.TrancheDate);
                    }

                    remainsAmount += installment.CapitalRepayment - installment.PaidCapital;
                }
            }

            OCurrency interestAmount = !to.ApplyNewInterestOnOLB
                                           ? to.TrancheAmount * to.InterestRate +
                                             remainsInterestAmount / to.CountOfNewInstallments
                                           : (to.TrancheAmount + remainsAmount) * to.InterestRate +
                                             remainsInterestAmount / to.CountOfNewInstallments;

            OCurrency generalInterestAmount = interestAmount;

            interestAmount = _currentLoan.UseCents ? interestAmount : Math.Round(interestAmount.Value, 0);

            OCurrency olb = to.TrancheAmount + remainsAmount;

            TrancheExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    installment.CapitalRepayment = _currentLoan.UseCents
                                                       ? (to.TrancheAmount + remainsAmount) /
                                                         to.CountOfNewInstallments
                                                       : Math.Round(
                                                             ((to.TrancheAmount + remainsAmount) /
                                                              to.CountOfNewInstallments).Value, 0);

                    installment.InterestsRepayment = interestAmount;

                    installment.PaidCapital = 0;
                    installment.PaidInterests = 0;
                    installment.OLB = olb;
                    olb -= installment.CapitalRepayment;
                }
            }

            OCurrency lastInstallmentInterest = _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].InterestsRepayment +
                generalInterestAmount * to.CountOfNewInstallments - interestAmount * to.CountOfNewInstallments;

            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].InterestsRepayment = _currentLoan.UseCents
                                                                                ? lastInstallmentInterest
                                                                                : Math.Round(
                                                                                      lastInstallmentInterest
                                                                                          .Value, 0);
            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment =
                _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment + olb;

            _currentLoan.Amount = _currentLoan.Amount + to.TrancheAmount;
        }
Example #12
0
 private OCurrency CalculateInterestRepaymentWithNewInterest(TrancheOptions to, OCurrency remainsInterestAmount,  OCurrency remainingOlb, OCurrency olb, OCurrency interestAmount)
 {
     OCurrency result;
     if (to.ApplyNewInterestOnOLB)
         result= (olb + remainingOlb)*to.InterestRate + remainsInterestAmount;
     else
         result = olb * to.InterestRate + interestAmount;
     result = RoundResult(_currentLoan.UseCents, result);
     return result;
 }
Example #13
0
        public void AddTranche_FixedPrincipal_ApplyNewInterest_Cash()
        {
            ApplicationSettings.GetInstance("").UpdateParameter(OGeneralSettings.ACCOUNTINGPROCESS, OAccountingProcesses.Cash);
            Loan loan = _GetLoan(_GetFixedPrincipalProduct(), 1000, 0.025m, 4, new DateTime(2010, 5, 11));
            loan.Disburse(new DateTime(2010, 5, 11), true, false);
            loan.Repay(1, new DateTime(2010, 6, 11), 275m, false, true);
            loan.Repay(2, new DateTime(2010, 7, 9), 269m, false, true);

            Assert.AreEqual(loan.GetInstallment(0).IsRepaid, true);
            Assert.AreEqual(loan.GetInstallment(1).IsRepaid, true);

            TrancheOptions to = new TrancheOptions
            {
                TrancheDate = new DateTime(2010, 7, 15),
                CountOfNewInstallments = 4,
                TrancheAmount = 1000,
                InterestRate = 0.03m,
                ApplyNewInterestOnOLB = true
            };

            loan.AddTranche(loan.CalculateTranche(to));

            _AssertInstallment(loan, 2, "2010-08-16", 45m, 500m);
            _AssertInstallment(loan, 3, "2010-09-15", 30m, 500m);
            _AssertInstallment(loan, 4, "2010-10-15", 15m, 250m);
            _AssertInstallment(loan, 5, "2010-11-15", 8m, 250m);
        }
Example #14
0
        private void AddFixedPrincipalTranche(TrancheOptions to)
        {
            OCurrency remainsAmount = 0;
            //            List<Installment> _previousSchedule = new List<Installment>();
            int numberRemainInstallment = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
            //                previousSchedule.Add(installment);

                if (!installment.IsRepaid)
                {
                    remainsAmount += installment.CapitalRepayment - installment.PaidCapital;
                    numberRemainInstallment++;
                }
            }

            OCurrency olb = to.TrancheAmount;

            OCurrency remainsInterestAmount = _generalSettings.AccountingProcesses == OAccountingProcesses.Accrual
                                                  ? GenerateEvents.Accrual.CalculateRemainingInterests(_currentLoan, to.TrancheDate)
                                                  : GenerateEvents.Cash.CalculateRemainingInterests(_currentLoan, to.TrancheDate);

            remainsInterestAmount = _currentLoan.UseCents ? remainsInterestAmount : Math.Round(remainsInterestAmount.Value, 0, MidpointRounding.AwayFromZero);

            TrancheExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);
            OCurrency remainingOlb = remainsAmount;
            bool itIsFirstNotRepaidInstallment=true;
            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (installment.IsRepaid) continue;

                if (_previousSchedule.Count >= installment.Number)
                {
                    if (!_previousSchedule[installment.Number - 1].IsRepaid)
                    {
                        installment.CapitalRepayment = CalculateCapitalRepayment(to, installment);

                        if (itIsFirstNotRepaidInstallment)
                        {
                            OCurrency interestAmount = RecalculateInterestForFirstNotPaidInstallment(installment, remainingOlb, to);
                            installment.InterestsRepayment =
                                CalculateInterestRepaymentWithNewInterest(to, remainsInterestAmount, remainingOlb, olb, interestAmount);
                            itIsFirstNotRepaidInstallment = false;
                        }
                        else
                        {
                            installment.InterestsRepayment = CalculateInterestRepayment(to, remainsInterestAmount, remainingOlb, olb);
                        }

                        installment.OLB = olb + remainingOlb;

                        if (installment.Number!=_previousSchedule.Count)
                            remainingOlb = _previousSchedule[installment.Number].OLB;
                        if (_currentLoan.UseCents)
                            olb -= Math.Round(to.TrancheAmount.Value / to.CountOfNewInstallments, 2, MidpointRounding.AwayFromZero);
                        else
                        {
                            olb -= Math.Round(to.TrancheAmount.Value/to.CountOfNewInstallments, 0, MidpointRounding.AwayFromZero);
                        }

                        installment.PaidCapital = 0;
                        installment.PaidInterests = 0;
                        remainsInterestAmount = 0;
                    }
                }
                else
                {
                    installment.CapitalRepayment = _currentLoan.UseCents
                                                       ? Math.Round(to.TrancheAmount.Value / to.CountOfNewInstallments, 2, MidpointRounding.AwayFromZero)
                                                       : Math.Round(
                                                             (to.TrancheAmount / to.CountOfNewInstallments).Value, 0,
                                                             MidpointRounding.AwayFromZero);

                    CheckAndCorrectSumOfCapitalRepayments(to, installment);
                    installment.InterestsRepayment = olb.Value * to.InterestRate;

                    installment.InterestsRepayment = _currentLoan.UseCents
                                                         ? Math.Round(installment.InterestsRepayment.Value, 2, MidpointRounding.AwayFromZero)
                                                         : Math.Round(installment.InterestsRepayment.Value, 0,
                                                                      MidpointRounding.AwayFromZero);

                    installment.PaidCapital = 0;
                    installment.PaidInterests = 0;
                    installment.OLB = olb;

                    olb -= installment.CapitalRepayment;
                }
            }

            _currentLoan.Amount = _currentLoan.Amount + to.TrancheAmount;
        }
Example #15
0
        private void AddFixedPrincipalTranche(TrancheOptions to)
        {
            OCurrency remainsAmount = 0;
//            List<Installment> _previousSchedule = new List<Installment>();
            int numberRemainInstallment = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
//                previousSchedule.Add(installment);

                if (!installment.IsRepaid)
                {
                    remainsAmount += installment.CapitalRepayment - installment.PaidCapital;
                    numberRemainInstallment++;
                }
            }

            OCurrency olb = to.TrancheAmount;

            OCurrency remainsInterestAmount = _generalSettings.AccountingProcesses == OAccountingProcesses.Accrual
                                                  ? GenerateEvents.Accrual.CalculateRemainingInterests(_currentLoan, to.TrancheDate)
                                                  : GenerateEvents.Cash.CalculateRemainingInterests(_currentLoan, to.TrancheDate);

            remainsInterestAmount = _currentLoan.UseCents ? remainsInterestAmount : Math.Round(remainsInterestAmount.Value, 0, MidpointRounding.AwayFromZero);


            TrancheExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);
            OCurrency remainingOlb = remainsAmount;
            bool      itIsFirstNotRepaidInstallment = true;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (installment.IsRepaid)
                {
                    continue;
                }


                if (_previousSchedule.Count >= installment.Number)
                {
                    if (!_previousSchedule[installment.Number - 1].IsRepaid)
                    {
                        installment.CapitalRepayment = CalculateCapitalRepayment(to, installment);

                        if (itIsFirstNotRepaidInstallment)
                        {
                            OCurrency interestAmount = RecalculateInterestForFirstNotPaidInstallment(installment, remainingOlb, to);
                            installment.InterestsRepayment =
                                CalculateInterestRepaymentWithNewInterest(to, remainsInterestAmount, remainingOlb, olb, interestAmount);
                            itIsFirstNotRepaidInstallment = false;
                        }
                        else
                        {
                            installment.InterestsRepayment = CalculateInterestRepayment(to, remainsInterestAmount, remainingOlb, olb);
                        }

                        installment.OLB = olb + remainingOlb;

                        if (installment.Number != _previousSchedule.Count)
                        {
                            remainingOlb = _previousSchedule[installment.Number].OLB;
                        }
                        if (_currentLoan.UseCents)
                        {
                            olb -= Math.Round(to.TrancheAmount.Value / to.CountOfNewInstallments, 2, MidpointRounding.AwayFromZero);
                        }
                        else
                        {
                            olb -= Math.Round(to.TrancheAmount.Value / to.CountOfNewInstallments, 0, MidpointRounding.AwayFromZero);
                        }

                        installment.PaidCapital   = 0;
                        installment.PaidInterests = 0;
                        remainsInterestAmount     = 0;
                    }
                }
                else
                {
                    installment.CapitalRepayment = _currentLoan.UseCents
                                                       ? Math.Round(to.TrancheAmount.Value / to.CountOfNewInstallments, 2, MidpointRounding.AwayFromZero)
                                                       : Math.Round(
                        (to.TrancheAmount / to.CountOfNewInstallments).Value, 0,
                        MidpointRounding.AwayFromZero);

                    CheckAndCorrectSumOfCapitalRepayments(to, installment);
                    installment.InterestsRepayment = olb.Value * to.InterestRate;

                    installment.InterestsRepayment = _currentLoan.UseCents
                                                         ? Math.Round(installment.InterestsRepayment.Value, 2, MidpointRounding.AwayFromZero)
                                                         : Math.Round(installment.InterestsRepayment.Value, 0,
                                                                      MidpointRounding.AwayFromZero);

                    installment.PaidCapital   = 0;
                    installment.PaidInterests = 0;
                    installment.OLB           = olb;

                    olb -= installment.CapitalRepayment;
                }
            }

            _currentLoan.Amount = _currentLoan.Amount + to.TrancheAmount;
        }
Example #16
0
        private void AddFlatTranche(TrancheOptions to)
        {
            OCurrency remainsInterestAmount = 0;
            OCurrency remainsAmount         = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    if (to.TrancheDate > _currentLoan.InstallmentList[installment.Number - 2].ExpectedDate)
                    {
                        remainsInterestAmount += installment.InterestsRepayment *
                                                 (to.TrancheDate - _currentLoan.InstallmentList[installment.Number - 2].ExpectedDate).Days /
                                                 _currentLoan.NumberOfDaysInTheInstallment(installment.Number, to.TrancheDate);
                    }

                    remainsAmount += installment.CapitalRepayment - installment.PaidCapital;
                }
            }

            OCurrency interestAmount = !to.ApplyNewInterestOnOLB
                                           ? to.TrancheAmount * to.InterestRate +
                                       remainsInterestAmount / to.CountOfNewInstallments
                                           : (to.TrancheAmount + remainsAmount) * to.InterestRate +
                                       remainsInterestAmount / to.CountOfNewInstallments;

            OCurrency generalInterestAmount = interestAmount;

            interestAmount = _currentLoan.UseCents ? interestAmount : Math.Round(interestAmount.Value, 0);

            OCurrency olb = to.TrancheAmount + remainsAmount;

            TrancheExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    installment.CapitalRepayment = _currentLoan.UseCents
                                                       ? (to.TrancheAmount + remainsAmount) /
                                                   to.CountOfNewInstallments
                                                       : Math.Round(
                        ((to.TrancheAmount + remainsAmount) /
                         to.CountOfNewInstallments).Value, 0);

                    installment.InterestsRepayment = interestAmount;

                    installment.PaidCapital   = 0;
                    installment.PaidInterests = 0;
                    installment.OLB           = olb;
                    olb -= installment.CapitalRepayment;
                }
            }

            OCurrency lastInstallmentInterest = _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].InterestsRepayment +
                                                generalInterestAmount * to.CountOfNewInstallments - interestAmount * to.CountOfNewInstallments;

            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].InterestsRepayment = _currentLoan.UseCents
                                                                                ? lastInstallmentInterest
                                                                                : Math.Round(
                lastInstallmentInterest
                .Value, 0);
            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment =
                _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment + olb;

            _currentLoan.Amount = _currentLoan.Amount + to.TrancheAmount;
        }
Example #17
0
 private OCurrency RecalculateInterestForFirstNotPaidInstallment(Installment installment, OCurrency remainingOlb, TrancheOptions to)
 {
     OCurrency newInterest=0;
     if (installment.ExpectedDate>_previousSchedule[installment.Number-1].ExpectedDate)
     {
         if (installment.Number==1)
         {
             int daysBeforeTranche = (to.TrancheDate - _currentLoan.StartDate).Days;
             int oldQuantityOfDays =
                 (_previousSchedule[installment.Number - 1].ExpectedDate - _currentLoan.StartDate).Days;
             newInterest = remainingOlb * _currentLoan.GivenTranches[to.Number - 1].InterestRate / oldQuantityOfDays * daysBeforeTranche
                         + _previousSchedule[installment.Number - 1].InterestsRepayment;
         }
         else
         {
             int daysBeforeTranche =
                 (to.TrancheDate - _previousSchedule[installment.Number - 2].ExpectedDate).Days;
             int oldQuantityOfDays =
                 (_previousSchedule[installment.Number - 1].ExpectedDate -
                  _previousSchedule[installment.Number - 2].ExpectedDate).Days;
             newInterest = remainingOlb * _currentLoan.GivenTranches[to.Number - 1].InterestRate / oldQuantityOfDays * daysBeforeTranche
                         + _previousSchedule[installment.Number - 1].InterestsRepayment;
         }
     }
     else
     {
         newInterest = remainingOlb*_currentLoan.GivenTranches[to.Number - 1].InterestRate;
     }
     newInterest = RoundResult(_currentLoan.UseCents, newInterest);
     return newInterest;
 }
Example #18
0
 private void CheckAndCorrectSumOfCapitalRepayments(TrancheOptions to, Installment installment)
 {
     if (installment.Number==_currentLoan.InstallmentList.Count)
     {
         OCurrency sumOfCapitalRepayment = 0;
         foreach (Installment item in _currentLoan.InstallmentList)
         {
             sumOfCapitalRepayment += item.CapitalRepayment;
         }
         installment.CapitalRepayment += _currentLoan.Amount + to.TrancheAmount - sumOfCapitalRepayment;
     }
 }
Example #19
0
        public Loan FakeTranche(Loan pContract, DateTime pDate, int pNbOfMaturity, int pTrancheAmount, bool pApplyNewInterestOnOLB, decimal pNewInterestRate)
        {
            Loan fakeContract = pContract.Copy();

            TrancheOptions to = new TrancheOptions
            {
                TrancheDate = pDate,
                CountOfNewInstallments = pNbOfMaturity,
                TrancheAmount = pTrancheAmount,
                InterestRate = pNewInterestRate,
                ApplyNewInterestOnOLB = pApplyNewInterestOnOLB
            };

            fakeContract.CalculateTranche(to);
            return fakeContract;
        }
Example #20
0
        public TrancheEvent CalculateTranche(TrancheOptions pTo)
        {
            var tranche = new Tranche(this, _generalSettings);

            return tranche.AddTranche(pTo);
        }
Example #21
0
 private OCurrency CalculateCapitalRepayment(TrancheOptions to, Installment installment)
 {
     OCurrency result  = to.TrancheAmount/to.CountOfNewInstallments + _previousSchedule[installment.Number - 1].CapitalRepayment;
     result = RoundResult(_currentLoan.UseCents, result);
     return result;
 }
Example #22
0
        private void AddFixedInstallmentTranche(TrancheOptions to)
        {
            OCurrency remainsAmount = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    remainsAmount += installment.CapitalRepayment - installment.PaidCapital;
                }
            }

            OCurrency remainsInterestAmount = _generalSettings.AccountingProcesses == OAccountingProcesses.Accrual
                                                  ? GenerateEvents.Accrual.CalculateRemainingInterests(_currentLoan, to.TrancheDate)
                                                  : GenerateEvents.Cash.CalculateRemainingInterests(_currentLoan, to.TrancheDate);

            remainsInterestAmount = _currentLoan.UseCents ? remainsInterestAmount : Math.Round(remainsInterestAmount.Value, 0, MidpointRounding.AwayFromZero);

            TrancheExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);

            OCurrency olb;
            OCurrency newAmountVpm;
            OCurrency priviousAmountVpm = 0;

            if (to.ApplyNewInterestOnOLB)
            {
                olb = to.TrancheAmount + remainsAmount;

                newAmountVpm = _currentLoan.UseCents
                                   ? _currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate)
                                   : Math.Round(_currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate).Value, 0, MidpointRounding.AwayFromZero);
                remainsAmount = 0;
            }
            else
            {
                olb = to.TrancheAmount;

                newAmountVpm = _currentLoan.UseCents
                                   ? _currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate)
                                   : Math.Round(_currentLoan.VPM(olb, to.CountOfNewInstallments, to.InterestRate).Value, 0,
                                                MidpointRounding.AwayFromZero);
                priviousAmountVpm = _currentLoan.UseCents
                                        ? _currentLoan.VPM(remainsAmount, to.CountOfNewInstallments,
                                              (_currentLoan.GivenTranches[to.Number - 1].InterestRate.Value))
                                        : Math.Round((_currentLoan.VPM(remainsAmount, to.CountOfNewInstallments,
                                                          (_currentLoan.GivenTranches[to.Number - 1].InterestRate.Value))).Value, 0,
                                                     MidpointRounding.AwayFromZero);
            }

            OCurrency _OLB = olb + remainsAmount;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    installment.InterestsRepayment = _currentLoan.UseCents
                                   ? Math.Round(olb.Value * to.InterestRate, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(olb.Value * to.InterestRate, 0, MidpointRounding.AwayFromZero);

                    OCurrency interestAmountForPriviousOlb = _currentLoan.UseCents
                                   ? remainsAmount * _currentLoan.GivenTranches[to.Number - 1].InterestRate
                                   : Math.Round((remainsAmount * _currentLoan.GivenTranches[to.Number - 1].InterestRate).Value, 0, MidpointRounding.AwayFromZero);

                    installment.CapitalRepayment = newAmountVpm.Value - installment.InterestsRepayment.Value;

                    installment.InterestsRepayment += _currentLoan.UseCents
                                   ? Math.Round(interestAmountForPriviousOlb.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(interestAmountForPriviousOlb.Value, 0, MidpointRounding.AwayFromZero);

                    olb -= installment.CapitalRepayment;

                    installment.CapitalRepayment = _currentLoan.UseCents
                                   ? Math.Round(installment.CapitalRepayment.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(installment.CapitalRepayment.Value, 0, MidpointRounding.AwayFromZero);

                    OCurrency priviousCapital = priviousAmountVpm - interestAmountForPriviousOlb;

                    installment.CapitalRepayment += _currentLoan.UseCents
                                   ? Math.Round(priviousCapital.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(priviousCapital.Value, 0, MidpointRounding.AwayFromZero);

                    remainsAmount -= priviousCapital;

                    installment.InterestsRepayment += _currentLoan.UseCents
                                   ? Math.Round(remainsInterestAmount.Value, 2, MidpointRounding.AwayFromZero)
                                   : Math.Round(remainsInterestAmount.Value, 0, MidpointRounding.AwayFromZero);

                    remainsInterestAmount = 0;
                    installment.PaidCapital = 0;
                    installment.PaidInterests = 0;
                }
            }

            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment +=
                _currentLoan.UseCents
                    ? Math.Round(olb.Value + remainsAmount.Value, 2, MidpointRounding.AwayFromZero)
                    : Math.Round(olb.Value + remainsAmount.Value, 0, MidpointRounding.AwayFromZero);

            //OLB calculation
            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    installment.OLB = _OLB;
                    _OLB -= installment.CapitalRepayment;
                }
            }

            _currentLoan.Amount = _currentLoan.Amount + to.TrancheAmount;
            _currentLoan.InstallmentList[_currentLoan.InstallmentList.Count - 1].CapitalRepayment +=
                _currentLoan.UseCents
                    ? Math.Round(_OLB.Value, 2, MidpointRounding.AwayFromZero)
                    : Math.Round(_OLB.Value, 0, MidpointRounding.AwayFromZero);
        }
Example #23
0
        private OCurrency CalculateInterestRepayment(TrancheOptions to, OCurrency remainsInterestAmount, OCurrency remainingOlb, OCurrency olb)
        {
            OCurrency result=0;
            if (to.ApplyNewInterestOnOLB)
            {
               result =(olb + remainingOlb)*to.InterestRate + remainsInterestAmount;
            }
            else
            {
                if (_currentLoan.UseCents)
                {
                    OCurrency previousCapitalRepayment =
                        Math.Round(remainingOlb.Value*_currentLoan.GivenTranches[to.Number - 1].InterestRate.Value,
                                   2, MidpointRounding.AwayFromZero);
                    OCurrency newCapitalRepayment = Math.Round(olb.Value*to.InterestRate, 2,
                                                               MidpointRounding.AwayFromZero);

                    result = newCapitalRepayment + previousCapitalRepayment + remainsInterestAmount;

                }
                else
                {
                    OCurrency previousCapitalRepayment =
                        Math.Round(remainingOlb.Value * _currentLoan.GivenTranches[to.Number - 1].InterestRate.Value,
                                   0, MidpointRounding.AwayFromZero);
                    OCurrency newCapitalRepayment = Math.Round(olb.Value * to.InterestRate, 0,
                                                               MidpointRounding.AwayFromZero);

                    result = newCapitalRepayment + previousCapitalRepayment + remainsInterestAmount;
                }

            }
            result = RoundResult(_currentLoan.UseCents, result);
            return result;
        }