/// <summary> /// Calculate the monthly payment on this Cover Section /// </summary> /// <param name="instalmentCount"> /// The count of instalments /// </param> /// <param name="loanInterestPercentage"> /// The loan interest in percent /// </param> /// <param name="nonDepositFraction"> /// The fraction of the total PREMIUM loan NOT represented by the deposit /// i.e. 1 - ( deposit / [total PREMIUM] ) /// </param> public void CalculateMonthlyPayment(int instalmentCount, double loanInterestPercentage, double nonDepositFraction) { _installmentCount = instalmentCount; _loanInterestPercentage = loanInterestPercentage; _monthlyPayment = NumericalOperation.PennyRound(_premium * nonDepositFraction * (1.0 + loanInterestPercentage / NumericalOperation.PercentageDivisor) / instalmentCount); }
public void SetAdditionalCoverSectionMonthlyPaymentPlanDepositDetails( int installmentCount, double schemeResultTotalDeposit, double schemeResultTotalPremium) { _installmentCount = installmentCount; _uncorrectedDeposit = NumericalOperation.PennyRound(schemeResultTotalDeposit * _premium / schemeResultTotalPremium); _depositCorrection = 0.0; }
/// <summary> /// Calculate the monthly payment by an Additional Cover Section /// </summary> /// <param name="schemeResultMonthlyPayment">The total value of a single monthly payment including that for the Primary Cover Section</param> /// <param name="schemeResultTotalPremium">The total value of all the Cover Sections including the Primary Cover Section</param> public void SetAdditionalCoverSectionMonthlyPaymentDetails(double schemeResultMonthlyPayment, double schemeResultTotalPremium) { _uncorrectedMonthlyPayment = NumericalOperation.PennyRound(schemeResultMonthlyPayment * _premium / schemeResultTotalPremium); // Reset _monthlyPaymentCorrection = 0.0; }
public void CalculateMonthlyPaymentPremiums(int instalmentCount) { _instalmentCount = instalmentCount; if (instalmentCount == 12 /* a year */) { // No deposit at Renewal _deposit = 0.0; } else { // Standard deposit calculation _deposit = NumericalOperation.PennyTruncate(TotalPremium * (_depositPercentage / NumericalOperation.PercentageDivisor)) + _depositFixed; } double remainingPrinciple = TotalPremium - _deposit; _totalCalculatedLoan = NumericalOperation.PennyRound(remainingPrinciple * (1.0 + _interestPercentage / NumericalOperation.PercentageDivisor)); // Round the monthly payment // Note that due to the necessary rounding to a penny the total of all the payments may not equal exactly the calculated loan _monthlyPayment = NumericalOperation.PennyRound(_totalCalculatedLoan / instalmentCount); // The actual amount paid double monthlyPaymentTotal = _monthlyPayment * instalmentCount; // Check the difference between the total of the payments and the loan calculation _totalPaymentDifferenceFromCalculatedLoan = monthlyPaymentTotal - _totalCalculatedLoan; // Adjust the payments according to the deposit double nonDepositFraction = 1.0 - _deposit / TotalPremium; PrimaryCoverSection.CalculateMonthlyPayment(instalmentCount, _interestPercentage, nonDepositFraction); SetAdditionalCoverSectionPayments(instalmentCount, nonDepositFraction); // Generate total annual payment values double totalAdditionalCoverSectionAnnualPayment = TotalAdditionalCoverSectionMonthlyPayments * instalmentCount; double totalPrimaryCoverSectionAnnualPayment = PrimaryCoverSection.MonthlyPayment * instalmentCount; // Calculate the difference between the total of the penny rounded payments and what the total should really be double multiplePaymentCorrection = monthlyPaymentTotal - (totalPrimaryCoverSectionAnnualPayment + totalAdditionalCoverSectionAnnualPayment); // Put into the Deposit the difference between the total of the individual payments and what the total should have been _multiplePaymentCorrection = multiplePaymentCorrection; } // CalculateMonthlyPaymentPremiums
public void CalculateMonthlyPaymentPremiums(bool depositRequired, int installmentCount) { // Simple Endsleigh style payment validation if (depositRequired) { // New Business if (installmentCount != 11) { throw new ArgumentException(String.Format("Cases where a deposit is required must be New Business and have 11 payments")); } } // New Business else { // Renewals if (installmentCount != 12) { throw new ArgumentException(String.Format("Cases where a deposit is NOT required must be Renewals and have 12 payments")); } } // Renewals _installmentCount = installmentCount; if (depositRequired) { // Standard deposit calculation for New Business double depositTotal = NumericalOperation.PennyTruncate(TotalPremium * (_depositPercentage / NumericalOperation.PercentageDivisor)) + _depositFixedAmount; foreach (PaymentCoverSection additionalCoverSection in _additionalPaymentCoverSectionContainer) { additionalCoverSection.SetAdditionalCoverSectionMonthlyPaymentPlanDepositDetails(installmentCount, depositTotal, TotalPremium); } PrimaryPaymentCoverSection.InstallmentCount = installmentCount; // Use the remainder as the Primary Cover Section Deposit PrimaryPaymentCoverSection.UncorrectedDeposit = depositTotal - TotalAdditionalCoverSectionDeposits; PrimaryPaymentCoverSection.DepositCorrection = 0.0; } // Standard deposit calculation for New Business else { // No deposit at Renewal foreach (PaymentCoverSection additionalCoverSection in _additionalPaymentCoverSectionContainer) { additionalCoverSection.SetAdditionalCoverSectionMonthlyPaymentPlanDepositDetails(installmentCount, 0.0, TotalPremium); } PrimaryPaymentCoverSection.InstallmentCount = installmentCount; PrimaryPaymentCoverSection.UncorrectedDeposit = 0.0; PrimaryPaymentCoverSection.DepositCorrection = 0.0; } double loanPrincipal = TotalPremium - Deposit; _totalCalculatedLoan = NumericalOperation.PennyRound(loanPrincipal * (1.0 + _interestPercentage / NumericalOperation.PercentageDivisor)); // Round the monthly payment // Note that due to the necessary rounding to a penny the total of all the payments may not equal exactly the calculated loan _monthlyPayment = NumericalOperation.PennyRound(_totalCalculatedLoan / installmentCount); // The actual amount paid double monthlyPaymentTotal = _monthlyPayment * installmentCount; // Retain the difference between the total of the payments and the loan calculation _totalPaymentDifferenceFromCalculatedLoan = _totalCalculatedLoan - monthlyPaymentTotal; if (depositRequired) { // When there is a non-zero deposit correct the total payment // to equal the calculated loan by changing the value of the deposit PrimaryPaymentCoverSection.DepositCorrection = _totalPaymentDifferenceFromCalculatedLoan; } // Distribute the payments across the Cover Sections according to the premium for each Cover Section foreach (PaymentCoverSection additionalCoverSection in _additionalPaymentCoverSectionContainer) { additionalCoverSection.SetAdditionalCoverSectionMonthlyPaymentDetails(_monthlyPayment, TotalPremium); } // Use the remainder as the Primary Cover Section Monthly Payment PrimaryPaymentCoverSection.UncorrectedMonthlyPayment = _monthlyPayment - TotalAdditionalCoverSectionMonthlyPayments; // Calculate the difference between the total of the penny rounded or truncated payments and what the total payments should be really // This should be very close to zero double multiplePaymentDifference = monthlyPaymentTotal - TotalAnnualPayment; _multiplePaymentDifference = multiplePaymentDifference; } // CalculateMonthlyPaymentPremiums