exonio 0.4.1 → 0.5.4
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.
- checksums.yaml +5 -5
- data/.travis.yml +2 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +22 -24
- data/README.md +39 -2
- data/exonio.gemspec +1 -1
- data/lib/exonio.rb +10 -2
- data/lib/exonio/financial.rb +43 -2
- data/lib/exonio/helpers/irr_helper.rb +28 -0
- data/lib/exonio/statistical.rb +41 -0
- data/lib/exonio/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2177008fa8ad1fce23bd78efe356f146ab94350acb804eacc6fbdf7cf0b73756
|
4
|
+
data.tar.gz: a8a144747cec2755ae8c6739b91b8a4cc8eee4630ac6c950147c2eca260d5711
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74c8699b45184bcee100bda0aacf58f526461a02f4904e728ab9d1c2f4c3822a30fd19ea5fdff3de8c7f325eded5428e0946e2f243d15515c008181958404052
|
7
|
+
data.tar.gz: 170be11052472cdc4ed37f11bd6821a5f3273b44fd3e8374a52502918bb6d84a67f2c6e4483d35626533851852abee7e2426d04dfc1d89dbd00331d4a16c9131
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.5.4
|
4
|
+
|
5
|
+
* Fix zero interest rate (#18)
|
6
|
+
* Remove BigDecimal.new deprecation warning (#17)
|
7
|
+
|
8
|
+
## 0.5.3
|
9
|
+
|
10
|
+
* Fix error on IRR function
|
11
|
+
|
12
|
+
## 0.5.2
|
13
|
+
|
14
|
+
* Fix the IRR method
|
15
|
+
|
16
|
+
## 0.5.1
|
17
|
+
|
18
|
+
* Fix the FloatDomainError exception
|
19
|
+
|
20
|
+
## 0.5.0
|
21
|
+
|
22
|
+
* Implements `irr` and `npv` method
|
23
|
+
|
24
|
+
## 0.4.1
|
25
|
+
|
26
|
+
* Fix infinite loop with big scale on `rate` method
|
27
|
+
|
3
28
|
## 0.4.0
|
4
29
|
|
5
30
|
* Implements `rate` method
|
data/Gemfile.lock
CHANGED
@@ -1,37 +1,35 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
exonio (0.4
|
4
|
+
exonio (0.5.4)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
byebug (8.2.
|
10
|
-
coderay (1.1.
|
11
|
-
diff-lcs (1.
|
12
|
-
method_source (0.
|
13
|
-
pry (0.
|
14
|
-
coderay (~> 1.1
|
15
|
-
method_source (~> 0
|
16
|
-
slop (~> 3.4)
|
9
|
+
byebug (8.2.5)
|
10
|
+
coderay (1.1.2)
|
11
|
+
diff-lcs (1.3)
|
12
|
+
method_source (1.0.0)
|
13
|
+
pry (0.13.1)
|
14
|
+
coderay (~> 1.1)
|
15
|
+
method_source (~> 1.0)
|
17
16
|
pry-byebug (3.3.0)
|
18
17
|
byebug (~> 8.0)
|
19
18
|
pry (~> 0.10)
|
20
|
-
rake (
|
21
|
-
rspec (3.
|
22
|
-
rspec-core (~> 3.
|
23
|
-
rspec-expectations (~> 3.
|
24
|
-
rspec-mocks (~> 3.
|
25
|
-
rspec-core (3.
|
26
|
-
rspec-support (~> 3.
|
27
|
-
rspec-expectations (3.
|
19
|
+
rake (13.0.1)
|
20
|
+
rspec (3.9.0)
|
21
|
+
rspec-core (~> 3.9.0)
|
22
|
+
rspec-expectations (~> 3.9.0)
|
23
|
+
rspec-mocks (~> 3.9.0)
|
24
|
+
rspec-core (3.9.2)
|
25
|
+
rspec-support (~> 3.9.3)
|
26
|
+
rspec-expectations (3.9.2)
|
28
27
|
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
-
rspec-support (~> 3.
|
30
|
-
rspec-mocks (3.
|
28
|
+
rspec-support (~> 3.9.0)
|
29
|
+
rspec-mocks (3.9.1)
|
31
30
|
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
-
rspec-support (~> 3.
|
33
|
-
rspec-support (3.
|
34
|
-
slop (3.6.0)
|
31
|
+
rspec-support (~> 3.9.0)
|
32
|
+
rspec-support (3.9.3)
|
35
33
|
|
36
34
|
PLATFORMS
|
37
35
|
ruby
|
@@ -40,8 +38,8 @@ DEPENDENCIES
|
|
40
38
|
bundler (~> 1.11)
|
41
39
|
exonio!
|
42
40
|
pry-byebug (~> 3.3.0)
|
43
|
-
rake (~>
|
41
|
+
rake (~> 13.0)
|
44
42
|
rspec (~> 3.0)
|
45
43
|
|
46
44
|
BUNDLED WITH
|
47
|
-
1.
|
45
|
+
1.17.2
|
data/README.md
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
This gem brings some useful Excel formulas to Ruby. For now, it just has
|
4
4
|
financial formulas, but could have more (like statistical formulas) in the future.
|
5
5
|
|
6
|
+
[](https://badge.fury.io/rb/exonio)
|
7
|
+
[](https://travis-ci.org/Noverde/exonio)
|
8
|
+
|
6
9
|
## Installation
|
7
10
|
|
8
11
|
Add this line to your application's Gemfile:
|
@@ -43,6 +46,19 @@ By convention, the negative sign represents cash flow out (i.e. money not
|
|
43
46
|
available today). Thus, saving $100 a month at 5% annual interest leads
|
44
47
|
to $15,692.93 available to spend in 10 years.
|
45
48
|
|
49
|
+
### IRR
|
50
|
+
|
51
|
+
Suppose one invests 100 units and then makes the following withdrawals at regular (fixed)
|
52
|
+
intervals: 39, 59, 55, 20. Assuming the ending value is 0, one's 100 unit investment
|
53
|
+
yields 173 units; however, due to the combination of compounding and the periodic
|
54
|
+
withdrawals, the "average" rate of return is neither simply 0.73/4 nor (1.73)^0.25-1.
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
Exonio.irr([-100, 39, 59, 55, 20]) # ==> 0.28095
|
58
|
+
```
|
59
|
+
|
60
|
+
So, the internal rate of return is 28.09%
|
61
|
+
|
46
62
|
### IPMT
|
47
63
|
|
48
64
|
What is the interest part of a payment in the 8th period (i.e., 8th month),
|
@@ -65,6 +81,14 @@ Exonio.nper(0.07 / 12, -150, 8000) # ==> 64.07334877066185
|
|
65
81
|
|
66
82
|
So, over 64 months would be required to pay off the loan.
|
67
83
|
|
84
|
+
### NPV
|
85
|
+
|
86
|
+
Calculates the Net Present Value of an investment
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
Exonio.npv(0.281, [-100, 39, 59, 55, 29]) # ==> -0.00661872883563408
|
90
|
+
```
|
91
|
+
|
68
92
|
### PMT
|
69
93
|
|
70
94
|
What is the monthly payment needed to pay off a $200,000 loan in 15
|
@@ -103,6 +127,20 @@ Exonio.rate(12 * 3, 2_500, -50_000) # ==> 0.036006853458478955
|
|
103
127
|
|
104
128
|
So, the rate applied is 3.60%.
|
105
129
|
|
130
|
+
## Statistical formulas
|
131
|
+
|
132
|
+
### Sum
|
133
|
+
```ruby
|
134
|
+
Exonio.sum([1, 2, 3, 4, 5]) # ==> 15
|
135
|
+
```
|
136
|
+
### Mean
|
137
|
+
```ruby
|
138
|
+
Exonio.mean([1, 2, 3, 4, 5]) # ==> 3.0
|
139
|
+
```
|
140
|
+
### Median
|
141
|
+
```ruby
|
142
|
+
Exonio.median([1, 2, 3, 6, 5, 4]) # ==> 3.5
|
143
|
+
```
|
106
144
|
## TODO
|
107
145
|
|
108
146
|
There's a lot of formulas to be implemented, including:
|
@@ -113,9 +151,7 @@ There's a lot of formulas to be implemented, including:
|
|
113
151
|
* AMORLINC
|
114
152
|
* DB
|
115
153
|
* DDB
|
116
|
-
* IRR
|
117
154
|
* MIRR
|
118
|
-
* NPV
|
119
155
|
* PPMT
|
120
156
|
* SLN
|
121
157
|
* SYD
|
@@ -139,3 +175,4 @@ Exonio is released under the MIT License.
|
|
139
175
|
A special thanks goes to the python [NumPy project](http://www.numpy.org/), which was the source for most
|
140
176
|
of the formulas.
|
141
177
|
|
178
|
+
|
data/exonio.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.11"
|
22
|
-
spec.add_development_dependency "rake", "~>
|
22
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
24
24
|
spec.add_development_dependency "pry-byebug", "~> 3.3.0"
|
25
25
|
end
|
data/lib/exonio.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'bigdecimal/newton'
|
3
|
+
require "bigdecimal/util"
|
4
|
+
|
5
|
+
require 'exonio/version'
|
6
|
+
require 'exonio/financial'
|
7
|
+
require 'exonio/statistical'
|
8
|
+
require 'exonio/helpers/irr_helper'
|
3
9
|
|
4
10
|
module Exonio
|
11
|
+
extend Newton
|
5
12
|
extend Financial
|
13
|
+
extend Statistical
|
6
14
|
end
|
data/lib/exonio/financial.rb
CHANGED
@@ -50,8 +50,8 @@ module Exonio
|
|
50
50
|
# constant-amount periodic payments and a constant interest rate.
|
51
51
|
#
|
52
52
|
# @param rate [Float] The interest rate as decimal (not per cent) per period
|
53
|
-
# @param pmt [Float] The
|
54
|
-
# @param pv [Float] The present value
|
53
|
+
# @param pmt [Float] The payment amount made each period
|
54
|
+
# @param pv [Float] The present value of the payments
|
55
55
|
# @param fv [Float] The future value remaining after the final payment has been made
|
56
56
|
# @param end_or_begining [Integer] Whether payments are due at the end (0) or
|
57
57
|
# beggining (1) of each period
|
@@ -62,6 +62,8 @@ module Exonio
|
|
62
62
|
# Exonio.nper(0.07 / 12, -150, 8000) # ==> 64.07334877066185
|
63
63
|
#
|
64
64
|
def nper(rate, pmt, pv, fv = 0, end_or_beginning = 0)
|
65
|
+
return (-pv - fv) / pmt if rate.zero?
|
66
|
+
|
65
67
|
z = pmt * (1 + rate * end_or_beginning) / rate
|
66
68
|
temp = Math.log((-fv + z) / (pv + z))
|
67
69
|
|
@@ -144,6 +146,45 @@ module Exonio
|
|
144
146
|
next_guess
|
145
147
|
end
|
146
148
|
|
149
|
+
# Calculates the net present value of an investment based on a
|
150
|
+
# series of periodic cash flows and a discount rate.
|
151
|
+
#
|
152
|
+
# @param discount [Float] The discount rate of the investment over one period
|
153
|
+
# @param cashflows [Array] The first future cash flow + additional future cash flows
|
154
|
+
#
|
155
|
+
# @return [Float]
|
156
|
+
#
|
157
|
+
# @example
|
158
|
+
# Exonio.npv(0.281, [-100, 39, 59, 55, 20]) # ==> -0.00661872883563408
|
159
|
+
#
|
160
|
+
def npv(discount, cashflows)
|
161
|
+
total = 0
|
162
|
+
|
163
|
+
cashflows.each_with_index do |cashflow, index|
|
164
|
+
total += (cashflow.to_f / (1 + discount.to_f) ** (index + 1))
|
165
|
+
end
|
166
|
+
|
167
|
+
total
|
168
|
+
end
|
169
|
+
|
170
|
+
# Calculates the internal rate of return on an investment based on a
|
171
|
+
# series of periodic cash flows.
|
172
|
+
#
|
173
|
+
# @param cashflows [Array] An array containing the income or payments
|
174
|
+
# associated with the investment
|
175
|
+
#
|
176
|
+
# @return [Float]
|
177
|
+
#
|
178
|
+
# @example
|
179
|
+
# Exonio.irr([-100, 39, 59, 55, 20]) # ==> 0.28094842116...
|
180
|
+
#
|
181
|
+
def irr(values)
|
182
|
+
func = Helpers::IrrHelper.new(values)
|
183
|
+
guess = [ func.eps ]
|
184
|
+
nlsolve( func, guess)
|
185
|
+
guess[0]
|
186
|
+
end
|
187
|
+
|
147
188
|
private
|
148
189
|
|
149
190
|
# This method was borrowed from the NumPy rate formula
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Exonio
|
2
|
+
module Helpers
|
3
|
+
class IrrHelper
|
4
|
+
values = {
|
5
|
+
eps: '1.0e-16',
|
6
|
+
one: '1.0',
|
7
|
+
two: '2.0',
|
8
|
+
ten: '10.0',
|
9
|
+
zero: '0.0'
|
10
|
+
}
|
11
|
+
|
12
|
+
values.each do |key, value|
|
13
|
+
define_method key do
|
14
|
+
BigDecimal(value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(transactions)
|
19
|
+
@transactions = transactions
|
20
|
+
end
|
21
|
+
|
22
|
+
def values(x)
|
23
|
+
value = Exonio.npv(x[0].to_f, @transactions)
|
24
|
+
[ value.to_d ]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Exonio
|
2
|
+
module Statistical
|
3
|
+
|
4
|
+
# Sum of all numbers
|
5
|
+
#
|
6
|
+
# @param numbers_ary [array] and array of numbers to sum all elements
|
7
|
+
#
|
8
|
+
# @return [float]
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# Exonio.sum([1,2,3,4,5]) # => 15
|
12
|
+
def sum(numbers_ary)
|
13
|
+
numbers_ary.inject(0, :+)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Simple mean formula: sum elements and / by length
|
17
|
+
#
|
18
|
+
# @param numbers_ary [array] an array of numbers to calculate the mean
|
19
|
+
#
|
20
|
+
# @return [float]
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# Exonio.mean([1,2,3,4,5]) # => 3.0
|
24
|
+
def mean(numbers_ary)
|
25
|
+
numbers_ary.inject(0) { |sum, i| sum + i }.to_f / numbers_ary.size
|
26
|
+
end
|
27
|
+
|
28
|
+
# Median formula
|
29
|
+
# @param numbers_ary [array] an array of numbers
|
30
|
+
#
|
31
|
+
# @return [float]
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# Exonio.median([1,2,3,4,5]) # => 3.0
|
35
|
+
def median(numbers_ary)
|
36
|
+
numbers_ary.sort!
|
37
|
+
len = numbers_ary.length
|
38
|
+
(numbers_ary[(len - 1) / 2] + numbers_ary[len / 2]) / 2.0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/exonio/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exonio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Izidoro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,6 +88,8 @@ files:
|
|
88
88
|
- exonio.gemspec
|
89
89
|
- lib/exonio.rb
|
90
90
|
- lib/exonio/financial.rb
|
91
|
+
- lib/exonio/helpers/irr_helper.rb
|
92
|
+
- lib/exonio/statistical.rb
|
91
93
|
- lib/exonio/version.rb
|
92
94
|
homepage: http://github.com/noverde/exonio
|
93
95
|
licenses: []
|
@@ -107,8 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
109
|
- !ruby/object:Gem::Version
|
108
110
|
version: '0'
|
109
111
|
requirements: []
|
110
|
-
|
111
|
-
rubygems_version: 2.5.1
|
112
|
+
rubygems_version: 3.0.3
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
115
|
summary: Excel usefull formulas written in Ruby
|