Skip to content

Commit

Permalink
Merge pull request #1 from randallreedjr/add-interest-rate
Browse files Browse the repository at this point in the history
Add ability to calculate interest rate
  • Loading branch information
randallreedjr committed Mar 27, 2016
2 parents eacf7d9 + 5560843 commit 2a2309f
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 32 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,12 @@
# Changelog

## 0.1.0

* 1 minor enhancement
* Update docs, add License and Changelog
* 2 major enhancement:
* Add ability to calculate interest rate (I)

## 0.1.0

Initial project; ability to calculate present value (PV), payments (PMT), future value (FV), and number of periods (N) given other values
23 changes: 23 additions & 0 deletions LICENSE
@@ -0,0 +1,23 @@
LICENSE

The MIT License

Copyright (c) 2014-2016 Randall Reed, Jr.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
43 changes: 26 additions & 17 deletions README.md
@@ -1,25 +1,34 @@
Time Value of Money calculator
# Time Value of Money calculator

Performs financial calculatins for:
-n (number of periods)
-pv (present value)
-pmt (payment amount)
-fv (future value)
## Performs financial calculations for:
* n (number of periods)
* pv (present value)
* pmt (payment amount)
* fv (future value)
* i (interest rate)

Does not currently solve for interest rate. Only supports annuity due.
**NOTE:** Only supports annuity due.

## Usage

Usage
Initialize with values:
time_value = TimeValue.new(n, i, pv, pmt, fv)
```
time_value = TimeValue.new(n, i, pv, pmt, fv)
```

Or set values after initialization:
time_value = TimeValue.new()
time_value.n = my_n
time_value.i = my_i
time_value.pv = my_pv
time_value.pmt = my_pmt
my_fv = time_value.calc_fv()
```
time_value = TimeValue.new()
time_value.n = my_n
time_value.i = my_i
time_value.pv = my_pv
time_value.pmt = my_pmt
my_fv = time_value.calc_fv()
```

Remember to follow a convention for signs of values:
-Money being paid should have a negative value (-)
-Money being received should have a positive value (+)

* Money being paid should have a negative value (-)
* Money being received should have a positive value (+)

Failing to follow this convention may yield unexpected results
5 changes: 3 additions & 2 deletions config/environment.rb
@@ -1,3 +1,4 @@
require_relative '../lib/timevalue.rb'
require_relative '../lib/time_value.rb'
require_relative '../lib/solver.rb'
require 'rspec'
require_relative '../spec/spec_helper.rb'
require_relative '../spec/spec_helper.rb'
42 changes: 42 additions & 0 deletions lib/solver.rb
@@ -0,0 +1,42 @@
class Solver
attr_reader :time_value, :goal
attr_accessor :guess, :lower_bound, :upper_bound, :upper_cap_met

def initialize(time_value, guess = 10.00, lower_bound = 0.00, upper_bound = 10.00)
@upper_bound = upper_bound
@lower_bound = lower_bound
@guess = guess
@time_value = time_value
@goal = time_value.fv
@upper_cap_met = false
end

def solve!
iteration_count = 0
time_value.i = guess
while (upper_bound - lower_bound).round(2) > 0.01 && iteration_count < 100
iteration_count += 1
begin
result = time_value.calc_fv
rescue FloatDomainError => error
return nil
end
adjust_bounds(result)
time_value.i = guess
end
guess if iteration_count < 100
end

def adjust_bounds(result)
if result > goal
# interest rate too high
self.upper_cap_met = true
self.upper_bound = guess
elsif result < goal
# interest rate too low
self.upper_bound *= 2 unless upper_cap_met
self.lower_bound = guess
end
self.guess = ((upper_bound + lower_bound) / 2).round(2)
end
end
8 changes: 8 additions & 0 deletions lib/timevalue.rb → lib/time_value.rb
@@ -1,3 +1,6 @@
require 'byebug'
require 'solver'

class TimeValue

attr_accessor :n, :i, :pv, :pmt, :fv
Expand Down Expand Up @@ -43,4 +46,9 @@ def calc_pmt()
@pmt = (-i*(@fv+(@pv*((1+i)**n))))/(((1+i)**n)-1)
@pmt = (@pmt*100).round / 100.0
end

def calc_i(guess = 10.0)
solver = Solver.new(self, 10.00, 0.00, 10.00)
solver.solve!
end
end
29 changes: 28 additions & 1 deletion spec/timevalue_spec.rb → spec/time_value_spec.rb
Expand Up @@ -43,4 +43,31 @@
time_value.pmt = -100
expect(time_value.calc_fv).to eq(149_217.62)
end
end

it 'should calculate interest correctly when higher than guess' do
time_value.pv = -100_000
time_value.pmt = -1000.0
time_value.n = 20
time_value.fv = 1_113_330
guess = 10.00
expect(time_value.calc_i(guess)).to eq(12.41)
end

it 'should calculate interest correctly when lower than guess' do
time_value.pv = -100_000
time_value.pmt = 0.00
time_value.n = 20
time_value.fv = 500_000
guess = 10.00
expect(time_value.calc_i(guess)).to eq(8.38)
end

it 'should return an error if inputs are incorrect' do
time_value.pv = 100_000
time_value.pmt = 0
time_value.n = 20
time_value.fv = 500_000
guess = 10.00
expect(time_value.calc_i(guess)).to eq(nil)
end
end
Binary file added time_value-0.1.0.gem
Binary file not shown.
13 changes: 13 additions & 0 deletions time_value.gemspec
@@ -0,0 +1,13 @@
Gem::Specification.new do |s|
s.name = 'time_value'
s.version = '0.1.0'
s.date = '2016-03-27'
s.summary = "Time value of money financial calculations"
s.description = "Perform time value of money calculations using financial calculator variables n, i, PV, PMT, and FV"
s.authors = ["Randall Reed, Jr."]
s.email = 'randallreedjr@gmail.com'
s.add_development_dependency "rspec", '~> 3.2'
s.files = Dir.glob("{bin,lib}/**/*") + %w(LICENSE README.md CHANGELOG.md)
s.homepage = 'http://rubygems.org/gems/timevalue'
s.license = 'MIT'
end
Binary file removed timevalue-0.0.1.gem
Binary file not shown.
12 changes: 0 additions & 12 deletions timevalue.gemspec

This file was deleted.

0 comments on commit 2a2309f

Please sign in to comment.