refinance 0.0.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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +10 -0
- data/lib/refinance/annuities.rb +99 -0
- data/lib/refinance/version.rb +3 -0
- data/lib/refinance.rb +5 -0
- data/refinance.gemspec +24 -0
- data/test/bigdecimal_annuities_test.rb +109 -0
- data/test/float_annuities_test.rb +108 -0
- data/test/refinance_test.rb +12 -0
- metadata +96 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 reInteractive
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Refinance
|
2
|
+
|
3
|
+
Refinance is a Ruby gem that provides a collection of finance algorithms.
|
4
|
+
Currently, it contains algorithms for calculating the properties of ordinary
|
5
|
+
annuities: principal, interest rate, number of payment periods, and payment
|
6
|
+
amount.
|
7
|
+
|
8
|
+
The algorithms are simple rather than fast. At present, they deal only with
|
9
|
+
_annuities immediate_ (in which the interest is accumulated _before_ the
|
10
|
+
payment), not _annuities due_ (in which the interest is accumulated _after_ the
|
11
|
+
payment). There are many opportunities for extension and improvement.
|
12
|
+
|
13
|
+
## Requirements
|
14
|
+
|
15
|
+
This library requires Ruby 1.9.3 or newer. (However, it will work with Ruby
|
16
|
+
1.9.2 if you only use Float, not BigDecimal, for floating-point values.)
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
gem 'refinance'
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install refinance
|
31
|
+
|
32
|
+
## Contributing
|
33
|
+
|
34
|
+
1. Fork it
|
35
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
36
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
37
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
38
|
+
5. Create new Pull Request
|
39
|
+
|
40
|
+
## Authorship and copyright information
|
41
|
+
|
42
|
+
This software was written by [reInteractive](http://reinteractive.net/), a
|
43
|
+
software consulting company in Sydney, Australia. It is distributed under the
|
44
|
+
MIT License; see LICENSE.txt for details.
|
45
|
+
|
46
|
+
## Acknowledgements
|
47
|
+
|
48
|
+
Thanks to Stan Brown for his paper _[Loan or Investment
|
49
|
+
Formulas](http://oakroadsystems.com/math/loan.htm)_. It is an excellent
|
50
|
+
introduction to the mathematics of annuities, and we used some of its examples
|
51
|
+
as test cases.
|
data/Rakefile
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module Refinance
|
2
|
+
|
3
|
+
##
|
4
|
+
# This module contains methods for calculating the basic properties of
|
5
|
+
# annuities. Annuities are assumed to be an annuities immediate (that is,
|
6
|
+
# interest is accumulated before the payment).
|
7
|
+
#
|
8
|
+
# The floating-point numbers you pass in as arguments can be instances of
|
9
|
+
# Float or BigDecimal. Actually, thanks to duck typing, they can be any
|
10
|
+
# objects that support the necessary operations.
|
11
|
+
#
|
12
|
+
module Annuities
|
13
|
+
|
14
|
+
##
|
15
|
+
# Determine an annuity's interest rate over some period, given:
|
16
|
+
#
|
17
|
+
# * Periodic payment amount
|
18
|
+
# * Number of payment periods
|
19
|
+
# * Principal
|
20
|
+
#
|
21
|
+
# This has no closed-form solution, so the answer is iteratively
|
22
|
+
# approximated with the Newton-Raphson method. After each improvement, the
|
23
|
+
# guess will be rounded; _max_decimals_ is the number of decimal places to
|
24
|
+
# keep (if you set this high, the algorithm will be slow). _max_iterations_
|
25
|
+
# is the maximum number of iterations that will be attempted. It will stop
|
26
|
+
# iterating if the last improvement was less than _precision_ in magnitude.
|
27
|
+
#
|
28
|
+
def self.interest_rate(payment, periods, principal, initial_guess = 0.1,
|
29
|
+
precision = 0.0001, max_decimals = 8, max_iterations = 10)
|
30
|
+
guess = initial_guess
|
31
|
+
|
32
|
+
max_iterations.times do
|
33
|
+
new_guess = improve_interest_rate(payment, periods, principal, guess).
|
34
|
+
round(max_decimals)
|
35
|
+
difference = (guess - new_guess).abs
|
36
|
+
guess = new_guess
|
37
|
+
break if difference < precision
|
38
|
+
end
|
39
|
+
|
40
|
+
guess
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Iteratively improve an approximated interest rate for an annuity using
|
45
|
+
# the Newton-Raphson method. This method is used by ::interest_rate.
|
46
|
+
#
|
47
|
+
def self.improve_interest_rate(payment, periods, principal, guess)
|
48
|
+
top = payment - (payment * ((guess + 1) ** -periods)) -
|
49
|
+
(principal * guess)
|
50
|
+
bottom = (periods * payment * ((guess + 1) ** (-periods - 1))) -
|
51
|
+
principal
|
52
|
+
guess - (top / bottom)
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Determine an annuity's periodic payment amount, given:
|
57
|
+
#
|
58
|
+
# * Interest rate over a period
|
59
|
+
# * Number of payment periods
|
60
|
+
# * Principal
|
61
|
+
#
|
62
|
+
def self.payment(interest_rate, periods, principal)
|
63
|
+
(interest_rate * principal) / (1 - ((interest_rate + 1) ** -periods))
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Determine the number of payment periods for an annuity, given:
|
68
|
+
#
|
69
|
+
# * Interest rate over a period
|
70
|
+
# * Periodic payment amount
|
71
|
+
# * Principal
|
72
|
+
#
|
73
|
+
def self.periods(interest_rate, payment, principal)
|
74
|
+
-Math.log(1 - ((interest_rate * principal) / payment)) /
|
75
|
+
Math.log(interest_rate + 1)
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Determine an annuity's principal, given:
|
80
|
+
#
|
81
|
+
# * Interest rate over a period
|
82
|
+
# * Periodic payment amount
|
83
|
+
# * Number of payment periods
|
84
|
+
#
|
85
|
+
def self.principal(interest_rate, payment, periods)
|
86
|
+
(payment / interest_rate) * (1 - ((interest_rate + 1) ** -periods))
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Determines the effective interest rate, given:
|
91
|
+
#
|
92
|
+
# * The nominal annual interest rate
|
93
|
+
# * The number of compounding periods per year
|
94
|
+
#
|
95
|
+
def self.effective_interest_rate(nair, cppy)
|
96
|
+
(((nair / cppy) + 1) ** cppy) - 1
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/refinance.rb
ADDED
data/refinance.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'refinance/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "refinance"
|
8
|
+
gem.version = Refinance::VERSION
|
9
|
+
gem.authors = ["reInteractive"]
|
10
|
+
gem.email = ["enquiries@reinteractive.net"]
|
11
|
+
gem.description = %q{A collection of finance algorithms related to annuities.}
|
12
|
+
gem.summary = %q{Simple annuity algorithms}
|
13
|
+
gem.homepage = "https://github.com/reinteractive-open/refinance"
|
14
|
+
gem.license = "MIT"
|
15
|
+
gem.required_ruby_version = ">= 1.9.3"
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rake', '0.9.2.2'
|
23
|
+
gem.add_development_dependency 'minitest', '3.5.0'
|
24
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'bigdecimal'
|
3
|
+
require 'refinance'
|
4
|
+
|
5
|
+
class BigDecimalAnnuitiesTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_improve_interest_rate
|
8
|
+
# Based on Example 6 in http://oakroadsystems.com/math/loan.htm .
|
9
|
+
payment = BigDecimal.new('291')
|
10
|
+
periods = BigDecimal.new('48')
|
11
|
+
principal = BigDecimal.new('11200')
|
12
|
+
guess = BigDecimal.new('0.01')
|
13
|
+
|
14
|
+
expected = BigDecimal.new('0.0094295242')
|
15
|
+
actual = Refinance::Annuities.improve_interest_rate(payment, periods,
|
16
|
+
principal, guess)
|
17
|
+
|
18
|
+
assert_in_delta expected, actual, BigDecimal.new('0.00000001')
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_interest_rate_stops_if_improvement_is_small
|
22
|
+
# Based on Example 6 in http://oakroadsystems.com/math/loan.htm .
|
23
|
+
payment = BigDecimal.new('291')
|
24
|
+
periods = BigDecimal.new('48')
|
25
|
+
principal = BigDecimal.new('11200')
|
26
|
+
guess = BigDecimal.new('0.01')
|
27
|
+
imprecision = BigDecimal.new('0.5')
|
28
|
+
|
29
|
+
expected = BigDecimal.new('0.0094295242')
|
30
|
+
actual = Refinance::Annuities.interest_rate(payment, periods, principal,
|
31
|
+
guess, imprecision)
|
32
|
+
|
33
|
+
assert_in_delta expected, actual, BigDecimal.new('0.00000001')
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_interest_rate_stops_if_max_iterations_reached
|
37
|
+
extreme_precision = BigDecimal.new('0')
|
38
|
+
guess = BigDecimal.new('0.01')
|
39
|
+
|
40
|
+
expected = guess
|
41
|
+
actual = Refinance::Annuities.interest_rate(0, 0, 0, guess,
|
42
|
+
extreme_precision, 1, 0)
|
43
|
+
|
44
|
+
assert_equal expected, actual
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_interest_rate_does_multiple_iterations
|
48
|
+
# Based on Example 6 in http://oakroadsystems.com/math/loan.htm .
|
49
|
+
payment = BigDecimal.new('291')
|
50
|
+
periods = BigDecimal.new('48')
|
51
|
+
principal = BigDecimal.new('11200')
|
52
|
+
guess = BigDecimal.new('0.01')
|
53
|
+
extreme_precision = BigDecimal.new('0')
|
54
|
+
max_iterations = 4
|
55
|
+
|
56
|
+
expected = BigDecimal.new('0.0094007411')
|
57
|
+
actual = Refinance::Annuities.interest_rate(payment, periods, principal,
|
58
|
+
guess, extreme_precision, 10, 4)
|
59
|
+
|
60
|
+
assert_in_delta expected, actual, BigDecimal.new('0.0000000001')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_payment
|
64
|
+
# Based on Example 2 in http://oakroadsystems.com/math/loan.htm .
|
65
|
+
interest_rate = BigDecimal.new('0.0065')
|
66
|
+
periods = BigDecimal.new('360')
|
67
|
+
principal = BigDecimal.new('225000')
|
68
|
+
|
69
|
+
expected = BigDecimal.new('1619.708627')
|
70
|
+
actual = Refinance::Annuities.payment(interest_rate, periods, principal)
|
71
|
+
|
72
|
+
assert_in_delta expected, actual, BigDecimal.new('0.000001')
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_periods
|
76
|
+
# Based on Example 3 in http://oakroadsystems.com/math/loan.htm .
|
77
|
+
interest_rate = BigDecimal.new('0.005')
|
78
|
+
payment = BigDecimal.new('100')
|
79
|
+
principal = BigDecimal.new('3500')
|
80
|
+
|
81
|
+
expected = BigDecimal.new('38.57')
|
82
|
+
actual = Refinance::Annuities.periods(interest_rate, payment, principal)
|
83
|
+
|
84
|
+
assert_in_delta expected, actual, BigDecimal.new('0.01')
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_principal
|
88
|
+
# Based on Example 5 in http://oakroadsystems.com/math/loan.htm .
|
89
|
+
interest_rate = BigDecimal.new('0.014083')
|
90
|
+
payment = BigDecimal.new('60')
|
91
|
+
periods = BigDecimal.new('36')
|
92
|
+
|
93
|
+
expected = BigDecimal.new('1685.26') # Example fudges to 1685.25.
|
94
|
+
actual = Refinance::Annuities.principal(interest_rate, payment, periods)
|
95
|
+
|
96
|
+
assert_in_delta expected, actual, BigDecimal.new('0.01')
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_effective_interest_rate
|
100
|
+
nominal_annual_interest_rate = BigDecimal.new('0.1')
|
101
|
+
compounding_periods_per_year = BigDecimal.new('12')
|
102
|
+
|
103
|
+
expected = BigDecimal.new('0.10471')
|
104
|
+
actual = Refinance::Annuities.effective_interest_rate(
|
105
|
+
nominal_annual_interest_rate, compounding_periods_per_year)
|
106
|
+
|
107
|
+
assert_in_delta expected, actual, BigDecimal.new('0.00001')
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'refinance'
|
3
|
+
|
4
|
+
class FloatAnnuitiesTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def test_improve_interest_rate
|
7
|
+
# Based on Example 6 in http://oakroadsystems.com/math/loan.htm .
|
8
|
+
payment = 291.0
|
9
|
+
periods = 48.0
|
10
|
+
principal = 11200.0
|
11
|
+
guess = 0.01
|
12
|
+
|
13
|
+
expected = 0.0094295242
|
14
|
+
actual = Refinance::Annuities.improve_interest_rate(payment, periods,
|
15
|
+
principal, guess)
|
16
|
+
|
17
|
+
assert_in_delta expected, actual, 0.00000001
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_interest_rate_stops_if_improvement_is_small
|
21
|
+
# Based on Example 6 in http://oakroadsystems.com/math/loan.htm .
|
22
|
+
payment = 291.0
|
23
|
+
periods = 48.0
|
24
|
+
principal = 11200.0
|
25
|
+
guess = 0.01
|
26
|
+
imprecision = 0.5
|
27
|
+
|
28
|
+
expected = 0.0094295242
|
29
|
+
actual = Refinance::Annuities.interest_rate(payment, periods, principal,
|
30
|
+
guess, imprecision)
|
31
|
+
|
32
|
+
assert_in_delta expected, actual, 0.00000001
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_interest_rate_stops_if_max_iterations_reached
|
36
|
+
extreme_precision = 0.0
|
37
|
+
guess = 0.01
|
38
|
+
|
39
|
+
expected = guess
|
40
|
+
actual = Refinance::Annuities.interest_rate(0, 0, 0, guess,
|
41
|
+
extreme_precision, 1, 0)
|
42
|
+
|
43
|
+
assert_equal expected, actual
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_interest_rate_does_multiple_iterations
|
47
|
+
# Based on Example 6 in http://oakroadsystems.com/math/loan.htm .
|
48
|
+
payment = 291.0
|
49
|
+
periods = 48.0
|
50
|
+
principal = 11200.0
|
51
|
+
guess = 0.01
|
52
|
+
extreme_precision = 0.0
|
53
|
+
max_iterations = 4
|
54
|
+
|
55
|
+
expected = 0.0094007411
|
56
|
+
actual = Refinance::Annuities.interest_rate(payment, periods, principal,
|
57
|
+
guess, extreme_precision, 10, 4)
|
58
|
+
|
59
|
+
assert_in_delta expected, actual, 0.0000000001
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_payment
|
63
|
+
# Based on Example 2 in http://oakroadsystems.com/math/loan.htm .
|
64
|
+
interest_rate = 0.0065
|
65
|
+
periods = 360.0
|
66
|
+
principal = 225000.0
|
67
|
+
|
68
|
+
expected = 1619.708627
|
69
|
+
actual = Refinance::Annuities.payment(interest_rate, periods, principal)
|
70
|
+
|
71
|
+
assert_in_delta expected, actual, 0.000001
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_periods
|
75
|
+
# Based on Example 3 in http://oakroadsystems.com/math/loan.htm .
|
76
|
+
interest_rate = 0.005
|
77
|
+
payment = 100.0
|
78
|
+
principal = 3500.0
|
79
|
+
|
80
|
+
expected = 38.57
|
81
|
+
actual = Refinance::Annuities.periods(interest_rate, payment, principal)
|
82
|
+
|
83
|
+
assert_in_delta expected, actual, 0.01
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_principal
|
87
|
+
# Based on Example 5 in http://oakroadsystems.com/math/loan.htm .
|
88
|
+
interest_rate = 0.014083
|
89
|
+
payment = 60.0
|
90
|
+
periods = 36.0
|
91
|
+
|
92
|
+
expected = 1685.26 # Example fudges to 1685.25.
|
93
|
+
actual = Refinance::Annuities.principal(interest_rate, payment, periods)
|
94
|
+
|
95
|
+
assert_in_delta expected, actual, 0.01
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_effective_interest_rate
|
99
|
+
nominal_annual_interest_rate = 0.1
|
100
|
+
compounding_periods_per_year = 12.0
|
101
|
+
|
102
|
+
expected = 0.10471
|
103
|
+
actual = Refinance::Annuities.effective_interest_rate(
|
104
|
+
nominal_annual_interest_rate, compounding_periods_per_year)
|
105
|
+
|
106
|
+
assert_in_delta expected, actual, 0.00001
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'refinance'
|
3
|
+
|
4
|
+
class RefinanceTest < MiniTest::Unit::TestCase
|
5
|
+
def test_refinance_is_a_module
|
6
|
+
assert_kind_of Module, ::Refinance
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_version_is_a_string
|
10
|
+
assert_kind_of String, ::Refinance::VERSION
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: refinance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- reInteractive
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.2.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: minitest
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.5.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.5.0
|
46
|
+
description: A collection of finance algorithms related to annuities.
|
47
|
+
email:
|
48
|
+
- enquiries@reinteractive.net
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/refinance.rb
|
59
|
+
- lib/refinance/annuities.rb
|
60
|
+
- lib/refinance/version.rb
|
61
|
+
- refinance.gemspec
|
62
|
+
- test/bigdecimal_annuities_test.rb
|
63
|
+
- test/float_annuities_test.rb
|
64
|
+
- test/refinance_test.rb
|
65
|
+
homepage: https://github.com/reinteractive-open/refinance
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.9.3
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
hash: 803431032426501235
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.24
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Simple annuity algorithms
|
93
|
+
test_files:
|
94
|
+
- test/bigdecimal_annuities_test.rb
|
95
|
+
- test/float_annuities_test.rb
|
96
|
+
- test/refinance_test.rb
|