xirr 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4503151b19d0e3540c2f88066fcbefe12799d70d
4
- data.tar.gz: 70a4f1a010d6d4a084babadeb326d59f02e7d284
3
+ metadata.gz: 408c3bf957bc9651c987e8677e997866cfd170bc
4
+ data.tar.gz: 7b4ffaef9837569c22bd86f97a878b172d3284c9
5
5
  SHA512:
6
- metadata.gz: f433267dae83354352f38d3b861ae02a2b7d0d83ef009b350ea059a8d479f8f323b05f9ba197b16c2b363c3db5e2ce2ed23d05d53008749ec87276647d118dcd
7
- data.tar.gz: 59c0511149b7473f4fee70eddfb1cb67f8bc060fd5cea1255e110724448cc15eb9f6501e83d9b3ecefbc8dc863cfbe3f02c82cf2f50fafe36fb05ecf2ba3aa51
6
+ metadata.gz: 6dc5b68ea4821d65b771e4d9ae697a7a24c456d10eabe33638ebf67d1b9c37273d85c838200ac47539238197350def7e20501a7233fb820ff9adf006c91518af
7
+ data.tar.gz: d79dba2d39dfce72b0d5c9fc5844e6768160c83f73019525b2e2c9418866d2efea5d5145b0cca808f0afa73101fe7962bfb04aaa77cf2e28c8e2f38d2b1d0295
@@ -10,29 +10,25 @@ module Xirr
10
10
  # An initial guess rate will override the {Cashflow#irr_guess}
11
11
  def xirr(midpoint = nil)
12
12
 
13
- # Raises error if Cashflow is not valid
14
- cf.valid?
15
-
16
- # Bisection method finding the rate to zero nfv
17
-
18
13
  # Initial values
19
14
  left = BigDecimal.new -0.99, Xirr::PRECISION
20
15
  right = BigDecimal.new 9.99, Xirr::PRECISION
21
- eps = Xirr::EPS
22
16
  midpoint ||= cf.irr_guess
23
- limit = Xirr.config.iteration_limit.to_i
24
17
  runs = 0
25
18
 
26
19
  # Loops until difference is within error margin
27
- while ((right-left).abs > eps) do
20
+ while ((right - left).abs > Xirr::EPS && runs < Xirr.config.iteration_limit.to_i) do
28
21
 
29
- raise 'Did not converge' if runs == limit
30
22
  runs += 1
31
23
  npv_positive?(midpoint) ? right = midpoint : left = midpoint
32
24
  midpoint = format_irr(left, right)
33
25
 
34
26
  end
35
27
 
28
+ if runs >= Xirr.config.iteration_limit.to_i
29
+ raise ArgumentError, 'Did not converge'
30
+ end
31
+
36
32
  return midpoint.round Xirr::PRECISION
37
33
 
38
34
  end
@@ -47,7 +47,7 @@ module Xirr
47
47
  # Calculates a simple IRR guess based on period of investment and multiples.
48
48
  # @return [Float]
49
49
  def irr_guess
50
- ((multiple ** (1 / years_of_investment)) - 1).round(3)
50
+ ((multiple ** (1 / years_of_investment)) - 1).round(3) if valid?
51
51
  end
52
52
 
53
53
  # @param guess [Float]
@@ -55,7 +55,12 @@ module Xirr
55
55
  # @return [Float]
56
56
  # Finds the XIRR according to the method provided. Default to Bisection
57
57
  def xirr(guess = nil, method = Xirr.config.default_method)
58
- method == :bisection ? Bisection.new(self).xirr(guess) : NewtonMethod.new(self).xirr(guess)
58
+ _method = if method == :bisection
59
+ Bisection.new(self)
60
+ else
61
+ NewtonMethod.new(self)
62
+ end
63
+ _method.send :xirr, guess if valid?
59
64
  end
60
65
 
61
66
  # First investment date
@@ -91,7 +96,6 @@ module Xirr
91
96
  # @return
92
97
  def years_of_investment
93
98
  (max_date - min_date) / (365).to_f
94
- # (max_date - min_date) / (365 * 24 * 60 * 60).to_f
95
99
  end
96
100
 
97
101
  # @api private
@@ -127,7 +131,7 @@ module Xirr
127
131
  # Error message depending on the missing transaction
128
132
  def invalid_message
129
133
  return 'No positive transaction' if positives.empty?
130
- return 'No negatives transaction' if negatives.empty?
134
+ return 'No negative transaction' if negatives.empty?
131
135
  end
132
136
 
133
137
  end
@@ -11,7 +11,7 @@ module Xirr
11
11
  # @param opts [Hash]
12
12
  # @note Don't forget to add date: [Date] in the opts hash.
13
13
  def initialize(amount, opts={})
14
- @amount = amount.to_f
14
+ self.amount = amount
15
15
 
16
16
  # Set optional attributes..
17
17
  opts.each do |key, value|
@@ -1,4 +1,4 @@
1
1
  module Xirr
2
2
  # Version of the Gem
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
@@ -2,7 +2,7 @@ require_relative 'test_helper'
2
2
 
3
3
  describe 'Cashflows' do
4
4
 
5
- describe 'of a good investment' do
5
+ describe 'of a ok investment' do
6
6
  before(:all) do
7
7
  @cf = Cashflow.new
8
8
  @cf << Transaction.new(1000, date: '1985-01-01'.to_date)
@@ -26,15 +26,77 @@ describe 'Cashflows' do
26
26
  assert_equal '0.208'.to_f, @cf.irr_guess
27
27
  end
28
28
  end
29
- describe 'an invalid array of Transactions' do
30
- it 'should have an Internal Rate of Return' do
29
+
30
+ describe 'of a good investment' do
31
+ before(:all) do
32
+ @cf = Cashflow.new
33
+ @cf << Transaction.new(1000, date: '1985-01-01'.to_date)
34
+ @cf << Transaction.new(-6000, date: '1985-01-02'.to_date)
35
+ end
36
+
37
+ it 'has an Internal Rate of Return on Bisection Method' do
38
+ assert_equal '1.0597572345993451e+284'.to_f, @cf.xirr
39
+ end
40
+
41
+ =begin
42
+ # FIXME Check why limit is not being enforced
43
+ it 'has an Internal Rate of Return on Bisection Method using a Guess' do
44
+ assert_equal '0.225683'.to_f, @cf.xirr(0.15)
45
+ end
46
+ =end
47
+
48
+ it 'has an Internal Rate of Return on Newton Method' do
49
+ assert_equal '1.0597572345993451e+284'.to_f, @cf.xirr(nil, :newton_method)
50
+ end
51
+
52
+ it 'has an educated guess' do
53
+ assert_equal '1.0597572345993451e+284'.to_f, @cf.irr_guess
54
+ end
55
+ end
56
+
57
+ describe 'an all-negative Cashflow' do
58
+ before(:all) do
31
59
  @cf = Cashflow.new
32
60
  @cf << Transaction.new(-600, date: '1990-01-01'.to_date)
33
61
  @cf << Transaction.new(-600, date: '1995-01-01'.to_date)
62
+ end
63
+
64
+ it 'is invalid' do
65
+ assert_raises(ArgumentError) { @cf.valid? }
66
+ end
67
+
68
+ it 'raises error when xirr is called' do
69
+ assert_raises(ArgumentError) { @cf.xirr }
70
+ end
71
+
72
+ it 'raises error when xirr is called' do
73
+ assert_raises(ArgumentError) { @cf.irr_guess }
74
+ end
75
+
76
+ end
77
+
78
+ describe 'an all-positive Cashflow' do
79
+ before(:all) do
80
+ @cf = Cashflow.new
81
+ @cf << Transaction.new(600, date: '1990-01-01'.to_date)
82
+ @cf << Transaction.new(600, date: '1995-01-01'.to_date)
83
+ end
84
+
85
+ it 'is invalid' do
34
86
  assert_raises(ArgumentError) { @cf.valid? }
35
87
  end
88
+
89
+ it 'raises error when xirr is called' do
90
+ assert_raises(ArgumentError) { @cf.xirr }
91
+ end
92
+
93
+ it 'raises error when xirr is called' do
94
+ assert_raises(ArgumentError) { @cf.irr_guess }
95
+ end
36
96
  end
97
+
37
98
  describe 'of a bad investment' do
99
+
38
100
  before(:all) do
39
101
  @cf = Cashflow.new
40
102
  @cf << Transaction.new(1000, date: '1985-01-01'.to_date)
@@ -55,6 +117,7 @@ describe 'Cashflows' do
55
117
  end
56
118
 
57
119
  end
120
+
58
121
  describe 'of a long investment' do
59
122
  before(:all) do
60
123
  @cf = Cashflow.new
@@ -13,3 +13,21 @@ require 'xirr/newton_method.rb'
13
13
  require 'xirr/cashflow.rb'
14
14
  require 'xirr/transaction.rb'
15
15
  include Xirr
16
+
17
+ =begin
18
+
19
+ require 'active_support/all'
20
+ require_relative 'lib/xirr.rb'
21
+ require_relative 'lib/xirr/config.rb'
22
+ require_relative 'lib/xirr/base.rb'
23
+ require_relative 'lib/xirr/bisection.rb'
24
+ require_relative 'lib/xirr/newton_method.rb'
25
+ require_relative 'lib/xirr/cashflow.rb'
26
+ require_relative 'lib/xirr/transaction.rb'
27
+ include Xirr
28
+ cf = Cashflow.new
29
+ cf << Transaction.new(1000, date: '1985-01-01'.to_date)
30
+ cf << Transaction.new(-6000, date: '1985-01-02'.to_date)
31
+ cf.xirr(0.15)
32
+
33
+ =end
@@ -10,4 +10,8 @@ describe 'Transaction' do
10
10
  it 'retreives the date' do
11
11
  assert_equal Date.today, @t.date
12
12
  end
13
+ it 'has inspect' do
14
+ assert_equal "T(1000.0,#{Date.today})", @t.inspect
15
+ end
16
+
13
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xirr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - tubedude