finance_rb 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a0dc37279e3b577acb13a90c61ad4f232573a4d8c0eccdf19a267d42001a9ea
4
- data.tar.gz: ca6db2175dd770056d7539d555b239127bcc5836ae79826edc6807a4f5bd4311
3
+ metadata.gz: 82235bcca3f51afff5ec345707da9d1ed2e8472a20488bb3847a4967baf6932c
4
+ data.tar.gz: '02029b9b9151d52ad860b1f985cc708199d734f8f210e574cda50fc7290f4231'
5
5
  SHA512:
6
- metadata.gz: 395383e7e7c9b2b564a738aae13bc6f95d7180652b951a2fa4cf90118e551cb0cba6e87badb4ca23c7b5ab790be2de0ff5bef0e3736c50c18a7246262b2ae496
7
- data.tar.gz: 5c9a8d1e5b8726234fafa45ed747dcf881f7ae92a9157abf34e9186594775a4e651fc8c09395cdd9fd30e21426e217c4216f2b13644ee15f324a967325d4bf6a
6
+ metadata.gz: 38348b526019d3124c6cff67c4cd39427600d7a52ea584ea9b583328bedcfceb6680783bbbfdb8f9b45b686ff612e6295e670f1a09d882e09f4540fcf23a3aea
7
+ data.tar.gz: 879a9b9b6e01efd654e32a1bbc77a9e07e8a9b1cebbbb1061f6d20f3e0aa723b8150fbf8a56e66dee87bf3eb69a14301dc4d9a51fd62f87e9414f69f47aab5d6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [0.0.4] - 2021-03-25
2
+
3
+ ### Added
4
+ * Implement Finance::Calculations#mirr
5
+
1
6
  ## [0.0.3] - 2021-03-23
2
7
 
3
8
  ### Added
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 the [numpy-financial](https://github.com/numpy/numpy-financial) library.
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
+ [![Release](https://img.shields.io/github/v/release/wowinter13/finance_rb.svg?style=flat-square)](https://github.com/wowinter13/finance_rb/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](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 || Computes the rate of interest per period|
19
- | irr | | Computes the internal rate of return|
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 | | Computes the modified internal rate of return|
23
+ | mirr || Computes the modified internal rate of return|
@@ -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
- inflows, outflows = values.partition{ |i| i >= 0 }
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; end
5
+ def initialize(**options)
6
+ end
6
7
 
7
- def pmt; end
8
+ def pmt()
9
+ end
8
10
 
9
- def ipmt; end
11
+ def ipmt()
12
+ end
10
13
 
11
- def ppmt; end
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Finance
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.4"
5
5
  end
@@ -26,7 +26,7 @@ RSpec.describe Finance::Calculations do
26
26
  ).to eq(0.14299344106053188)
27
27
  end
28
28
 
29
- it 'calculates zero value for cashflows w/o any inflows' do
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.3
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-22 00:00:00.000000000 Z
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