time_value 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/LICENSE +23 -0
  4. data/README.md +34 -0
  5. data/lib/solver.rb +42 -0
  6. data/lib/time_value.rb +54 -0
  7. metadata +63 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 96e4ad82d62c670fec471ea4f8aadf88af94b5f2
4
+ data.tar.gz: d4caa002f101a1941564dbd097966a3972877a54
5
+ SHA512:
6
+ metadata.gz: e6697021a95ef94d39cc788855c7cf54fd87f032a0430534eab0226c8965b8083259821ce3c5ee094d30146a0783932248dea59fc85f05846db955e33b13a7c5
7
+ data.tar.gz: a99e9e6a7fcd828dae68f38040fd3f9dc0ec30152a751823a7aea9bbf09dc844c9f7ab97ae85f78fdcfc92836f59dbce7e80c3ce9613e36292b1728bd26759f3
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ * 1 minor enhancement
6
+ * Update docs, add License and Changelog
7
+ * 2 major enhancement:
8
+ * Add ability to calculate interest rate (I)
9
+
10
+ ## 0.1.0
11
+
12
+ Initial project; ability to calculate present value (PV), payments (PMT), future value (FV), and number of periods (N) given other values
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ LICENSE
2
+
3
+ The MIT License
4
+
5
+ Copyright (c) 2014-2016 Randall Reed, Jr.
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Time Value of Money calculator
2
+
3
+ ## Performs financial calculations for:
4
+ * n (number of periods)
5
+ * pv (present value)
6
+ * pmt (payment amount)
7
+ * fv (future value)
8
+ * i (interest rate)
9
+
10
+ **NOTE:** Only supports annuity due.
11
+
12
+ ## Usage
13
+
14
+ Initialize with values:
15
+ ```
16
+ time_value = TimeValue.new(n, i, pv, pmt, fv)
17
+ ```
18
+
19
+ Or set values after initialization:
20
+ ```
21
+ time_value = TimeValue.new()
22
+ time_value.n = my_n
23
+ time_value.i = my_i
24
+ time_value.pv = my_pv
25
+ time_value.pmt = my_pmt
26
+ my_fv = time_value.calc_fv()
27
+ ```
28
+
29
+ Remember to follow a convention for signs of values:
30
+
31
+ * Money being paid should have a negative value (-)
32
+ * Money being received should have a positive value (+)
33
+
34
+ Failing to follow this convention may yield unexpected results
data/lib/solver.rb ADDED
@@ -0,0 +1,42 @@
1
+ class Solver
2
+ attr_reader :time_value, :goal
3
+ attr_accessor :guess, :lower_bound, :upper_bound, :upper_cap_met
4
+
5
+ def initialize(time_value, guess = 10.00, lower_bound = 0.00, upper_bound = 10.00)
6
+ @upper_bound = upper_bound
7
+ @lower_bound = lower_bound
8
+ @guess = guess
9
+ @time_value = time_value
10
+ @goal = time_value.fv
11
+ @upper_cap_met = false
12
+ end
13
+
14
+ def solve!
15
+ iteration_count = 0
16
+ time_value.i = guess
17
+ while (upper_bound - lower_bound).round(2) > 0.01 && iteration_count < 100
18
+ iteration_count += 1
19
+ begin
20
+ result = time_value.calc_fv
21
+ rescue FloatDomainError => error
22
+ return nil
23
+ end
24
+ adjust_bounds(result)
25
+ time_value.i = guess
26
+ end
27
+ guess if iteration_count < 100
28
+ end
29
+
30
+ def adjust_bounds(result)
31
+ if result > goal
32
+ # interest rate too high
33
+ self.upper_cap_met = true
34
+ self.upper_bound = guess
35
+ elsif result < goal
36
+ # interest rate too low
37
+ self.upper_bound *= 2 unless upper_cap_met
38
+ self.lower_bound = guess
39
+ end
40
+ self.guess = ((upper_bound + lower_bound) / 2).round(2)
41
+ end
42
+ end
data/lib/time_value.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'byebug'
2
+ require 'solver'
3
+
4
+ class TimeValue
5
+
6
+ attr_accessor :n, :i, :pv, :pmt, :fv
7
+
8
+ def initialize(n = 0, i = 0, pv = 0.0, pmt = 0.0, fv = 0.0)
9
+ @n = n
10
+ @i = i.to_f
11
+ @pv = pv.to_f
12
+ @pmt = pmt.to_f
13
+ @fv = fv.to_f
14
+ end
15
+
16
+ #Base formula, ordinary annuity: -PV = [FV/((1+i)^n)] + (PMT/i)*[1-(1/(1+i)^n)]
17
+ def calc_pv()
18
+ i = @i / 100.0
19
+ #Initial contribution
20
+ pvf = @fv / ((1 + i) ** @n)
21
+ #Present value of annuity
22
+ pva = (@pmt/i) * (1-(1/((1+i)**@n)))
23
+ @pv = (pvf + pva) * (-1)
24
+ #Round
25
+ @pv = (@pv*100).round / 100.0
26
+ end
27
+
28
+ def calc_fv()
29
+ i = @i / 100.0
30
+ #Growth of initial contribution
31
+ fvp = @pv * ((1 + i) ** @n)
32
+ #Growth of payments
33
+ fva = @pmt * (((1 + i) ** @n)-1) / i
34
+ @fv = (fvp + fva) * (-1)
35
+ #Round
36
+ @fv = (@fv*100).round / 100.0
37
+ end
38
+
39
+ def calc_n()
40
+ i = @i / 100.0
41
+ @n = (Math.log((@pmt - (i * @fv))/(@pmt + (i * @pv)))/Math.log(1 + i)).round(0)
42
+ end
43
+
44
+ def calc_pmt()
45
+ i = @i / 100.0
46
+ @pmt = (-i*(@fv+(@pv*((1+i)**n))))/(((1+i)**n)-1)
47
+ @pmt = (@pmt*100).round / 100.0
48
+ end
49
+
50
+ def calc_i(guess = 10.0)
51
+ solver = Solver.new(self, 10.00, 0.00, 10.00)
52
+ solver.solve!
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: time_value
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Randall Reed, Jr.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ description: Perform time value of money calculations using financial calculator variables
28
+ n, i, PV, PMT, and FV
29
+ email: randallreedjr@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - LICENSE
36
+ - README.md
37
+ - lib/solver.rb
38
+ - lib/time_value.rb
39
+ homepage: http://rubygems.org/gems/timevalue
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.4.6
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Time value of money financial calculations
63
+ test_files: []