Module: Refinance::Annuities
- Defined in:
- lib/refinance/annuities.rb
Overview
This module contains methods for calculating the basic properties of annuities. Annuities are assumed to be an annuities immediate (that is, interest is accumulated before the payment).
The floating-point numbers you pass in as arguments can be instances of Float or BigDecimal. Actually, thanks to duck typing, they can be any objects that support the necessary operations.
Class Method Summary collapse
-
.effective_interest_rate(nair, cppy) ⇒ Object
Determines the effective interest rate, given:.
-
.improve_interest_rate(payment, periods, principal, guess) ⇒ Object
Iteratively improve an approximated interest rate for an annuity using the Newton-Raphson method.
-
.interest_rate(payment, periods, principal, initial_guess = 0.1, precision = 0.0001, max_decimals = 8, max_iterations = 10) ⇒ Object
Determine an annuity’s interest rate over some period, given:.
-
.payment(interest_rate, periods, principal) ⇒ Object
Determine an annuity’s periodic payment amount, given:.
-
.periods(interest_rate, payment, principal) ⇒ Object
Determine the number of payment periods for an annuity, given:.
-
.principal(interest_rate, payment, periods) ⇒ Object
Determine an annuity’s principal, given:.
Class Method Details
.effective_interest_rate(nair, cppy) ⇒ Object
Determines the effective interest rate, given:
-
The nominal annual interest rate
-
The number of compounding periods per year
95 96 97 |
# File 'lib/refinance/annuities.rb', line 95 def self.effective_interest_rate(nair, cppy) (((nair / cppy) + 1) ** cppy) - 1 end |
.improve_interest_rate(payment, periods, principal, guess) ⇒ Object
Iteratively improve an approximated interest rate for an annuity using the Newton-Raphson method. This method is used by ::interest_rate.
47 48 49 50 51 52 53 |
# File 'lib/refinance/annuities.rb', line 47 def self.improve_interest_rate(payment, periods, principal, guess) top = payment - (payment * ((guess + 1) ** -periods)) - (principal * guess) bottom = (periods * payment * ((guess + 1) ** (-periods - 1))) - principal guess - (top / bottom) end |
.interest_rate(payment, periods, principal, initial_guess = 0.1, precision = 0.0001, max_decimals = 8, max_iterations = 10) ⇒ Object
Determine an annuity’s interest rate over some period, given:
-
Periodic payment amount
-
Number of payment periods
-
Principal
This has no closed-form solution, so the answer is iteratively approximated with the Newton-Raphson method. After each improvement, the guess will be rounded; max_decimals is the number of decimal places to keep (if you set this high, the algorithm will be slow). max_iterations is the maximum number of iterations that will be attempted. It will stop iterating if the last improvement was less than precision in magnitude.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/refinance/annuities.rb', line 28 def self.interest_rate(payment, periods, principal, initial_guess = 0.1, precision = 0.0001, max_decimals = 8, max_iterations = 10) guess = initial_guess max_iterations.times do new_guess = improve_interest_rate(payment, periods, principal, guess). round(max_decimals) difference = (guess - new_guess).abs guess = new_guess break if difference < precision end guess end |
.payment(interest_rate, periods, principal) ⇒ Object
Determine an annuity’s periodic payment amount, given:
-
Interest rate over a period
-
Number of payment periods
-
Principal
62 63 64 |
# File 'lib/refinance/annuities.rb', line 62 def self.payment(interest_rate, periods, principal) (interest_rate * principal) / (1 - ((interest_rate + 1) ** -periods)) end |
.periods(interest_rate, payment, principal) ⇒ Object
Determine the number of payment periods for an annuity, given:
-
Interest rate over a period
-
Periodic payment amount
-
Principal
73 74 75 76 |
# File 'lib/refinance/annuities.rb', line 73 def self.periods(interest_rate, payment, principal) -Math.log(1 - ((interest_rate * principal) / payment)) / Math.log(interest_rate + 1) end |
.principal(interest_rate, payment, periods) ⇒ Object
Determine an annuity’s principal, given:
-
Interest rate over a period
-
Periodic payment amount
-
Number of payment periods
85 86 87 |
# File 'lib/refinance/annuities.rb', line 85 def self.principal(interest_rate, payment, periods) (payment / interest_rate) * (1 - ((interest_rate + 1) ** -periods)) end |