pathfinderdev-mortgage_calc 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.
data/Manifest ADDED
@@ -0,0 +1,11 @@
1
+ Manifest
2
+ Rakefile
3
+ Version.yml
4
+ features/apr.feature
5
+ features/step_definitions/apr_steps.rb
6
+ features/support/env.rb
7
+ lib/mortgage_calc.rb
8
+ lib/mortgage_calc/mortgage_util.rb
9
+ pathfinderdev-mortgage_calc.gemspec
10
+ spec/mortgage_calc/mortgage_util_spec.rb
11
+ spec/spec_helper.rb
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+ require 'spec'
5
+ require 'cucumber'
6
+ require 'lib/mortgage_calc'
7
+
8
+ require 'cucumber/rake/task'
9
+ require 'spec/rake/spectask'
10
+
11
+ Echoe.new("pathfinderdev-mortgage_calc", MortgageCalc::VERSION) do |p|
12
+ p.description = "Mortgage utilities"
13
+ p.url = "http://github.com/pathfinderdev/mortgage_calc"
14
+ p.author = "Perry Hertler"
15
+ p.email = "phertler@pathf.com"
16
+ p.ignore_pattern = ["tmp/*", "script/*, .idea/*"]
17
+ p.development_dependencies = []
18
+ end
19
+
20
+ Dir["#File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
21
+
22
+ spec_files = Rake::FileList["spec/**/*_spec.rb"]
23
+
24
+ desc "Run specs"
25
+ Spec::Rake::SpecTask.new do |t|
26
+ t.spec_files = spec_files
27
+ t.spec_opts = ["-c"]
28
+ end
29
+
30
+ Cucumber::Rake::Task.new(:features) do |t|
31
+ t.cucumber_opts = "features --format progress"
32
+ end
33
+
34
+ task :default => [:spec, :features]
35
+
36
+
37
+
data/Version.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 1
@@ -0,0 +1,18 @@
1
+ Feature Calculate APR
2
+ In order to show sorted APR search results
3
+ As a person navigating OMT
4
+ I want to see correct APRs
5
+
6
+ Scenario Outline: Calculate APR
7
+ Given <loan_amount>, <fees>, <points>, <rate>, <period>
8
+ Then the resultant apr should be <apr>
9
+
10
+ Scenarios: with APR fields
11
+ | loan_amount | fees | points | rate | period | apr |
12
+ | 125000 | 5000 | 0 | 6.5 | 360 | 6.881 |
13
+ | 125000 | 5000 | -1.25 | 6.5 | 360 | 6.881 |
14
+ | 400000 | 1200 | 0 | 5.25 | 180 | 5.296 |
15
+ | 125000 | 811 | 0.375 | 6.125 | 360 | 6.221 |
16
+ | 125000 | 811 | -0.375 | 6.5 | 360 | 6.562 |
17
+ | 100000 | 1000 | 0 | 7.0 | 360 | 7.099 |
18
+ | 100000 | 0 | 0 | 7.0 | 360 | 7.0 |
@@ -0,0 +1,7 @@
1
+ Given /^(.*), (.*), (.*), (.*), (.*)$/ do |loan_amount, fees, points, rate, period|
2
+ @mortgage_util = MortgageCalc::MortgageUtil.new(Integer(loan_amount), Float(rate), Float(period), Float(fees), Float(points))
3
+ end
4
+
5
+ Then /^the resultant apr should be (.*)$/ do |apr_expected|
6
+ Float(apr_expected).should be_close(@mortgage_util.apr, 0.001)
7
+ end
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__),"..","..","lib")
2
+ require 'mortgage_calc'
3
+ require 'spec/expectations'
4
+ require 'spec/matchers'
5
+ require 'spec/stubs/cucumber'
@@ -0,0 +1,9 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ require 'yaml'
3
+
4
+ module MortgageCalc
5
+ version = YAML.load_file(File.dirname(__FILE__) + "/../VERSION.yml")
6
+ VERSION = "#{version[:major]}.#{version[:minor]}.#{version[:patch]}"
7
+ end
8
+
9
+ require 'mortgage_calc/mortgage_util'
@@ -0,0 +1,55 @@
1
+ module MortgageCalc
2
+ class MortgageUtil
3
+ attr_accessor :loan_amount, :interest_rate, :period, :lender_fee, :points
4
+
5
+ def initialize(loan_amount, interest_rate, period=360, lender_fee=0, points=0)
6
+ self.loan_amount = loan_amount
7
+ self.interest_rate = interest_rate
8
+ self.period = period
9
+ self.lender_fee = lender_fee
10
+ self.points = points
11
+ end
12
+
13
+ def apr
14
+ payment_with_fees = calculate_monthly_payment(self.loan_amount + total_fees, monthly_interst_rate, self.period)
15
+ calculate_apr_with_newton_raphson(self.period, payment_with_fees, self.loan_amount, monthly_interst_rate + 1) * 12 * 100
16
+ end
17
+
18
+ def monthly_payment
19
+ calculate_monthly_payment(self.loan_amount, monthly_interst_rate, self.period)
20
+ end
21
+
22
+ def total_fees
23
+ buyer_points = self.points <= 0 ? 0 : self.points
24
+ self.lender_fee + (self.loan_amount * buyer_points.abs/100)
25
+ end
26
+
27
+ private
28
+ def monthly_interst_rate
29
+ self.interest_rate / 100 / 12
30
+ end
31
+
32
+ def calculate_monthly_payment(amount, monthly_rate, period)
33
+ amount * (monthly_rate/(1 - (1 + monthly_rate)**(-period)))
34
+ end
35
+
36
+ # solves APR
37
+ # where a = APR/1200, N = period, P = monthly payment, C = loan_amount
38
+ # calculate APR uses the Newton-Raphson to find the root (the value for 'a' that makes f(a) = 0)
39
+ # for best performance call this with 'start'= interest rate
40
+ def calculate_apr_with_newton_raphson(periods, monthly_payment, loan_amount, start=1.1)
41
+ payment_ratio = monthly_payment / loan_amount
42
+ f = lambda {|k| (k**(periods + 1) - (k**periods * (payment_ratio + 1)) + payment_ratio)}
43
+ f_slope = lambda { |k| ((periods + 1) * k**periods) - (periods * (payment_ratio + 1) * k**(periods - 1))}
44
+
45
+ k_plus_one = start
46
+ k = 0.0
47
+
48
+ while ((k - 1) * 100000).to_f.floor != ((k_plus_one - 1) * 100000).to_f.floor
49
+ k = k_plus_one
50
+ k_plus_one = k - f.call(k) / f_slope.call(k)
51
+ end
52
+ (k_plus_one - 1).to_f
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{pathfinderdev-mortgage_calc}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Perry Hertler"]
9
+ s.date = %q{2010-02-12}
10
+ s.description = %q{Mortgage utilities}
11
+ s.email = %q{phertler@pathf.com}
12
+ s.extra_rdoc_files = ["lib/mortgage_calc.rb", "lib/mortgage_calc/mortgage_util.rb"]
13
+ s.files = ["Manifest", "Rakefile", "Version.yml", "features/apr.feature", "features/step_definitions/apr_steps.rb", "features/support/env.rb", "lib/mortgage_calc.rb", "lib/mortgage_calc/mortgage_util.rb", "pathfinderdev-mortgage_calc.gemspec", "spec/mortgage_calc/mortgage_util_spec.rb", "spec/spec_helper.rb"]
14
+ s.homepage = %q{http://github.com/pathfinderdev/mortgage_calc}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Pathfinderdev-mortgage_calc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{pathfinderdev-mortgage_calc}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Mortgage utilities}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ module MortgageCalc
4
+ describe MortgageUtil do
5
+ def assert_monthly_apr_payment_matches(loan_amount, rate, period, fee, points)
6
+ mortgage_util = MortgageUtil.new(loan_amount, rate, period, fee, points)
7
+ monthly_payment_with_fees = MortgageUtil.new(loan_amount + mortgage_util.total_fees, rate, period, 0, 0).monthly_payment
8
+ monthly_payment_from_apr = MortgageUtil.new(loan_amount, mortgage_util.apr, period, 0, 0).monthly_payment
9
+ monthly_payment_with_fees.should be_close(monthly_payment_from_apr, 0.01)
10
+ end
11
+
12
+ context "with valid MortgageUtil" do
13
+ before(:all) do
14
+ @mortgage_util = MortgageUtil.new(100000, 6.0, 360, 1200, 1.25)
15
+ @mortgage_util_with_apr_as_rate = MortgageUtil.new(100000, @mortgage_util.apr, 360, 1200, 1.25)
16
+ end
17
+ it "should have proper monthly interest rate" do
18
+ @mortgage_util.send(:monthly_interst_rate).should == 0.005
19
+ end
20
+ it "should have proper monthly payment" do
21
+ @mortgage_util.monthly_payment.should be_close(599.55, 0.001)
22
+ end
23
+ it "should have proper total fees" do
24
+ @mortgage_util.total_fees.should be_close(2450, 0.001)
25
+ end
26
+ it "should have proper APR" do
27
+ @mortgage_util.apr.should be_close(6.22726, 0.00001)
28
+ end
29
+ end
30
+ it "should calculate original monthly payment from APR" do
31
+ assert_monthly_apr_payment_matches(300000, 6.5, 360, 1200, 1.25)
32
+ assert_monthly_apr_payment_matches(300000, 6.5, 360, 0, 0)
33
+ assert_monthly_apr_payment_matches(400000, 1.1, 180, 1200, 1.25)
34
+ assert_monthly_apr_payment_matches(300000, 6.5, 360, 0, 7.25)
35
+ assert_monthly_apr_payment_matches(300000, 6.5, 360, 10000, 7.25)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__),"..","lib")
2
+ require 'spec'
3
+ require 'mortgage_calc'
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pathfinderdev-mortgage_calc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Perry Hertler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-12 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Mortgage utilities
17
+ email: phertler@pathf.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/mortgage_calc.rb
24
+ - lib/mortgage_calc/mortgage_util.rb
25
+ files:
26
+ - Manifest
27
+ - Rakefile
28
+ - Version.yml
29
+ - features/apr.feature
30
+ - features/step_definitions/apr_steps.rb
31
+ - features/support/env.rb
32
+ - lib/mortgage_calc.rb
33
+ - lib/mortgage_calc/mortgage_util.rb
34
+ - pathfinderdev-mortgage_calc.gemspec
35
+ - spec/mortgage_calc/mortgage_util_spec.rb
36
+ - spec/spec_helper.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/pathfinderdev/mortgage_calc
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --line-numbers
44
+ - --inline-source
45
+ - --title
46
+ - Pathfinderdev-mortgage_calc
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "1.2"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project: pathfinderdev-mortgage_calc
64
+ rubygems_version: 1.3.5
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Mortgage utilities
68
+ test_files: []
69
+