mortgage-buddy 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -27
- data/lib/mortgage_buddy.rb +2 -0
- data/lib/mortgage_buddy/amoratizer.rb +16 -9
- data/lib/mortgage_buddy/floor_rounding.rb +9 -0
- data/lib/mortgage_buddy/mortgage_cost.rb +2 -2
- data/lib/mortgage_buddy/payment_plan.rb +24 -21
- data/lib/mortgage_buddy/standard_rounding.rb +9 -0
- data/lib/mortgage_buddy/version.rb +1 -1
- data/mortgage-buddy-0.1.0.gem +0 -0
- data/mortgage-buddy.gemspec +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57d7dfa4923485c7c5c7d832249a7d655019f228
|
4
|
+
data.tar.gz: 9db923e6a6a4bf5a89064e066f4901d82fc13660
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
41
|
+
amoratizer_30_year = MortgageBuddy::Amoratizer.new(interest_rate: interest_rate,
|
42
|
+
loan_amount: loan_amount,
|
43
|
+
period: period)
|
42
44
|
|
43
|
-
puts
|
44
|
-
puts
|
45
|
-
puts
|
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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
puts
|
55
|
-
puts
|
56
|
-
|
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
|
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
|
|
data/lib/mortgage_buddy.rb
CHANGED
@@ -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
|
14
|
-
@loan_amount
|
15
|
-
@period
|
16
|
-
@extra_monthly_payment
|
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:
|
42
|
-
|
43
|
-
|
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
|
@@ -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
|
11
|
-
@monthly_payment
|
12
|
-
@monthly_interest_rate
|
13
|
-
@
|
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
|
25
|
-
principal
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
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
|
-
|
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
|
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
|
Binary file
|
data/mortgage-buddy.gemspec
CHANGED
@@ -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.
|
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-
|
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:
|