Class: Finance::Loan
- Inherits:
-
Object
- Object
- Finance::Loan
- Defined in:
- lib/finance/loan.rb
Constant Summary collapse
- PAYMENT_TYPE_MAPPING =
{ end: 0.0, beginning: 1.0 }.freeze
Instance Attribute Summary collapse
-
#amount ⇒ Float
The amount of loan request (I.e. a present value) You can use #pv method to calculate value if param is not defined.
-
#duration ⇒ Float
The number of periods to be compounded for.
-
#future_value ⇒ Float
Future value.
-
#monthly_rate ⇒ Float
readonly
The monthly rate is the nominal annual rate divided by 12.
-
#nominal_rate ⇒ Float
The nominal annual rate of interest as decimal (not per cent).
-
#payment ⇒ Float
The (fixed) periodic payment.
-
#period ⇒ Float
Period under consideration.
-
#ptype ⇒ Integer
Specification of whether payment is made at the beginning (ptype = 1) or the end (ptype = 0) of each period.
Instance Method Summary collapse
-
#fv(payment: nil) ⇒ Float
Fv computes future value at the end of some periods (duration).
-
#initialize(**options) ⇒ Loan
constructor
Create a new Loan instance.
-
#ipmt ⇒ Float
IPmt computes interest payment for a loan under a given period.
-
#nper ⇒ Float
Nper computes the number of periodic payments.
-
#pmt ⇒ Numeric
Pmt computes the payment against a loan principal plus interest (future_value = 0).
-
#ppmt ⇒ Float
PPmt computes principal payment for a loan under a given period.
-
#pv ⇒ Float
Pv computes present value.
-
#rate(tolerance: 1e-6, iterations: 100, initial_guess: 0.1) ⇒ Float
Rate computes the interest rate per period by running Newton Rapson to find an approximate value.
Constructor Details
#initialize(**options) ⇒ Loan
Create a new Loan instance.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/finance/loan.rb', line 44 def initialize(**) initialize_payment_type([:ptype]) @nominal_rate = .fetch(:nominal_rate, 0).to_f @duration = .fetch(:duration, 1).to_f @amount = .fetch(:amount, 0).to_f @future_value = .fetch(:future_value, 0).to_f @period = [:period] @payment = [:payment] @monthly_rate = @nominal_rate / 12 end |
Instance Attribute Details
#amount ⇒ Float
Returns The amount of loan request (I.e. a present value) You can use #pv method to calculate value if param is not defined. Defaults to 0.
10 11 12 |
# File 'lib/finance/loan.rb', line 10 def amount @amount end |
#duration ⇒ Float
Returns The number of periods to be compounded for. (I.e. Nper()) Defaults to 1. You can use #nper method to calculate value if param is not defined.
29 30 31 |
# File 'lib/finance/loan.rb', line 29 def duration @duration end |
#future_value ⇒ Float
Returns Future value. You can use #fv method to calculate value if param is not defined. Defaults to 0.
34 35 36 |
# File 'lib/finance/loan.rb', line 34 def future_value @future_value end |
#monthly_rate ⇒ Float (readonly)
Returns The monthly rate is the nominal annual rate divided by 12. Defaults to 0.
24 25 26 |
# File 'lib/finance/loan.rb', line 24 def monthly_rate @monthly_rate end |
#nominal_rate ⇒ Float
Returns The nominal annual rate of interest as decimal (not per cent). (e.g., 13% -> 0.13) Defaults to 0.
20 21 22 |
# File 'lib/finance/loan.rb', line 20 def nominal_rate @nominal_rate end |
#payment ⇒ Float
Returns The (fixed) periodic payment. You can use #pmt method to calculate value if param is not defined.
38 39 40 |
# File 'lib/finance/loan.rb', line 38 def payment @payment end |
#period ⇒ Float
Returns Period under consideration.
41 42 43 |
# File 'lib/finance/loan.rb', line 41 def period @period end |
#ptype ⇒ Integer
Returns Specification of whether payment is made at the beginning (ptype = 1) or the end (ptype = 0) of each period. Defaults to 0.
15 16 17 |
# File 'lib/finance/loan.rb', line 15 def ptype @ptype end |
Instance Method Details
#fv(payment: nil) ⇒ Float
Fv computes future value at the end of some periods (duration).
Required Loan arguments: nominal_rate, duration, payment, amount*
171 172 173 174 175 176 177 178 179 180 |
# File 'lib/finance/loan.rb', line 171 def fv(payment: nil) raise ArgumentError, 'no payment given' if self.payment.nil? && payment.nil? final_payment = payment || self.payment factor = (1.0 + monthly_rate)**duration second_factor = (factor - 1) * (1 + monthly_rate * ptype) / monthly_rate -((amount * factor) + (final_payment.to_f * second_factor)) end |
#ipmt ⇒ Float
IPmt computes interest payment for a loan under a given period.
Required Loan arguments: period, nominal_rate, duration, amount, future_value*
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/finance/loan.rb', line 104 def ipmt raise ArgumentError, 'no period given' if period.nil? ipmt_val = remaining_balance * monthly_rate if ptype == PAYMENT_TYPE_MAPPING[:beginning] period == 1 ? 0.0 : (ipmt_val / 1 + monthly_rate) else ipmt_val end end |
#nper ⇒ Float
Nper computes the number of periodic payments.
Required Loan arguments: payment, nominal_rate, period, amount, future_value*
146 147 148 149 150 |
# File 'lib/finance/loan.rb', line 146 def nper z = payment * (1.0 + monthly_rate * ptype) / monthly_rate Math.log(-future_value + z / (amount + z)) / Math.log(1.0 + monthly_rate) end |
#pmt ⇒ Numeric
Pmt computes the payment against a loan principal plus interest (future_value = 0).
It can also be used to calculate the recurring payments needed to achieve
a certain future value given an initial deposit,
a fixed periodically compounded interest rate, and the total number of periods.
Required Loan arguments: nominal_rate, duration, amount, future_value*
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/finance/loan.rb', line 75 def pmt factor = (1.0 + monthly_rate)**duration second_factor = if monthly_rate.zero? duration else (factor - 1) * (1 + monthly_rate * ptype) / monthly_rate end -((future_value + amount * factor) / second_factor) end |
#ppmt ⇒ Float
PPmt computes principal payment for a loan under a given period.
Required Loan arguments: period, nominal_rate, duration, amount, future_value*
132 133 134 |
# File 'lib/finance/loan.rb', line 132 def ppmt pmt - ipmt end |
#pv ⇒ Float
Pv computes present value.
Required Loan arguments: nominal_rate, duration, payment, future_value, *ptype
198 199 200 201 202 203 |
# File 'lib/finance/loan.rb', line 198 def pv factor = (1.0 + monthly_rate)**duration second_factor = (factor - 1) * (1 + monthly_rate * ptype) / monthly_rate -(future_value + (payment.to_f * second_factor)) / factor end |
#rate(tolerance: 1e-6, iterations: 100, initial_guess: 0.1) ⇒ Float
Rate computes the interest rate per period
by running Newton Rapson to find an approximate value.
225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/finance/loan.rb', line 225 def rate(tolerance: 1e-6, iterations: 100, initial_guess: 0.1) next_iteration_rate = nil current_iteration_rate = initial_guess (0..iterations).each do |iteration| next_iteration_rate = current_iteration_rate - rate_ratio(current_iteration_rate) break if (next_iteration_rate - current_iteration_rate).abs <= tolerance current_iteration_rate = next_iteration_rate end next_iteration_rate end |