mortgage-buddy 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c4dcd770517fb8d88b02c5bb62accfb05268f4a
4
- data.tar.gz: a82c613cbfad5ba13ee19d7b0c9b3785da790902
3
+ metadata.gz: 57d7dfa4923485c7c5c7d832249a7d655019f228
4
+ data.tar.gz: 9db923e6a6a4bf5a89064e066f4901d82fc13660
5
5
  SHA512:
6
- metadata.gz: dfe96325cb57d7484509cdd76289de0c4a30acceb423f1ad37e6bb3854ade42b5adc16dbd2db2de919bcda70d68261facdaf4e362b43b3c28adf36098fc435aa
7
- data.tar.gz: ce526f2e8094c38f7901ba0158a7892eeb9df64ec7882ff8c2025a052dc45f1852e676337af3d792cca40136ee2c08fc76ef074f93ea5ea1a9fe60164556cbeb
6
+ metadata.gz: c7fe975c98ab2a0a72c171598bdc14504f95eb76c3c50d4a3c31ccc2d114b45e431674676b4758ab6c7ac43d572098d50a41503cac8f49252e5e2f2fa5534c77
7
+ data.tar.gz: 1673be619c7ec677eb68af1cb69649f7d1beb0a13d7a2c0fe54857f7f3ab0a059d1f22d3a18ade8f5f5a8e5ea7134b96ba12349413bae5f97ba3d69f0a2f464d
data/README.md CHANGED
@@ -1,14 +1,9 @@
1
- https://travis-ci.org/perryqh/mortgage-buddy.svg?branch=master
2
-
3
1
  # MortgageBuddy
4
- [![Gem Version](https://badge.fury.io/rb/g5_updatable.svg)](http://badge.fury.io/rb/g5_updatable)
2
+ [![Gem Version](https://badge.fury.io/rb/mortgage-buddy.svg)](https://badge.fury.io/rb/mortgage-buddy)
5
3
  [![Build Status](https://travis-ci.org/perryqh/mortgage-buddy.svg?branch=master)](https://travis-ci.org/perryqh/mortgage-buddy)
6
4
 
7
5
  This gem will calculate APR and Amoratization.
8
6
 
9
- The Amoratization class can really help you if you're trying to decide on refinancing.
10
-
11
-
12
7
 
13
8
  ## Installation
14
9
 
@@ -28,39 +23,55 @@ Or install it yourself as:
28
23
 
29
24
  ## Usage
30
25
  ```ruby
31
- mortgage_cost = MortgageBuddy::MortgageCost.new(loan_amount: 550000,
32
- interest_rate: 3.0,
33
- period: 360,
34
- fees: 600,
35
- points: 0)
26
+
27
+ loan_amount = 550000
28
+ interest_rate = 3.0
29
+ period = 360 # 12 months * 30 years
30
+ fees = 600 # $600 closing costs
31
+ points = 0 # no points to get this loan
32
+
33
+ mortgage_cost = MortgageBuddy::MortgageCost.new(loan_amount: loan_amount,
34
+ interest_rate: interest_rate,
35
+ period: period,
36
+ fees: fees,
37
+ points: points)
36
38
  puts mortgage_cost.apr # 3.01% (rounded)
37
39
  puts mortgage_cost.monthly_payment_with_fees # $2321.35 (rounded)
38
40
 
39
- amoratizer = MortgageBuddy::Amoratizer.new(interest_rate: mortgage_cost.apr,
40
- loan_amount: 550000,
41
- period: 360)
41
+ amoratizer_30_year = MortgageBuddy::Amoratizer.new(interest_rate: interest_rate,
42
+ loan_amount: loan_amount,
43
+ period: period)
42
44
 
43
- puts amoratizer.total_num_payments # 360 or 30 years (no extra payment)
44
- puts amoratizer.total_interest # $285,684.09 (disturbing)
45
- puts amoratizer.payments # an array of openstructs with every payment amount, interest, principal, etc
45
+ puts amoratizer_30_year.total_num_payments # 360 or 30 years (no extra payment)
46
+ puts amoratizer_30_year.total_interest # $284,773.56 (disturbing)
47
+ puts amoratizer_30_year.payments # an array of openstructs with every payment amount, interest, principal, etc
46
48
 
47
49
  # Now let's see what happens when we pay extra
48
-
49
- amoratizer_with_extra = MortgageBuddy::Amoratizer.new(interest_rate: mortgage_cost.apr,
50
- loan_amount: 550000,
51
- period: 360,
52
- extra_monthly_payment: 1000)
53
-
54
- puts amoratizer_with_extra.total_num_payments # 215 or just under 18 years
55
- puts amoratizer_with_extra.total_interest # $161532.46
56
- puts amoratizer.total_interest - amoratizer_with_extra.total_interest # a savings of $124,151.63
50
+ amoratizer_with_pay_extra = MortgageBuddy::Amoratizer.new(interest_rate: interest_rate,
51
+ loan_amount: loan_amount,
52
+ period: period,
53
+ extra_monthly_payment: 1000)
54
+
55
+ puts amoratizer_with_pay_extra.total_num_payments # 215 or just under 18 years
56
+ puts amoratizer_with_pay_extra.total_interest # $161053.35
57
+ puts amoratizer_30_year.total_interest - amoratizer_with_pay_extra.total_interest # a savings of $123720.21
58
+
59
+ # What if we can get a little bit lower rate on a 15 year?
60
+ amoratizer_15_year = MortgageBuddy::Amoratizer.new(interest_rate: 2.9,
61
+ loan_amount: loan_amount,
62
+ period: 180,
63
+ extra_monthly_payment: 0)
64
+ puts amoratizer_15_year.total_num_payments # 180 15 years
65
+ puts amoratizer_15_year.total_interest # $128,923.59
66
+ puts amoratizer_15_year.actual_monthly_payment # $3771.80
67
+ puts amoratizer_30_year.total_interest - amoratizer_15_year.total_interest # a savings of $155,849.97
57
68
 
58
69
 
59
70
  ```
60
71
 
61
72
  ## Development
62
73
 
63
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
74
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
64
75
 
65
76
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
66
77
 
@@ -3,6 +3,8 @@ require 'active_support/core_ext/object/blank'
3
3
  require 'mortgage_buddy/version'
4
4
  require 'mortgage_buddy/safe_num'
5
5
  require 'mortgage_buddy/monthly'
6
+ require 'mortgage_buddy/standard_rounding'
7
+ require 'mortgage_buddy/floor_rounding'
6
8
  require 'mortgage_buddy/apr_calculator'
7
9
  require 'mortgage_buddy/mortgage_cost'
8
10
  require 'mortgage_buddy/payment_plan'
@@ -10,14 +10,15 @@ module MortgageBuddy
10
10
  # [:period] Number of months of the loan. 30 yr is 360. 15 yr is 189
11
11
  # [:extra_monthly_payment] This is the extra monthly principal payment. Optional and defaults to 0
12
12
  def initialize(params={})
13
- @interest_rate = safe_float params[:interest_rate]
14
- @loan_amount = safe_float params[:loan_amount]
15
- @period = safe_int params[:period]
16
- @extra_monthly_payment = safe_float(params.fetch(:extra_monthly_payment, 0))
13
+ @interest_rate = safe_float params[:interest_rate]
14
+ @loan_amount = safe_float params[:loan_amount]
15
+ @period = safe_int params[:period]
16
+ @extra_monthly_payment = safe_float(params.fetch(:extra_monthly_payment, 0))
17
+ @interest_rounding_strategy = params[:interest_rounding_strategy]
17
18
  end
18
19
 
19
20
  def total_interest
20
- payments.inject(0){|sum,pay| sum + pay.interest }.round(2)
21
+ payments.inject(0) { |sum, pay| sum + pay.interest }.round(2)
21
22
  end
22
23
 
23
24
  # A = [i * P * (1 + i)^n] / [(1 + i)^n - 1]
@@ -30,17 +31,23 @@ module MortgageBuddy
30
31
  end
31
32
 
32
33
  def actual_monthly_payment
33
- minimum_monthly_payment + @extra_monthly_payment
34
+ (minimum_monthly_payment + @extra_monthly_payment).round(2)
34
35
  end
35
36
 
36
37
  def total_num_payments
37
38
  payments.length
38
39
  end
39
40
 
41
+ def last_monthly_payment
42
+ payments.last.payment
43
+ end
44
+
40
45
  def payments
41
- @payments ||= MortgageBuddy::PaymentPlan.build(loan_amount: self.loan_amount,
42
- monthly_payment: actual_monthly_payment,
43
- monthly_interest_rate: monthly_interest_rate)
46
+ @payments ||= MortgageBuddy::PaymentPlan.build(loan_amount: self.loan_amount,
47
+ period: self.period,
48
+ monthly_payment: actual_monthly_payment,
49
+ monthly_interest_rate: monthly_interest_rate,
50
+ interest_rounding_strategy: @interest_rounding_strategy)
44
51
  end
45
52
 
46
53
  private
@@ -0,0 +1,9 @@
1
+ module MortgageBuddy
2
+ class FloorRounding
3
+ class << self
4
+ def round(num)
5
+ (num * 100).floor.to_f / 100
6
+ end
7
+ end
8
+ end
9
+ end
@@ -45,11 +45,11 @@ module MortgageBuddy
45
45
 
46
46
  private
47
47
  def calculate_monthly_payment(amount, monthly_rate, period)
48
- amount * (monthly_rate/(1 - (1 + monthly_rate)**(-period)))
48
+ (amount * (monthly_rate/(1 - (1 + monthly_rate)**(-period)))).round(2)
49
49
  end
50
50
 
51
51
  def calculate_total_fees
52
- @fees + (@loan_amount * points/100)
52
+ (@fees + (@loan_amount * points/100)).round(2)
53
53
  end
54
54
  end
55
55
  end
@@ -7,10 +7,12 @@ module MortgageBuddy
7
7
  end
8
8
 
9
9
  def initialize(params)
10
- @loan_amount = params[:loan_amount]
11
- @monthly_payment = params[:monthly_payment]
12
- @monthly_interest_rate = params[:monthly_interest_rate]
13
- @remaining_loan_amount = @loan_amount
10
+ @loan_amount = params[:loan_amount]
11
+ @monthly_payment = params[:monthly_payment]
12
+ @monthly_interest_rate = params[:monthly_interest_rate]
13
+ @interest_rounding_strategy = params[:interest_rounding_strategy] || MortgageBuddy::StandardRounding
14
+ @period = params[:period]
15
+ @remaining_loan_amount = @loan_amount
14
16
  end
15
17
 
16
18
  def payments
@@ -20,34 +22,35 @@ module MortgageBuddy
20
22
  def build_payments
21
23
  payments = []
22
24
  payment_number = 1
23
- while @remaining_loan_amount > 0
24
- interest = next_payment_interest
25
- principal = next_payment_principal(interest)
26
- if principal >= @remaining_loan_amount
27
- difference = principal - @remaining_loan_amount
28
- principal = @remaining_loan_amount.round(2)
29
- payment = (@monthly_payment - difference).round(2)
30
- @remaining_loan_amount = 0
31
- else
32
- @remaining_loan_amount -= principal
33
- payment = @monthly_payment
34
- end
35
- payments << OpenStruct.new(payment: payment,
25
+ while @remaining_loan_amount > 0.0
26
+ interest = next_payment_interest
27
+ principal = next_payment_principal(interest, payments.length + 1)
28
+ payment = interest + principal
29
+ @remaining_loan_amount = (@remaining_loan_amount - principal).round(2)
30
+ payments << OpenStruct.new(payment: payment.round(2),
36
31
  interest: interest,
37
32
  principal: principal,
38
33
  number: payment_number,
39
- balance: @remaining_loan_amount.round(2))
34
+ balance: @remaining_loan_amount)
40
35
  payment_number += 1
41
36
  end
42
37
  payments
43
38
  end
44
39
 
45
- def next_payment_principal(interest)
46
- (@monthly_payment - interest).round(2)
40
+ def next_payment_principal(interest, payment_number)
41
+ principal = @monthly_payment - interest
42
+ if principal > @remaining_loan_amount || last_payment?(payment_number)
43
+ principal = @remaining_loan_amount
44
+ end
45
+ principal.round(2)
47
46
  end
48
47
 
49
48
  def next_payment_interest
50
- (@monthly_interest_rate * @remaining_loan_amount * 100).floor.to_f / 100
49
+ @interest_rounding_strategy.round(@monthly_interest_rate * @remaining_loan_amount)
50
+ end
51
+
52
+ def last_payment?(payment_number)
53
+ @period == payment_number
51
54
  end
52
55
  end
53
56
  end
@@ -0,0 +1,9 @@
1
+ module MortgageBuddy
2
+ class StandardRounding
3
+ class << self
4
+ def round(num)
5
+ num.round(2)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module MortgageBuddy
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
Binary file
@@ -22,6 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rspec"
23
23
  spec.add_development_dependency "rspec-its"
24
24
  spec.add_development_dependency "cucumber"
25
- spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "pry-nav"
26
26
  spec.add_dependency "activesupport"
27
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mortgage-buddy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Perry Hertler
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-20 00:00:00.000000000 Z
11
+ date: 2015-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: pry
84
+ name: pry-nav
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -129,11 +129,14 @@ files:
129
129
  - lib/mortgage_buddy.rb
130
130
  - lib/mortgage_buddy/amoratizer.rb
131
131
  - lib/mortgage_buddy/apr_calculator.rb
132
+ - lib/mortgage_buddy/floor_rounding.rb
132
133
  - lib/mortgage_buddy/monthly.rb
133
134
  - lib/mortgage_buddy/mortgage_cost.rb
134
135
  - lib/mortgage_buddy/payment_plan.rb
135
136
  - lib/mortgage_buddy/safe_num.rb
137
+ - lib/mortgage_buddy/standard_rounding.rb
136
138
  - lib/mortgage_buddy/version.rb
139
+ - mortgage-buddy-0.1.0.gem
137
140
  - mortgage-buddy.gemspec
138
141
  homepage: https://github.com/perryqh/mortgage-buddy
139
142
  licenses:
@@ -160,3 +163,4 @@ signing_key:
160
163
  specification_version: 4
161
164
  summary: Some mortgage calculation helpers
162
165
  test_files: []
166
+ has_rdoc: