예제 #1
0
        public TrancheEvent AddTranche(TrancheOptions pTO)
        {
            _trancheEvent = new TrancheEvent
                                {
                                    Date = DateTime.Now,
                                    InterestRate = pTO.InterestRate,
                                    Amount = pTO.TrancheAmount,
                                    Maturity = pTO.CountOfNewInstallments,
                                    StartDate = pTO.TrancheDate,
                                    Number = _currentLoan.GivenTranches.Count
                                };

            pTO.Number = _trancheEvent.Number;

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

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

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

            return _trancheEvent;
        }
예제 #2
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);

            _Tranche_ExtendMaturity(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, (double)to.InterestRate)
                                   : Math.Round(_currentLoan.VPM(olb, to.CountOfNewInstallments, (double)to.InterestRate).Value, 0, MidpointRounding.AwayFromZero);
                RemainsAmount = 0;
            }
            else
            {
                olb = to.TrancheAmount;

                newAmountVPM = _currentLoan.UseCents
                                   ? _currentLoan.VPM(olb, to.CountOfNewInstallments, (double)to.InterestRate)
                                   : Math.Round(_currentLoan.VPM(olb, to.CountOfNewInstallments, (double)to.InterestRate).Value, 0,
                                                MidpointRounding.AwayFromZero);
                priviousAmountVPM = _currentLoan.UseCents
                                        ? _currentLoan.VPM(RemainsAmount, to.CountOfNewInstallments,
                                              (double)(_currentLoan.GivenTranches[to.Number - 1].InterestRate.Value))
                                        : Math.Round((_currentLoan.VPM(RemainsAmount, to.CountOfNewInstallments,
                                                          (double)(_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 - to.CountOfNewInstallments].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);
        }
예제 #3
0
        private void AddFixedPrincipalTranche(TrancheOptions to)
        {
            OCurrency RemainsAmount = 0;
            List<Installment> _NotRepaidInstollment = new List<Installment>();
            int numberRemainInstallment = 0;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                _NotRepaidInstollment.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);

            _Tranche_ExtendMaturity(to.CountOfNewInstallments, to.TrancheDate);
            OCurrency RemainingOLB = RemainsAmount;

            foreach (Installment installment in _currentLoan.InstallmentList)
            {
                if (!installment.IsRepaid)
                {
                    if (_NotRepaidInstollment.Count >= installment.Number)
                    {
                        if (!_NotRepaidInstollment[installment.Number - 1].IsRepaid)
                        {
                            installment.CapitalRepayment = _currentLoan.UseCents
                                                               ? to.TrancheAmount / to.CountOfNewInstallments +
                                                                 RemainsAmount / numberRemainInstallment
                                                               : Math.Round(
                                                                     (to.TrancheAmount / to.CountOfNewInstallments +
                                                                      RemainsAmount / numberRemainInstallment).Value, 0,
                                                                     MidpointRounding.AwayFromZero);

                            installment.InterestsRepayment = to.ApplyNewInterestOnOLB
                                           ? (olb + RemainingOLB) * to.InterestRate + RemainsInterestAmount
                                           : olb * to.InterestRate + RemainingOLB * _currentLoan.GivenTranches[to.Number - 1].InterestRate + RemainsInterestAmount;

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

                            installment.OLB = olb + RemainingOLB;

                            RemainingOLB -= _currentLoan.UseCents
                                                 ? RemainingOLB / numberRemainInstallment
                                                 : Math.Round(
                                                       (RemainingOLB / numberRemainInstallment).Value, 0,
                                                       MidpointRounding.AwayFromZero);

                            olb -= to.TrancheAmount / to.CountOfNewInstallments;

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

                        installment.InterestsRepayment = olb * to.InterestRate;

                        installment.InterestsRepayment = _currentLoan.UseCents
                                     ? installment.InterestsRepayment
                                     : 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;
        }
예제 #4
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;

            _Tranche_ExtendMaturity(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;
        }
예제 #5
0
파일: Loan.cs 프로젝트: Ramazanov/FomsNet
        public TrancheEvent CalculateTranche(TrancheOptions pTo)
        {
            var tranche = new Tranche(this, _generalSettings);

            return tranche.AddTranche(pTo);
        }