pathfinderdev-mortgage_calc 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
+