Class: FinancialCalculator::Amortization
- Inherits:
-
Object
- Object
- FinancialCalculator::Amortization
- Defined in:
- lib/financial_calculator/amortization.rb
Overview
There are two ways to create an amortization. The first example uses the amortize method for the Numeric class. The second calls Amortization.new directly.
the Amortization class provides an interface for working with loan amortizations.
Instance Attribute Summary collapse
-
#balance ⇒ DecNum
readonly
The balance of the loan at the end of the amortization period (usually zero).
-
#payment ⇒ DecNum
readonly
The required monthly payment.
-
#principal ⇒ DecNum
readonly
The principal amount of the loan.
-
#rates ⇒ Array
readonly
The interest rates used for calculating the amortization.
Class Method Summary collapse
-
.payment(principal, rate, periods) ⇒ DecNum
The periodic payment due on a loan.
Instance Method Summary collapse
-
#==(amortization) ⇒ Numeric
compare two Amortization instances.
-
#additional_payments ⇒ Array
The amount of any additional payments in each period.
-
#amortize(rate) ⇒ Object
private
amortize the balance of loan with the given interest rate.
-
#compute ⇒ Object
private
compute the amortization of the principal.
-
#duration ⇒ Integer
The time required to pay off the loan, in months.
-
#initialize(principal, *rates, &block) ⇒ Amortization
constructor
create a new Amortization instance.
- #inspect ⇒ Object
-
#interest ⇒ Array
The amount of interest charged in each period.
-
#payments ⇒ Array
The amount of the payment in each period.
Constructor Details
#initialize(principal, *rates, &block) ⇒ Amortization
create a new Amortization instance
130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/financial_calculator/amortization.rb', line 130 def initialize(principal, *rates, &block) @principal = Flt::DecNum.new(principal.to_s) @rates = rates @block = block # compute the total duration from all of the rates. @periods = (rates.collect { |r| r.duration }).sum @period = 0 compute end |
Instance Attribute Details
#balance ⇒ DecNum (readonly)
Returns the balance of the loan at the end of the amortization period (usually zero).
22 23 24 |
# File 'lib/financial_calculator/amortization.rb', line 22 def balance @balance end |
#payment ⇒ DecNum (readonly)
Returns the required monthly payment. For loans with more than one rate, returns nil.
25 26 27 |
# File 'lib/financial_calculator/amortization.rb', line 25 def payment @payment end |
#principal ⇒ DecNum (readonly)
Returns the principal amount of the loan.
28 29 30 |
# File 'lib/financial_calculator/amortization.rb', line 28 def principal @principal end |
#rates ⇒ Array (readonly)
Returns the interest rates used for calculating the amortization.
31 32 33 |
# File 'lib/financial_calculator/amortization.rb', line 31 def rates @rates end |
Class Method Details
.payment(principal, rate, periods) ⇒ DecNum
in most cases, you will probably want to use rate.monthly when calling this function outside of an Amortization instance.
Returns the periodic payment due on a loan.
172 173 174 175 176 177 178 179 |
# File 'lib/financial_calculator/amortization.rb', line 172 def Amortization.payment(principal, rate, periods) if rate.zero? # simplified formula to avoid division-by-zero when interest rate is zero return -(principal / periods).round(2) else return -(principal * (rate + (rate / ((1 + rate) ** periods - 1)))).round(2) end end |
Instance Method Details
#==(amortization) ⇒ Numeric
compare two Amortization instances
37 38 39 |
# File 'lib/financial_calculator/amortization.rb', line 37 def ==(amortization) self.principal == amortization.principal and self.rates == amortization.rates and self.payments == amortization.payments end |
#additional_payments ⇒ Array
Returns the amount of any additional payments in each period.
47 48 49 |
# File 'lib/financial_calculator/amortization.rb', line 47 def additional_payments @transactions.find_all(&:payment?).collect{ |p| p.difference } end |
#amortize(rate) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
amortize the balance of loan with the given interest rate
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/financial_calculator/amortization.rb', line 55 def amortize(rate) # For the purposes of calculating a payment, the relevant time # period is the remaining number of periods in the loan, not # necessarily the duration of the rate itself. periods = @periods - @period amount = Amortization.payment @balance, rate.monthly, periods pmt = Payment.new(amount, :period => @period) if @block then pmt.modify(&@block) end rate.duration.to_i.times do # Do this first in case the balance is zero already. if @balance.zero? then break end # Compute and record interest on the outstanding balance. int = (@balance * rate.monthly).round(2) interest = Interest.new(int, :period => @period) @balance += interest.amount @transactions << interest.dup # Record payment. Don't pay more than the outstanding balance. if pmt.amount.abs > @balance then pmt.amount = -@balance end @transactions << pmt.dup @balance += pmt.amount @period += 1 end end |
#compute ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
compute the amortization of the principal
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/financial_calculator/amortization.rb', line 87 def compute @balance = @principal @transactions = [] @rates.each do |rate| amortize(rate) end # Add any remaining balance due to rounding error to the last payment. unless @balance.zero? @transactions.find_all(&:payment?)[-1].amount -= @balance @balance = 0 end if @rates.length == 1 @payment = self.payments[0] else @payment = nil end @transactions.freeze end |
#duration ⇒ Integer
Returns the time required to pay off the loan, in months.
120 121 122 |
# File 'lib/financial_calculator/amortization.rb', line 120 def duration self.payments.length end |
#inspect ⇒ Object
143 144 145 |
# File 'lib/financial_calculator/amortization.rb', line 143 def inspect "Amortization.new(#{@principal})" end |
#interest ⇒ Array
Returns the amount of interest charged in each period.
157 158 159 |
# File 'lib/financial_calculator/amortization.rb', line 157 def interest @transactions.find_all(&:interest?).collect{ |p| p.amount } end |
#payments ⇒ Array
Returns the amount of the payment in each period.
187 188 189 |
# File 'lib/financial_calculator/amortization.rb', line 187 def payments @transactions.find_all(&:payment?).collect{ |p| p.amount } end |