finance_rb 0.0.3 → 0.0.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +6 -4
- data/lib/finance/calculations.rb +46 -4
- data/lib/finance/loan.rb +16 -4
- data/lib/finance/version.rb +1 -1
- data/spec/finance/calculations_spec.rb +43 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82235bcca3f51afff5ec345707da9d1ed2e8472a20488bb3847a4967baf6932c
|
4
|
+
data.tar.gz: '02029b9b9151d52ad860b1f985cc708199d734f8f210e574cda50fc7290f4231'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38348b526019d3124c6cff67c4cd39427600d7a52ea584ea9b583328bedcfceb6680783bbbfdb8f9b45b686ff612e6295e670f1a09d882e09f4540fcf23a3aea
|
7
|
+
data.tar.gz: 879a9b9b6e01efd654e32a1bbc77a9e07e8a9b1cebbbb1061f6d20f3e0aa723b8150fbf8a56e66dee87bf3eb69a14301dc4d9a51fd62f87e9414f69f47aab5d6
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
This package is a ruby native port of the numpy-financial package with some helpful additional functions.
|
4
4
|
|
5
|
-
The functions in this package are a scalar version of their vectorised counterparts in
|
5
|
+
The functions in this package are a scalar version of their vectorised counterparts in the [numpy-financial](https://github.com/numpy/numpy-financial) library.
|
6
|
+
|
7
|
+
[](https://github.com/wowinter13/finance_rb/releases) [](http://makeapullrequest.com)
|
6
8
|
|
7
9
|
Currently, only some functions are ported,
|
8
10
|
which are as follows:
|
@@ -15,7 +17,7 @@ which are as follows:
|
|
15
17
|
| ppmt | | Computes principal payment for a loan|
|
16
18
|
| nper | | Computes the number of periodic payments|
|
17
19
|
| pv | | Computes the present value of a payment|
|
18
|
-
| rate |
|
19
|
-
| irr |
|
20
|
+
| rate | | Computes the rate of interest per period|
|
21
|
+
| irr | ✅ | Computes the internal rate of return|
|
20
22
|
| npv | ✅ | Computes the net present value of a series of cash flow|
|
21
|
-
| mirr |
|
23
|
+
| mirr | ✅ | Computes the modified internal rate of return|
|
data/lib/finance/calculations.rb
CHANGED
@@ -35,6 +35,8 @@ module Finance
|
|
35
35
|
# @return [Float] Internal Rate of Return for periodic input values.
|
36
36
|
#
|
37
37
|
# @param [Array<Numeric>] :values Input cash flows per time period.
|
38
|
+
# At least, must contain one positive and one negative value.
|
39
|
+
# Otherwise, irr equals zero.
|
38
40
|
#
|
39
41
|
# @example
|
40
42
|
# require 'finance_rb'
|
@@ -44,10 +46,7 @@ module Finance
|
|
44
46
|
# @see L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
|
45
47
|
# Addison-Wesley, 2003, pg. 348.
|
46
48
|
def irr(values)
|
47
|
-
|
48
|
-
if inflows.empty? || outflows.empty?
|
49
|
-
return 0.0
|
50
|
-
end
|
49
|
+
return 0.0 unless correct_cashflows?(values)
|
51
50
|
|
52
51
|
func = BigDecimal.limit(100)
|
53
52
|
func = Function.new(values)
|
@@ -56,11 +55,54 @@ module Finance
|
|
56
55
|
rate[0].to_f
|
57
56
|
end
|
58
57
|
|
58
|
+
# MIRR computes the modified Rate of Interest.
|
59
|
+
#
|
60
|
+
# @return [Float] Modified Internal Rate of Return.
|
61
|
+
#
|
62
|
+
# @param [Array<Numeric>] :values
|
63
|
+
# At least, must contain one positive and one negative value.
|
64
|
+
# Otherwise, mirr equals zero.
|
65
|
+
# @param [Numeric] :rate Interest rate paid on the cash flows
|
66
|
+
# @param [Numeric] :reinvest_rate Interest rate received on the cash flows upon reinvestment
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
# require 'finance_rb'
|
70
|
+
# Finance::Calculations.mirr([100, 200, -50, 300, -200], 0.05, 0.06) => 0.2979256979689131
|
71
|
+
#
|
72
|
+
# @see https://en.wikipedia.org/wiki/Modified_internal_rate_of_return
|
73
|
+
def mirr(values, rate, reinvest_rate)
|
74
|
+
inflows = [];
|
75
|
+
outflows = [];
|
76
|
+
# We prefer manual enumeration over the partition
|
77
|
+
# because of the need to replace outflows with zeros.
|
78
|
+
values.each do |val|
|
79
|
+
if val >= 0
|
80
|
+
inflows << val
|
81
|
+
outflows << 0.0
|
82
|
+
else
|
83
|
+
outflows << val
|
84
|
+
inflows << 0.0
|
85
|
+
end
|
86
|
+
end
|
87
|
+
if outflows.all?(0.0) || inflows.all?(0.0)
|
88
|
+
return 0.0
|
89
|
+
end
|
90
|
+
fv = npv(reinvest_rate, inflows).abs
|
91
|
+
pv = npv(rate, outflows).abs
|
92
|
+
|
93
|
+
return (fv/pv) ** (1.0/(values.size - 1)) * (1 + reinvest_rate) - 1
|
94
|
+
end
|
95
|
+
|
59
96
|
alias net_present_value npv
|
60
97
|
alias internal_return_rate irr
|
61
98
|
|
62
99
|
private
|
63
100
|
|
101
|
+
def correct_cashflows?(values)
|
102
|
+
inflows, outflows = values.partition{ |i| i >= 0 }
|
103
|
+
!(inflows.empty? || outflows.empty?)
|
104
|
+
end
|
105
|
+
|
64
106
|
# Base class for working with Newton's Method.
|
65
107
|
# For more details, see Bigdecimal::Newton.
|
66
108
|
# @api private
|
data/lib/finance/loan.rb
CHANGED
@@ -2,12 +2,24 @@
|
|
2
2
|
|
3
3
|
module Finance
|
4
4
|
class Loan
|
5
|
-
def initialize
|
5
|
+
def initialize(**options)
|
6
|
+
end
|
6
7
|
|
7
|
-
def pmt
|
8
|
+
def pmt()
|
9
|
+
end
|
8
10
|
|
9
|
-
def ipmt
|
11
|
+
def ipmt()
|
12
|
+
end
|
10
13
|
|
11
|
-
def ppmt
|
14
|
+
def ppmt()
|
15
|
+
end
|
16
|
+
|
17
|
+
def fv();end
|
18
|
+
|
19
|
+
def pv();end
|
20
|
+
|
21
|
+
def nper();end
|
22
|
+
|
23
|
+
def rate();end
|
12
24
|
end
|
13
25
|
end
|
data/lib/finance/version.rb
CHANGED
@@ -26,7 +26,7 @@ RSpec.describe Finance::Calculations do
|
|
26
26
|
).to eq(0.14299344106053188)
|
27
27
|
end
|
28
28
|
|
29
|
-
it 'calculates zero
|
29
|
+
it 'calculates zero for cashflows w/o any inflows' do
|
30
30
|
expect(
|
31
31
|
Finance::Calculations.irr([100,500,200,50])
|
32
32
|
).to eq(0.0)
|
@@ -38,4 +38,46 @@ RSpec.describe Finance::Calculations do
|
|
38
38
|
).to eq(-0.09549583035161031)
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
describe '#mirr' do
|
43
|
+
it 'calculates correct mirr value' do
|
44
|
+
expect(
|
45
|
+
Finance::Calculations.mirr(
|
46
|
+
[-120000.0, 39000.0, 30000.0, 21000.0, 37000.0, 46000.0], 0.10, 0.12
|
47
|
+
)
|
48
|
+
).to eq(0.1260941303659051)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'calculates correct mirr value with integers' do
|
52
|
+
expect(
|
53
|
+
Finance::Calculations.mirr(
|
54
|
+
[-4500, -800, 800, 800, 600, 600, 800, 800, 700, 3000], 0.08, 0.055
|
55
|
+
)
|
56
|
+
).to eq(0.06659717503155349)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'calculates zero for cashflows w/o any outflows' do
|
60
|
+
expect(
|
61
|
+
Finance::Calculations.mirr(
|
62
|
+
[39000, 30000, 21000, 37000, 46000], 0.10, 0.12
|
63
|
+
)
|
64
|
+
).to eq(0.0)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'calculates zero for cashflows w/o any inflows' do
|
68
|
+
expect(
|
69
|
+
Finance::Calculations.mirr(
|
70
|
+
[-1000, -5000, -2000, -100, -50], 0.10, 0.12
|
71
|
+
)
|
72
|
+
).to eq(0.0)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'calculates correct mirr value for a shuffled order' do
|
76
|
+
expect(
|
77
|
+
Finance::Calculations.mirr(
|
78
|
+
[100, 200, -50, 300, -200], 0.05, 0.06
|
79
|
+
)
|
80
|
+
).to eq(0.3428233878421769)
|
81
|
+
end
|
82
|
+
end
|
41
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: finance_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vlad Dyachenko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A ruby port of numpy-financial functions. This library provides a Ruby
|
14
14
|
interface for working with interest rates, mortgage amortization, and cashflows
|