Class: Apy::Loan

Inherits:
Object
  • Object
show all
Defined in:
lib/apy/loan.rb

Overview

A loan object; Provides helpers for calculating various debt-related scenarios

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(borrow, apy:) ⇒ Loan

Returns a new instance of Loan.

Parameters:

  • borrow (Numeric)

    Amount of money to be borrowed

  • apy (Float)

    The interest rate of the borrowed money



12
13
14
15
16
17
# File 'lib/apy/loan.rb', line 12

def initialize(borrow, apy:)
  fail(ArgumentError, "apy must be a positive Float") unless apy.positive? && apy.is_a?(Float)

  @borrow = borrow
  @apy = apy
end

Instance Attribute Details

#apyObject (readonly)

Returns the value of attribute apy.



8
9
10
# File 'lib/apy/loan.rb', line 8

def apy
  @apy
end

#borrowObject (readonly)

Returns the value of attribute borrow.



8
9
10
# File 'lib/apy/loan.rb', line 8

def borrow
  @borrow
end

Instance Method Details

#amortized_payment_size(start_date:, end_date:, times: 1, days_per_term: 365, payments_per_term: times) ⇒ Object

TODO:

Finish this

TODO:

Once finished, make #payment_size accept less args (lump-sum, only accept payment count)

Similar to payment_size, except interest accrues based on the remaining debt



62
63
64
# File 'lib/apy/loan.rb', line 62

def amortized_payment_size(start_date:, end_date:, times: 1, days_per_term: 365, payments_per_term: times)
  fail
end

#amortized_total_owed(start_date:, end_date:, times: 1, days_per_term: 365, payments_per_term: times) ⇒ Object

TODO:

Finish this

TODO:

Once finished, make #total_owed accept less args (lump-sum, only accept payment count)



68
69
70
# File 'lib/apy/loan.rb', line 68

def amortized_total_owed(start_date:, end_date:, times: 1, days_per_term: 365, payments_per_term: times)
  fail
end

#payment_size(start_date:, end_date:, times: 1, days_per_term: 365, payments_per_term: times) ⇒ Object

Based on the borrow amount, calculate the payment size required to pay off the principal and accrued interest

Examples:

Payment size for 1200, interest accrued once, repaid in 1 payment across 365 days:

d1 = Date.parse "2020-01-01"
d2 = Date.parse "2021-01-01"
Loan.new(1200, apy: 0.1).payment_size(start_date: d1, end_date: d2) == 1320.0

Payment size for 1200, interest accrued once, repaid in 12 payments across 365 days:

Loan.new(1200, apy: 0.1).payment_size(start_date: d1, end_date: d2, payments_per_term: 12) == 110.0

Payment size for 1200, interest accrued 12 times, repaid in 12 payments across 365 days:

Loan.new(1200, apy: 0.1).payment_size(start_date: d1, end_date: d2, times: 12) == 110.47

Parameters:

  • start_date (Date)

    Date the loan will begin

  • end_date (Date)

    Date the loan will be fully paid off

  • times (Integer) (defaults to: 1)

    The number of times per term interest is accrued; Defaults to 1 (flat rate)

  • days_per_term (Integer) (defaults to: 365)

    The number of days per interest term

  • payments_per_term (Integer) (defaults to: times)

    The number of payments made towards the loan per term; Defaults to ‘times`



33
34
35
36
37
38
39
40
# File 'lib/apy/loan.rb', line 33

def payment_size(start_date:, end_date:, times: 1, days_per_term: 365, payments_per_term: times)
  total_owed(
    start_date: start_date,
    end_date: end_date,
    times: times,
    days_per_term: days_per_term
  ) / (payments_per_term * Interest.get_term_size(start_date, end_date, days_per_term))
end

#total_owed(start_date:, end_date:, times: 1, days_per_term: 365) ⇒ Object

Note:

Because the constructor accepts an APY for the year, an adjusted rate is used here based on days_per_term

Get the total amount owed, based on the start & end date

Parameters:

  • start_date (Date)

    Date the loan will begin

  • end_date (Date)

    Date the loan will be fully paid off

  • times (Integer) (defaults to: 1)

    The number of times per term interest is accrued; Defaults to 1 (flat rate)

  • days_per_term (Integer) (defaults to: 365)

    The number of days per interest term

See Also:



50
51
52
53
54
55
56
57
# File 'lib/apy/loan.rb', line 50

def total_owed(start_date:, end_date:, times: 1, days_per_term: 365)
  Apy::Interest.new(
    apy: adjusted_apy(days_per_term),
    start_date: start_date,
    end_date: end_date,
    days_per_term: days_per_term
  ).total(borrow, times: times)
end