xirr 0.2.2 → 0.2.3
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/.travis.yml +1 -1
- data/CHANGE_LOG.md +11 -0
- data/lib/xirr/base.rb +1 -1
- data/lib/xirr/bisection.rb +4 -4
- data/lib/xirr/cashflow.rb +7 -4
- data/lib/xirr/config.rb +2 -1
- data/lib/xirr/transaction.rb +8 -2
- data/lib/xirr/version.rb +1 -1
- data/test/test_cashflow.rb +36 -5
- data/xirr.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 474f38451b70bce0aab930fb7d7cefd20d9e3aa5
|
4
|
+
data.tar.gz: d9eac1f09cf640bc7cb1eb6c99c5e9cbfb2563a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6d71d8d7d43f56b11e22544276319623ecfc88ac1d7e6d483984450fcc0f9cb823dc1e34b7a2a167151f85154e9a31811c1c6c4df32fe3cceb6e135e5db671c
|
7
|
+
data.tar.gz: 0ca6b6c8d79be51df9c866666ccb9180a41aac883d5f99e972d986ab1145a27dfc2bec6976bdb2c713e8c8e50c0fa433dd372ae1524973ef862808db162d30b9
|
data/.travis.yml
CHANGED
data/CHANGE_LOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## Version 0.2.3
|
2
|
+
|
3
|
+
* Major fix to Bisection Engine.
|
4
|
+
* Error if provided method is wrong.
|
5
|
+
* Bisection: Initial guess is compared to default limits
|
6
|
+
* Transaction converts Time to Date.
|
7
|
+
|
8
|
+
## Version 0.2.2
|
9
|
+
|
10
|
+
* Added Tests.
|
11
|
+
|
1
12
|
## Version 0.2.1
|
2
13
|
|
3
14
|
* Output is rounded to default precision.
|
data/lib/xirr/base.rb
CHANGED
data/lib/xirr/bisection.rb
CHANGED
@@ -11,8 +11,8 @@ module Xirr
|
|
11
11
|
def xirr(midpoint = nil)
|
12
12
|
|
13
13
|
# Initial values
|
14
|
-
left = BigDecimal.new
|
15
|
-
right = BigDecimal.new
|
14
|
+
left = [BigDecimal.new(-0.99, Xirr::PRECISION), cf.irr_guess].min
|
15
|
+
right = [BigDecimal.new(9.99, Xirr::PRECISION), cf.irr_guess + 1].max
|
16
16
|
midpoint ||= cf.irr_guess
|
17
17
|
runs = 0
|
18
18
|
|
@@ -20,13 +20,13 @@ module Xirr
|
|
20
20
|
while ((right - left).abs > Xirr::EPS && runs < Xirr.config.iteration_limit.to_i) do
|
21
21
|
|
22
22
|
runs += 1
|
23
|
-
npv_positive?(midpoint) ?
|
23
|
+
npv_positive?(midpoint) == npv_positive?(left) ? left = midpoint : right = midpoint
|
24
24
|
midpoint = format_irr(left, right)
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
28
|
if runs >= Xirr.config.iteration_limit.to_i
|
29
|
-
raise ArgumentError,
|
29
|
+
raise ArgumentError, "Did not converge after #{runs} tries."
|
30
30
|
end
|
31
31
|
|
32
32
|
return midpoint.round Xirr::PRECISION
|
data/lib/xirr/cashflow.rb
CHANGED
@@ -55,10 +55,13 @@ 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 =
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
_method = case method
|
59
|
+
when :bisection
|
60
|
+
Bisection.new(self)
|
61
|
+
when :newton_method
|
62
|
+
NewtonMethod.new(self)
|
63
|
+
else
|
64
|
+
raise ArgumentError, "There is no #{method} method"
|
62
65
|
end
|
63
66
|
_method.send :xirr, guess if valid?
|
64
67
|
end
|
data/lib/xirr/config.rb
CHANGED
data/lib/xirr/transaction.rb
CHANGED
@@ -2,8 +2,7 @@ module Xirr
|
|
2
2
|
|
3
3
|
# A unit of the Cashflow.
|
4
4
|
class Transaction
|
5
|
-
attr_reader :amount
|
6
|
-
attr_accessor :date
|
5
|
+
attr_reader :amount, :date
|
7
6
|
|
8
7
|
# @example
|
9
8
|
# Transaction.new -1000, date: Date.now
|
@@ -19,6 +18,13 @@ module Xirr
|
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
21
|
+
# Sets the date
|
22
|
+
# @param value [Date, Time]
|
23
|
+
# @return [Date]
|
24
|
+
def date=(value)
|
25
|
+
@date = value.kind_of?(Time) ? value.to_date : value
|
26
|
+
end
|
27
|
+
|
22
28
|
# Sets the amount
|
23
29
|
# @param value [Numeric]
|
24
30
|
# @return [Float]
|
data/lib/xirr/version.rb
CHANGED
data/test/test_cashflow.rb
CHANGED
@@ -10,6 +10,36 @@ describe 'Cashflows' do
|
|
10
10
|
@cf << Transaction.new(-6000, date: '1995-01-01'.to_date)
|
11
11
|
end
|
12
12
|
|
13
|
+
it 'with a wrong method is invalid' do
|
14
|
+
assert_raises(ArgumentError) { @cf.xirr(nil, :no_method) }
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has an Internal Rate of Return on Bisection Method' do
|
18
|
+
assert_equal '0.225683'.to_f, @cf.xirr
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has an Internal Rate of Return on Bisection Method using a Guess' do
|
22
|
+
assert_equal '0.225683'.to_f, @cf.xirr(0.15)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has an Internal Rate of Return on Newton Method' do
|
26
|
+
assert_equal '0.225683'.to_f, @cf.xirr(nil, :newton_method)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has an educated guess' do
|
30
|
+
assert_equal '0.208'.to_f, @cf.irr_guess
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe 'of an inverted ok investment' do
|
36
|
+
before(:all) do
|
37
|
+
@cf = Cashflow.new
|
38
|
+
@cf << Transaction.new(-1000, date: '1985-01-01'.to_date)
|
39
|
+
@cf << Transaction.new(600, date: '1990-01-01'.to_date)
|
40
|
+
@cf << Transaction.new(6000, date: '1995-01-01'.to_date)
|
41
|
+
end
|
42
|
+
|
13
43
|
it 'has an Internal Rate of Return on Bisection Method' do
|
14
44
|
assert_equal '0.225683'.to_f, @cf.xirr
|
15
45
|
end
|
@@ -38,12 +68,9 @@ describe 'Cashflows' do
|
|
38
68
|
assert_equal '1.0597572345993451e+284'.to_f, @cf.xirr
|
39
69
|
end
|
40
70
|
|
41
|
-
|
42
|
-
|
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)
|
71
|
+
it 'has an Internal Rate of Return on Bisection Method using a bad Guess' do
|
72
|
+
assert_raises(ArgumentError) { @cf.xirr(0.15) }
|
45
73
|
end
|
46
|
-
=end
|
47
74
|
|
48
75
|
it 'has an Internal Rate of Return on Newton Method' do
|
49
76
|
assert_equal '1.0597572345993451e+284'.to_f, @cf.xirr(nil, :newton_method)
|
@@ -65,6 +92,10 @@ describe 'Cashflows' do
|
|
65
92
|
assert_raises(ArgumentError) { @cf.valid? }
|
66
93
|
end
|
67
94
|
|
95
|
+
it 'with a wrong method is invalid' do
|
96
|
+
assert_raises(ArgumentError) { @cf.xirr(nil, :no_method) }
|
97
|
+
end
|
98
|
+
|
68
99
|
it 'raises error when xirr is called' do
|
69
100
|
assert_raises(ArgumentError) { @cf.xirr }
|
70
101
|
end
|
data/xirr.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
22
|
spec.add_development_dependency 'rake', '~> 10'
|
23
23
|
|
24
|
-
spec.required_ruby_version = '>=
|
24
|
+
spec.required_ruby_version = '>=2.0'
|
25
25
|
spec.add_dependency 'activesupport', '~> 4.0'
|
26
26
|
spec.add_development_dependency 'minitest', '~> 5.4'
|
27
27
|
spec.add_development_dependency 'coveralls', '~> 0'
|
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.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tubedude
|
@@ -120,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
120
|
requirements:
|
121
121
|
- - '>='
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version: '
|
123
|
+
version: '2.0'
|
124
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
125
|
requirements:
|
126
126
|
- - '>='
|