Пример #1
0
 public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent)
 {
     //Nothing to modify
     pInstallment.PaidFees += pFeesEvent;
     pAmountPaid -= pFeesEvent;
     pFeesEvent = 0;
 }
Пример #2
0
 private static void ManualRepayMethod(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pCommisionEvent)
 {
     pInstallment.PaidCommissions = pCommisionEvent;
     pAmountPaid -= pCommisionEvent;
     pCommisionEvent = 0;
     //Nothing to modify
 }
Пример #3
0
 public void RepayCommission(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pCommisionEvent)
 {
     if (!_pCCO.CancelFees)
         AutomaticRepayMethod(pInstallment, ref pAmountPaid, ref pCommisionEvent);
     else
         ManualRepayMethod(pInstallment, ref pAmountPaid, ref pCommisionEvent);
 }
Пример #4
0
 private static void AutomaticRepayMethod(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pCommisionEvent)
 {
     if (AmountComparer.Compare(pAmountPaid, pInstallment.CommissionsUnpaid) > 0)
     {
         pCommisionEvent += pInstallment.CommissionsUnpaid;
         pAmountPaid -= pInstallment.CommissionsUnpaid;
         pInstallment.PaidCommissions += pInstallment.CommissionsUnpaid;
         pInstallment.CommissionsUnpaid = 0;
     }
     else
     {
         pCommisionEvent += pAmountPaid;
         pInstallment.PaidCommissions += pAmountPaid;
         pInstallment.CommissionsUnpaid -= pAmountPaid;
         pAmountPaid = 0;
     }
 }
Пример #5
0
        public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent)
        {
            if (AmountComparer.Compare(pAmountPaid, pInstallment.FeesUnpaid) > 0)
            {
                pFeesEvent += pInstallment.FeesUnpaid;
                pAmountPaid -= pInstallment.FeesUnpaid;
                pInstallment.PaidFees += pInstallment.FeesUnpaid;
                pInstallment.FeesUnpaid = 0;

            }
            else
            {
                pFeesEvent += pAmountPaid;
                pInstallment.PaidFees += pAmountPaid;
                pInstallment.FeesUnpaid -= pAmountPaid;
                pAmountPaid = 0;
            }
        }
Пример #6
0
        public List<Installment> CalculateInstallments(bool changeDate)
        {
            List<Installment> schedule = new List<Installment>();
            OCurrency olb = _contract.Amount;

            for (int number = 1; number <= _contract.NbOfInstallments; number++)
            {
                Installment installment = new Installment { Number = number, FeesUnpaid = 0 };

                if (changeDate)
                {
                    installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                }

                installment.OLB = olb;
                installment.InterestsRepayment = Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate), RoundingPoint);

                if (number <= _contract.GracePeriod)
                {
                    if (!_contract.Product.ChargeInterestWithinGracePeriod)
                        installment.InterestsRepayment = 0;

                    installment.CapitalRepayment = 0;
                }
                else
                {
                    ExoticInstallment exoInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(number - _contract.GracePeriod.Value - 1);
                    OCurrency capital = Convert.ToDecimal(exoInstallment.PrincipalCoeff) * _contract.Amount.Value;

                    installment.CapitalRepayment = Math.Round(capital.Value, RoundingPoint);
                    olb -= capital;
                }

                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;
            //return _iCI.CalculateInstallments(changeDate);
        }
Пример #7
0
        public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pInterestEvent, ref OCurrency pInterestPrepayment)
        {
            if (AmountComparer.Compare(pAmountPaid, pInstallment.InterestsRepayment - pInstallment.PaidInterests) > 0)
            {
                OCurrency interestHasToPay = pInstallment.InterestsRepayment - pInstallment.PaidInterests;

                pAmountPaid -= interestHasToPay;
                pInterestEvent += interestHasToPay;
                pInterestPrepayment += interestHasToPay;
                pInstallment.PaidInterests += interestHasToPay;
            }
            else
            {
                pInstallment.PaidInterests += pAmountPaid;
                pInterestEvent += pAmountPaid;
                pInterestPrepayment += pAmountPaid;
                pAmountPaid = 0;
            }
        }
Пример #8
0
 private void _Reschedule_ExtendMaturity(int newInstallments)
 {
     if (newInstallments > 0)
     {
         int lastNumber = _contract.LastInstallment.Number;
         for (int i = 1; i <= newInstallments; i++)
         {
             DateTime expectedDate = _contract.CalculateInstallmentDate(_contract.FirstInstallmentDate, lastNumber + i - 1);
             Installment installment = new Installment
             {
                 Number = lastNumber + i,
                 CapitalRepayment = 0,
                 PaidCapital = 0,
                 CommissionsUnpaid = 0,
                 FeesUnpaid = 0,
                 InterestsRepayment = 1,
                 PaidInterests = 0,
                 ExpectedDate = expectedDate
             };
             _contract.AddInstallment(installment);
         }
     }
 }
Пример #9
0
        private void _Reschedule_DecliningFixedInstallments(ReschedulingOptions ro)
        {
            int months = _contract.InstallmentType.NbOfMonths;
            int days = _contract.InstallmentType.NbOfDays;
            int rounding = _contract.UseCents ? 2 : 0;

            // Split installments into two lists - paid and unpaid
            List<Installment> paidInstallments = new List<Installment>();
            List<Installment> unpaidInstallments = new List<Installment>();
            foreach (Installment installment in _contract.InstallmentList)
            {
                if (installment.IsRepaid)
                {
                    paidInstallments.Add(installment);
                }
                else
                {
                    unpaidInstallments.Add(installment);
                }
            }

            // Add new installments
            if (ro.NewInstallments > 0)
            {
                int lastNumber = unpaidInstallments[unpaidInstallments.Count - 1].Number;
                for (int i = 1; i <= ro.NewInstallments; i++)
                {
                    Installment installment = new Installment();
                    installment.Number = lastNumber + i;
                    installment.CapitalRepayment = 0;
                    installment.PaidCapital = 0;
                    installment.InterestsRepayment = 0;
                    installment.PaidInterests = 0;
                    installment.FeesUnpaid = 0;
                    installment.CommissionsUnpaid = 0;
                    unpaidInstallments.Add(installment);
                }
            }

            // We want to recalculate installments if new installments are introduced,
            // interest rate is changed, or the first unpaid installment is partially paid.
            int moveToNext = 0;
            if (unpaidInstallments[0].IsPartiallyRepaid && ro.GracePeriod > 0)
            {
                moveToNext = 1;
            }

            if (ro.NewInstallments > 0 || _contract.InterestRate != ro.InterestRate || unpaidInstallments[0].IsPartiallyRepaid)
            {
                OCurrency initialOlb = unpaidInstallments[0].OLB - unpaidInstallments[0].PaidCapital;

                int n = unpaidInstallments.Count - ro.GracePeriod - moveToNext;
                // We use the formula below to calculate monthly annuity payments

                //OCurrency monthly = 0 == r ? initialOlb / n : initialOlb * r * Math.Pow(1 + r, n) / (Math.Pow(1 + r, n) - 1);
                OCurrency monthly = _contract.VPM(initialOlb, n, ro.InterestRate);
                monthly = Math.Round(monthly.Value, rounding, MidpointRounding.AwayFromZero); //_Reschedule_Round(monthly);

                // Now loop through the unpaid installments and calculate the principal and the interest
                OCurrency sum = 0;
                OCurrency olb = initialOlb;

                foreach (Installment installment in unpaidInstallments)
                {
                    OCurrency interest = olb * ro.InterestRate;

                    if (installment.IsPartiallyRepaid && ro.GracePeriod > 0)
                    {
                        installment.InterestsRepayment = installment.PaidInterests;
                        installment.CapitalRepayment = installment.PaidCapital;
                    }
                    else
                    {
                        if (installment.Number > ro.GracePeriod + unpaidInstallments[0].Number - 1 + moveToNext)
                        {
                            OCurrency principal = monthly - interest;
                            installment.CapitalRepayment = Math.Round(principal.Value, rounding,
                                                                      MidpointRounding.AwayFromZero);
                        }
                        else
                        {
                            installment.CapitalRepayment = 0;
                        }

                        if ((installment.Number > ro.GracePeriod + unpaidInstallments[0].Number - 1 + moveToNext) ||
                            (ro.ChargeInterestDuringGracePeriod))
                        {
                            installment.InterestsRepayment = Math.Round(interest.Value, rounding,
                                                                        MidpointRounding.AwayFromZero);
                        }
                        else
                        {
                            installment.InterestsRepayment = 0;
                        }

                        if (ro.GracePeriod > 0)
                        {
                            if (!installment.IsPartiallyRepaid)
                            {
                                sum += installment.CapitalRepayment;
                                installment.OLB = olb;
                                olb -= installment.CapitalRepayment.Value;
                            }
                        }
                        else
                        {
                            sum += installment.CapitalRepayment;
                            installment.OLB = olb;
                            olb -= installment.CapitalRepayment.Value;
                        }
                    }
                }

                // As a result of rounding there might be some difference between the
                // initial OLB and the sum of installment repayments. Thus we have to
                // compensate for this difference.
                OCurrency diff = sum - initialOlb;
                if (diff != 0)
                {
                    unpaidInstallments[ro.GracePeriod + moveToNext].CapitalRepayment -= diff;
                    int firstNumber = unpaidInstallments[ro.GracePeriod + moveToNext].Number;
                    // Iterate through all unpaid but first
                    foreach (Installment installment in unpaidInstallments.FindAll(x => x.Number > firstNumber))
                    {
                        installment.OLB += diff;
                    }
                }
            }

            // Adjust the amount of interest for the first installment
            if ((ro.RepaymentDateOffset > 0 && ro.ChargeInterestDuringShift) || (_contract.FirstDateChanged && 1 == unpaidInstallments[0].Number))
            {
                DateTime startDate;
                DateTime endDate1;
                DateTime endDate2;
                if (0 == paidInstallments.Count)
                {
                    startDate = _contract.StartDate;
                    endDate1 = startDate.AddMonths(months).AddDays(days);
                    endDate2 = _contract.FirstInstallmentDate.AddDays(ro.RepaymentDateOffset * (ro.ChargeInterestDuringShift ? 1 : 0));
                }
                else
                {
                    startDate = paidInstallments[paidInstallments.Count - 1].ExpectedDate;
                    endDate1 = startDate.AddMonths(months).AddDays(days);
                    endDate2 = endDate1.AddDays(ro.RepaymentDateOffset * (ro.ChargeInterestDuringShift ? 1 : 0));
                }
                TimeSpan oldSpan = endDate1 - startDate;
                TimeSpan newSpan = endDate2 - startDate;
                double olb = Convert.ToDouble(unpaidInstallments[0].OLB.Value);
                double ratio;

                if (ro.GracePeriod > 0 && !ro.ChargeInterestDuringGracePeriod)
                {
                    ratio = (double)(newSpan.Days - oldSpan.Days) / oldSpan.Days;
                }
                else
                {
                    ratio = (double)newSpan.Days / oldSpan.Days;
                }

                OCurrency interest = Convert.ToDecimal(olb * ro.InterestRate * ratio);
                interest = Math.Round(interest.Value, rounding, MidpointRounding.AwayFromZero);
                unpaidInstallments[0].InterestsRepayment = interest;
            }

            if (unpaidInstallments[0].IsPartiallyRepaid)
            {
                int instNum = ro.GracePeriod > 0 ? ro.GracePeriod - 1 : 0;
                unpaidInstallments[instNum].CapitalRepayment += unpaidInstallments[0].PaidCapital;
                unpaidInstallments[instNum].OLB += unpaidInstallments[0].PaidCapital;
            }

            // Adjust dates
            DateTime baseDate = unpaidInstallments[0].ExpectedDate.AddDays(ro.RepaymentDateOffset);
            int num = 0;
            foreach (Installment installment in unpaidInstallments)
            {
                DateTime d = baseDate.AddMonths(months * num).AddDays(days * num);
                d = _nwdS.GetTheNearestValidDate(d, _generalSettings.IsIncrementalDuringDayOff,
                                                 _generalSettings.DoNotSkipNonWorkingDays, true);
                installment.ExpectedDate = d;
                num++;
            }

            // Merge the lists back into one
            _contract.InstallmentList = paidInstallments;
            _contract.InstallmentList.AddRange(unpaidInstallments);
            _contract.NbOfInstallments = _contract.InstallmentList.Count();
        }
Пример #10
0
 public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pInterestEvent, ref OCurrency pInterestPrepayment)
 {
     //Nothing to modify
 }
Пример #11
0
        public List<Installment> CalculateInstallments(bool pChangeDate)
        {
            List<Installment> schedule = new List<Installment>();
            OCurrency olb = _startAmount;
            OCurrency VPM = 0;

            for (int number = 1; number <= _contract.NbOfInstallments; number++)
            {
                Installment installment;

                if (pChangeDate)
                {
                    installment = new Installment {Number = number};
                    installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate,
                                                                                  installment.Number);
                }
                else
                {
                    installment = _contract.GetInstallment(number - 1);
                }

                installment.FeesUnpaid = 0;
                installment.InterestsRepayment = Math.Round(olb.Value*Convert.ToDecimal(_contract.InterestRate),
                                                            RoundingPoint, MidpointRounding.AwayFromZero);

                if (installment.Number <= _contract.GracePeriod)
                {
                    if (!_contract.Product.ChargeInterestWithinGracePeriod)
                        installment.InterestsRepayment = 0;

                    installment.CapitalRepayment = 0;
                }
                else
                {
                    OCurrency installmentVPM = Math.Round(_contract.VPM(olb, _numberOfInstallmentsToPay - installment.Number + 1).Value,
                                   RoundingPoint, MidpointRounding.AwayFromZero);

                    if ((_contract.Product.RoundingType == ORoundingType.End ||
                             _contract.Product.RoundingType == ORoundingType.Begin) && VPM == 0)
                        {
                            VPM = installmentVPM;
                        }
                        else if (_contract.Product.RoundingType == ORoundingType.Approximate)
                        {
                            VPM = installmentVPM;
                        }

                    OCurrency capital =
                        Math.Round((VPM.Value - Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate), RoundingPoint)),
                            RoundingPoint, MidpointRounding.AwayFromZero);

                    installment.CapitalRepayment = capital;

                    //to count the difference in case End and Beging rounding type
                    OCurrency InstallemtDiff = VPM - (installment.CapitalRepayment + installment.InterestsRepayment);

                    if(InstallemtDiff != 0)
                        installment.CapitalRepayment += InstallemtDiff;

                    olb -= capital + InstallemtDiff;
                    ///////////////////////////////////////////////////////////////
                }

                if (installment.Number == 1 && GeneralSettings.PayFirstInterestRealValue)
                {
                    installment.InterestsRepayment =
                        Math.Round(
                            installment.InterestsRepayment.Value/_contract.NbOfDaysInTheInstallment*
                            (_contract.FirstInstallmentDate - _contract.StartDate).Days, RoundingPoint,
                            MidpointRounding.AwayFromZero);
                }

                if (pChangeDate)
                {
                    schedule.Add(installment);
                }
            }

            if (_contract.Product.RoundingType == ORoundingType.End && olb != 0)
            {
                schedule[_contract.NbOfInstallments - 1].CapitalRepayment += olb;
            }

            if (_contract.Product.RoundingType == ORoundingType.Begin && olb != 0)
            {
                schedule[0].CapitalRepayment += olb;
            }

            olb = _startAmount;
            OCurrency capetalRepayment = 0;
            //OLB Calculation
            foreach (Installment installment in schedule)
            {
                olb -= capetalRepayment;
                installment.OLB = olb;
                capetalRepayment = installment.CapitalRepayment;
            }

            return schedule;
            //return _iCs.CalculateInstallments(pChangeDate);
        }
Пример #12
0
        public List<Installment> CalculateInstallments(bool changeDate)
        {
            List<Installment> schedule = new List<Installment>();
            OCurrency olb = _contract.Amount;
            OCurrency totalAmount = _contract.Amount;

            OCurrency totalInterest = _contract.GracePeriod.HasValue && !_contract.Product.ChargeInterestWithinGracePeriod
                                ? Math.Round(_contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) * (_contract.NbOfInstallments - _contract.GracePeriod.Value), RoundingPoint, MidpointRounding.AwayFromZero)
                                : Math.Round(_contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) * _contract.NbOfInstallments, RoundingPoint, MidpointRounding.AwayFromZero);

            int nbOfInstallmentWithoutGracePeriod = _contract.GracePeriod.HasValue ? _contract.NbOfInstallments - _contract.GracePeriod.Value : _contract.NbOfInstallments;

            OCurrency sumOfPrincipal = 0;
            OCurrency sumOfInterest = 0;
            int installmentNumberWithoutGracePeriodForCapital = 0;
            int installmentNumberWithoutGracePeriodForInterest = 0;

            if (!_contract.Rescheduled)
            {
                for (int number = 1; number <= _contract.NbOfInstallments; number++)
                {
                    Installment installment = new Installment { Number = number, FeesUnpaid = 0 };

                    if (changeDate)
                    {
                        installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                    }

                    installment.OLB = olb;
                    if (_contract.GracePeriod.HasValue && number <= _contract.GracePeriod)
                    {
                        installment.CapitalRepayment = 0;
                        if (_contract.Product.ChargeInterestWithinGracePeriod)
                        {
                            installment.InterestsRepayment = Math.Round((totalInterest.Value - sumOfInterest.Value) / (_contract.NbOfInstallments - installmentNumberWithoutGracePeriodForInterest), RoundingPoint);
                            sumOfInterest += installment.InterestsRepayment;
                            installmentNumberWithoutGracePeriodForInterest++;
                        }
                        else
                        {
                            installment.InterestsRepayment = 0;
                            installmentNumberWithoutGracePeriodForInterest++;
                        }
                    }
                    else
                    {
                        installment.CapitalRepayment = decimal.Round((totalAmount.Value - sumOfPrincipal.Value) / (nbOfInstallmentWithoutGracePeriod - installmentNumberWithoutGracePeriodForCapital), RoundingPoint);
                        sumOfPrincipal += installment.CapitalRepayment;
                        installmentNumberWithoutGracePeriodForCapital++;

                        installment.InterestsRepayment = Math.Round((totalInterest.Value - sumOfInterest.Value) / (_contract.NbOfInstallments - installmentNumberWithoutGracePeriodForInterest), RoundingPoint);
                        sumOfInterest += installment.InterestsRepayment;
                        installmentNumberWithoutGracePeriodForInterest++;
                    }

                    if (installment.Number == 1 && GeneralSettings.PayFirstInterestRealValue)
                    {
                        installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, RoundingPoint);
                    }

                    olb -= installment.CapitalRepayment.Value;

                    schedule.Add(installment);
                }
            }
            else
            {
                for (int number = 1; number <= _contract.NbOfInstallments; number++)
                {
                    Installment installment = new Installment { Number = number, FeesUnpaid = 0 };

                    if (changeDate)
                    {
                        installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number);
                    }

                    installment.OLB = olb;
                    if (_contract.GracePeriod.HasValue && number <= _contract.GracePeriod)
                    {
                        installment.CapitalRepayment = 0;
                        if (_contract.Product.ChargeInterestWithinGracePeriod)
                        {
                            installment.InterestsRepayment = _initialOLBOfContractBeforeRescheduling.Value * Convert.ToDecimal(_contract.InterestRate);
                            // decimal.Round((totalInterest.Value - sumOfInterest.Value) / (_contract.NbOfInstallments - installmentNumberWithoutGracePeriodForInterest), 2);
                        }
                        else
                        {
                            installment.InterestsRepayment = 0;
                        }
                    }
                    else
                    {
                        installment.CapitalRepayment = Math.Round((totalAmount.Value - sumOfPrincipal.Value) / (nbOfInstallmentWithoutGracePeriod - installmentNumberWithoutGracePeriodForCapital), RoundingPoint);
                        sumOfPrincipal += installment.CapitalRepayment;
                        installmentNumberWithoutGracePeriodForCapital++;

                        installment.InterestsRepayment = _initialOLBOfContractBeforeRescheduling.Value * Convert.ToDecimal(_contract.InterestRate);
                        //installment.InterestsRepayment = decimal.Round((totalInterest.Value - sumOfInterest.Value) / (_contract.NbOfInstallments - installmentNumberWithoutGracePeriodForInterest), 2);
                    }

                    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;
            //return _iCS.CalculateInstallments(changeDate);
        }
Пример #13
0
        private void _Tranche_ExtendMaturity(int newInstallments, DateTime pFirstInstallmentDate)
        {
            if (newInstallments > 0)
            {
                List<Installment> listInstallment = new List<Installment>();
                listInstallment.AddRange(_currentLoan.InstallmentList);

                foreach (Installment _installment in _currentLoan.InstallmentList)
                {
                    if (!_installment.IsRepaid)
                    {
                        listInstallment.Remove(_installment);
                    }
                }

                int lastNumber = listInstallment.Count;
                _trancheEvent.StartedFrom = lastNumber;

                for (int i = 1; i <= newInstallments; i++)
                {
                    DateTime expectedDate = _currentLoan.CalculateInstallmentDate(pFirstInstallmentDate, i);
                    Installment installment = new Installment
                    {
                        Number = lastNumber + i,
                        CapitalRepayment = 0,
                        PaidCapital = 0,
                        CommissionsUnpaid = 0,
                        FeesUnpaid = 0,
                        InterestsRepayment = 1,
                        PaidInterests = 0,
                        ExpectedDate = expectedDate
                    };

                    listInstallment.Add(installment);
                }
                _currentLoan.InstallmentList = listInstallment;

                _currentLoan.NbOfInstallments = _currentLoan.InstallmentList.Count;
            }
        }
Пример #14
0
 public void AddInstallment(Installment pInstallment)
 {
     _installmentList.Add(pInstallment);
 }
Пример #15
0
 public void RepayFees(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent)
 {
     _methodToCalculateFees.Repay(pInstallment,ref pAmountPaid, ref pFeesEvent);
 }
Пример #16
0
 public void RepayInterest(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pInterestEvent,ref OCurrency pInterestPrepayment)
 {
     _methodToCalculateInterest.Repay(pInstallment, ref pAmountPaid, ref pInterestEvent,ref pInterestPrepayment);
 }