public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent) { //Nothing to modify pInstallment.PaidFees += pFeesEvent; pAmountPaid -= pFeesEvent; pFeesEvent = 0; }
private static void ManualRepayMethod(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pCommisionEvent) { pInstallment.PaidCommissions = pCommisionEvent; pAmountPaid -= pCommisionEvent; pCommisionEvent = 0; //Nothing to modify }
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); }
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; } }
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; } }
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); }
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; } }
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); } } }
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(); }
public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pInterestEvent, ref OCurrency pInterestPrepayment) { //Nothing to modify }
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); }
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); }
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; } }
public void AddInstallment(Installment pInstallment) { _installmentList.Add(pInstallment); }
public void RepayFees(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent) { _methodToCalculateFees.Repay(pInstallment,ref pAmountPaid, ref pFeesEvent); }
public void RepayInterest(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pInterestEvent,ref OCurrency pInterestPrepayment) { _methodToCalculateInterest.Repay(pInstallment, ref pAmountPaid, ref pInterestEvent,ref pInterestPrepayment); }