Class: Financier::Amortization

Inherits:
Object
  • Object
show all
Defined in:
lib/financier/amortization.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(principal, rate, closing_date: nil, first_payment_due: nil) ⇒ Amortization

Returns a new instance of Amortization.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/financier/amortization.rb', line 20

def initialize(principal, rate, closing_date: nil, first_payment_due: nil)
  @principal = Flt::DecNum.new(principal.to_s)
  @rate = rate

  self.closing_date = closing_date || Time.now
  self.first_payment_due = first_payment_due || (@closing_date + 30.days)

  #@periods = rate.duration
  #@period = 0

  compute
end

Instance Attribute Details

#closing_dateObject

attr_reader :principal, :rate, :closing_date, :first_payment_due



18
19
20
# File 'lib/financier/amortization.rb', line 18

def closing_date
  @closing_date
end

#first_payment_dueObject

attr_reader :principal, :rate, :closing_date, :first_payment_due



18
19
20
# File 'lib/financier/amortization.rb', line 18

def first_payment_due
  @first_payment_due
end

#ledgerObject (readonly)

attr_reader :principal, :rate, :closing_date, :first_payment_due



18
19
20
# File 'lib/financier/amortization.rb', line 18

def ledger
  @ledger
end

#paymentObject (readonly)

attr_reader :principal, :rate, :closing_date, :first_payment_due



18
19
20
# File 'lib/financier/amortization.rb', line 18

def payment
  @payment
end

Class Method Details

.interest(principal, rate) ⇒ Object



12
13
14
# File 'lib/financier/amortization.rb', line 12

def interest(principal, rate)
  (D(principal.to_s) * D(rate.to_s))
end

.payment(principal, rate, periods) ⇒ Object



4
5
6
7
8
9
10
# File 'lib/financier/amortization.rb', line 4

def payment(principal, rate, periods)
  principal, rate, periods = [D(principal.to_s), D(rate.to_s), D(periods.to_s)]

  return -(principal / periods).round(2) if rate.zero?

  -(principal * (rate + (rate / ((1 + rate) ** periods - 1)))).round(2)
end

Instance Method Details

#amortizeObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/financier/amortization.rb', line 56

def amortize
  @payment = Amortization.payment(@principal + interim_interest, @rate.monthly, @rate.duration)
  @ledger = Ledger.new(@principal)

  current_date = @first_payment_due

  @rate.duration.to_i.times do |period|
    break if @ledger.balance.zero?

    int = @ledger.balance * @rate.monthly
    int += interim_interest * (1 + @rate.monthly) if period === 0
    @ledger << Transaction.new(int.round(2), current_date)

    pmt = @payment.abs <= @ledger.balance ? @payment : -@ledger.balance
    @ledger << Transaction.new(pmt, current_date)

    current_date += 1.month
  end

  @ledger.debits.last.amount -= @ledger.balance unless @ledger.balance.zero?
end

#balanceObject



33
34
35
36
# File 'lib/financier/amortization.rb', line 33

def balance
  return unless @ledger
  @ledger.balance
end

#computeObject



78
79
80
# File 'lib/financier/amortization.rb', line 78

def compute
  amortize
end

#interestObject



43
44
45
46
# File 'lib/financier/amortization.rb', line 43

def interest
  return unless @ledger
  @ledger.credits[1..(@ledger.credits.length - 1)]
end

#paymentsObject



38
39
40
41
# File 'lib/financier/amortization.rb', line 38

def payments
  return unless @ledger
  @ledger.debits
end

#scheduleObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/financier/amortization.rb', line 82

def schedule
  @schedule = {}

  @schedule[closing_date] = {
    payment: 0.0,
    interest: 0.0,
    principal: 0.0,
    balance: @principal.round(2).to_f
  }

  payments.each_with_index do |payment, index|
    interest = self.interest[index]

    pmt = payment.amount.abs.round(2).to_f
    int = interest.amount.abs.round(2).to_f
    princ = (pmt - int).round(2).to_f
    bal = @ledger.balance(before: payment.date + 1.day).round(2).to_f

    @schedule[payment.date] = {
      payment: pmt,
      interest: int,
      principal: princ,
      balance: bal
    }
  end

  @schedule
end