exonio 0.4.1 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/exonio.svg)](https://badge.fury.io/rb/exonio)
|
7
|
+
[![Build Status](https://travis-ci.org/Noverde/exonio.svg?branch=master)](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
|