xirr 0.5.1 → 0.5.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 +4 -4
- data/.DS_Store +0 -0
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGE_LOG.md +3 -0
- data/drafts.rb +123 -0
- data/lib/xirr/bisection.rb +2 -2
- data/lib/xirr/cashflow.rb +12 -4
- data/lib/xirr/config.rb +1 -1
- data/lib/xirr/newton_method.rb +2 -1
- data/lib/xirr/version.rb +1 -1
- data/test/test_cashflow.rb +12 -1
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97aa8fc091ee69359b450ae546e218043d52298d
|
|
4
|
+
data.tar.gz: 8538c81ef259d6beae048e2407969580b68437c7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6fd7755b7219e30b1f2e2c1c726440d0932f5e3c690fbf7402421c6c598cf63145afcd61e0ac48cdee5b479e90430328d30bb7c6bf215d15b6552876a8d5555d
|
|
7
|
+
data.tar.gz: ddb3b2063e9e6079223a9ebe4cb4607b723612c23fd6dca6bfb4a3a58998744dcdd9c2a62ea138b0e23e85e0a72df98548fd5960767119d5ed4c6ba3bec2f616
|
data/.DS_Store
ADDED
|
Binary file
|
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
xirr
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby-2.1.5
|
data/CHANGE_LOG.md
CHANGED
data/drafts.rb
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# @cf = Cashflow.new
|
|
2
|
+
# @cf << Transaction.new(105187.06, date: '2011-12-07'.to_date )
|
|
3
|
+
# @cf << Transaction.new(816709.66, date: '2011-12-07'.to_date )
|
|
4
|
+
# @cf << Transaction.new(479069.684, date: '2011-12-07'.to_date )
|
|
5
|
+
# @cf << Transaction.new(937309.708, date: '2012-01-18'.to_date )
|
|
6
|
+
# @cf << Transaction.new(88622.661, date: '2012-07-03'.to_date )
|
|
7
|
+
# @cf << Transaction.new(100000.0, date: '2012-07-03'.to_date )
|
|
8
|
+
# @cf << Transaction.new(80000.0, date: '2012-07-19'.to_date )
|
|
9
|
+
# @cf << Transaction.new(403627.95, date: '2012-07-23'.to_date )
|
|
10
|
+
# @cf << Transaction.new(508117.9, date: '2012-07-23'.to_date )
|
|
11
|
+
# @cf << Transaction.new(789706.87, date: '2012-07-23'.to_date )
|
|
12
|
+
# @cf << Transaction.new(-88622.661, date: '2012-09-11'.to_date )
|
|
13
|
+
# @cf << Transaction.new(-789706.871, date: '2012-09-11'.to_date )
|
|
14
|
+
# @cf << Transaction.new(-688117.9, date: '2012-09-11'.to_date )
|
|
15
|
+
# @cf << Transaction.new(-403627.95, date: '2012-09-11'.to_date )
|
|
16
|
+
# @cf << Transaction.new(403627.95, date: '2012-09-12'.to_date )
|
|
17
|
+
# @cf << Transaction.new(789706.871, date: '2012-09-12'.to_date )
|
|
18
|
+
# @cf << Transaction.new(88622.661, date: '2012-09-12'.to_date )
|
|
19
|
+
# @cf << Transaction.new(688117.9, date: '2012-09-12'.to_date )
|
|
20
|
+
# @cf << Transaction.new(45129.14, date: '2013-03-11'.to_date )
|
|
21
|
+
# @cf << Transaction.new(26472.08, date: '2013-03-11'.to_date )
|
|
22
|
+
# @cf << Transaction.new(51793.2, date: '2013-03-11'.to_date )
|
|
23
|
+
# @cf << Transaction.new(126605.59, date: '2013-03-11'.to_date )
|
|
24
|
+
# @cf << Transaction.new(278532.29, date: '2013-03-28'.to_date )
|
|
25
|
+
# @cf << Transaction.new(99284.1, date: '2013-03-28'.to_date )
|
|
26
|
+
# @cf << Transaction.new(58238.57, date: '2013-03-28'.to_date )
|
|
27
|
+
# @cf << Transaction.new(113945.03, date: '2013-03-28'.to_date )
|
|
28
|
+
# @cf << Transaction.new(405137.88, date: '2013-05-21'.to_date )
|
|
29
|
+
# @cf << Transaction.new(-405137.88, date: '2013-05-21'.to_date )
|
|
30
|
+
# @cf << Transaction.new(165738.23, date: '2013-05-21'.to_date )
|
|
31
|
+
# @cf << Transaction.new(-165738.23, date: '2013-05-21'.to_date )
|
|
32
|
+
# @cf << Transaction.new(144413.24, date: '2013-05-21'.to_date )
|
|
33
|
+
# @cf << Transaction.new(84710.65, date: '2013-05-21'.to_date )
|
|
34
|
+
# @cf << Transaction.new(-84710.65, date: '2013-05-21'.to_date )
|
|
35
|
+
# @cf << Transaction.new(-144413.24, date: '2013-05-21'.to_date )
|
|
36
|
+
#
|
|
37
|
+
#
|
|
38
|
+
# #
|
|
39
|
+
# # (0.0,2014-02-14)
|
|
40
|
+
# # (0.0,2014-02-14)
|
|
41
|
+
# # (0.0,2014-02-14)
|
|
42
|
+
# # (0.0,2014-02-14)
|
|
43
|
+
# # (0.0,2014-02-14)
|
|
44
|
+
# # (0.0,2014-02-14)
|
|
45
|
+
# # (0.0,2014-02-14)
|
|
46
|
+
# # (0.0,2014-02-14)
|
|
47
|
+
# # (0.0,2014-02-14)
|
|
48
|
+
# # (0.0,2014-02-14)
|
|
49
|
+
# # (0.0,2014-02-14)
|
|
50
|
+
# # (0.0,2014-02-14) (0.0,2014-02-14) (0.0,2014-02-14) (0.0,2014-02-14) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (0.0,2014-08-12) (-0.0,2014-11-19)]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
require 'active_support/all'
|
|
55
|
+
require_relative 'lib/xirr.rb'
|
|
56
|
+
require_relative 'lib/xirr/config.rb'
|
|
57
|
+
require_relative 'lib/xirr/base.rb'
|
|
58
|
+
require_relative 'lib/xirr/bisection.rb'
|
|
59
|
+
require_relative 'lib/xirr/newton_method.rb'
|
|
60
|
+
require_relative 'lib/xirr/cashflow.rb'
|
|
61
|
+
require_relative 'lib/xirr/transaction.rb'
|
|
62
|
+
include Xirr
|
|
63
|
+
|
|
64
|
+
require 'Benchmark'
|
|
65
|
+
|
|
66
|
+
@cf = Cashflow.new
|
|
67
|
+
@cf << Transaction.new(105187.06, date: '2011-12-07'.to_date )
|
|
68
|
+
@cf << Transaction.new(816709.66, date: '2011-12-07'.to_date )
|
|
69
|
+
@cf << Transaction.new(479069.684, date: '2011-12-07'.to_date )
|
|
70
|
+
@cf << Transaction.new(937309.708, date: '2012-01-18'.to_date )
|
|
71
|
+
@cf << Transaction.new(88622.661, date: '2012-07-03'.to_date )
|
|
72
|
+
|
|
73
|
+
@cf << Transaction.new(100000.0, date: '2012-07-03'.to_date )
|
|
74
|
+
@cf << Transaction.new(80000.0, date: '2012-07-19'.to_date )
|
|
75
|
+
@cf << Transaction.new(403627.95, date: '2012-07-23'.to_date )
|
|
76
|
+
@cf << Transaction.new(508117.9, date: '2012-07-23'.to_date )
|
|
77
|
+
@cf << Transaction.new(789706.87, date: '2012-07-23'.to_date )
|
|
78
|
+
@cf << Transaction.new(-88622.661, date: '2012-09-11'.to_date )
|
|
79
|
+
@cf << Transaction.new(-789706.871, date: '2012-09-11'.to_date )
|
|
80
|
+
@cf << Transaction.new(-688117.9, date: '2012-09-11'.to_date )
|
|
81
|
+
@cf << Transaction.new(-403627.95, date: '2012-09-11'.to_date )
|
|
82
|
+
@cf << Transaction.new(403627.95, date: '2012-09-12'.to_date )
|
|
83
|
+
@cf << Transaction.new(789706.871, date: '2012-09-12'.to_date )
|
|
84
|
+
@cf << Transaction.new(88622.661, date: '2012-09-12'.to_date )
|
|
85
|
+
|
|
86
|
+
@cf << Transaction.new(688117.9, date: '2012-09-12'.to_date )
|
|
87
|
+
@cf << Transaction.new(45129.14, date: '2013-03-11'.to_date )
|
|
88
|
+
@cf << Transaction.new(26472.08, date: '2013-03-11'.to_date )
|
|
89
|
+
@cf << Transaction.new(51793.2, date: '2013-03-11'.to_date )
|
|
90
|
+
@cf << Transaction.new(126605.59, date: '2013-03-11'.to_date )
|
|
91
|
+
@cf << Transaction.new(278532.29, date: '2013-03-28'.to_date )
|
|
92
|
+
@cf << Transaction.new(99284.1, date: '2013-03-28'.to_date )
|
|
93
|
+
@cf << Transaction.new(58238.57, date: '2013-03-28'.to_date )
|
|
94
|
+
@cf << Transaction.new(113945.03, date: '2013-03-28'.to_date )
|
|
95
|
+
@cf << Transaction.new(405137.88, date: '2013-05-21'.to_date )
|
|
96
|
+
|
|
97
|
+
@cf << Transaction.new(-405137.88, date: '2013-05-21'.to_date )
|
|
98
|
+
@cf << Transaction.new(165738.23, date: '2013-05-21'.to_date )
|
|
99
|
+
@cf << Transaction.new(-165738.23, date: '2013-05-21'.to_date )
|
|
100
|
+
@cf << Transaction.new(144413.24, date: '2013-05-21'.to_date )
|
|
101
|
+
@cf << Transaction.new(84710.65, date: '2013-05-21'.to_date )
|
|
102
|
+
@cf << Transaction.new(-8471000.65, date: '2013-05-21'.to_date )
|
|
103
|
+
@cf << Transaction.new(-1444130.24, date: '2013-05-21'.to_date )
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def compact_cf
|
|
108
|
+
compact = Hash.new
|
|
109
|
+
@cf.map(&:date).uniq.each {|date| compact[date] = 0 }
|
|
110
|
+
@cf.each { |flow| compact[flow.date] += flow.amount}
|
|
111
|
+
@compact_cf = Cashflow.new compact.map { |key,value| Transaction.new(value, date: key.to_date)}
|
|
112
|
+
@compact_cf.xirr(@compact_cf.irr_guess, :newton_method)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
n = 100
|
|
119
|
+
Benchmark.bm (10) { |x|
|
|
120
|
+
x.report('Compact') { n.times { @cf.xirr(nil, :newton_method, true) } }
|
|
121
|
+
# x.report('Compact') { n.times { compact_cf } }
|
|
122
|
+
x.report('Natural') { n.times { @cf.xirr(nil, :newton_method, false) } }
|
|
123
|
+
}
|
data/lib/xirr/bisection.rb
CHANGED
|
@@ -11,8 +11,8 @@ module Xirr
|
|
|
11
11
|
def xirr midpoint
|
|
12
12
|
|
|
13
13
|
# Initial values
|
|
14
|
-
left
|
|
15
|
-
right = [BigDecimal.new(9.
|
|
14
|
+
left = [BigDecimal.new(-0.99999999, Xirr::PRECISION), cf.irr_guess].min
|
|
15
|
+
right = [BigDecimal.new(9.99999999, Xirr::PRECISION), cf.irr_guess + 1].max
|
|
16
16
|
@original_right = right
|
|
17
17
|
midpoint ||= cf.irr_guess
|
|
18
18
|
runs = 0
|
data/lib/xirr/cashflow.rb
CHANGED
|
@@ -16,7 +16,7 @@ module Xirr
|
|
|
16
16
|
@period = period
|
|
17
17
|
@fallback = options[:fallback]
|
|
18
18
|
@options = options
|
|
19
|
-
|
|
19
|
+
self << flow
|
|
20
20
|
self.flatten!
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -155,7 +155,11 @@ module Xirr
|
|
|
155
155
|
# @return [Float]
|
|
156
156
|
def multiple
|
|
157
157
|
result = positives.sum(&:amount) / -negatives.sum(&:amount)
|
|
158
|
-
|
|
158
|
+
first_transaction_positive? ? result : 1 / result
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def first_transaction_positive?
|
|
162
|
+
first_transaction_direction > 0
|
|
159
163
|
end
|
|
160
164
|
|
|
161
165
|
# @api private
|
|
@@ -171,7 +175,7 @@ module Xirr
|
|
|
171
175
|
# Selects all positives transactions from Cashflow
|
|
172
176
|
def positives
|
|
173
177
|
return @positives if @positives
|
|
174
|
-
|
|
178
|
+
extract_positives_and_negatives
|
|
175
179
|
@positives
|
|
176
180
|
end
|
|
177
181
|
|
|
@@ -181,10 +185,14 @@ module Xirr
|
|
|
181
185
|
# Selects all negatives transactions from Cashflow
|
|
182
186
|
def negatives
|
|
183
187
|
return @negatives if @negatives
|
|
184
|
-
|
|
188
|
+
extract_positives_and_negatives
|
|
185
189
|
@negatives
|
|
186
190
|
end
|
|
187
191
|
|
|
192
|
+
def extract_positives_and_negatives
|
|
193
|
+
@positives, @negatives = self.partition { |x| x.amount < 0 }
|
|
194
|
+
end
|
|
195
|
+
|
|
188
196
|
end
|
|
189
197
|
|
|
190
198
|
end
|
data/lib/xirr/config.rb
CHANGED
data/lib/xirr/newton_method.rb
CHANGED
data/lib/xirr/version.rb
CHANGED
data/test/test_cashflow.rb
CHANGED
|
@@ -277,7 +277,18 @@ describe 'Cashflows' do
|
|
|
277
277
|
end
|
|
278
278
|
|
|
279
279
|
it 'is a long and bad investment and newton generates an error' do
|
|
280
|
-
assert_equal '-0
|
|
280
|
+
assert_equal '-1.0'.to_f, @cf.xirr #(method: :newton_method)
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
describe 'xichen27' do
|
|
286
|
+
it 'it matchs Excel' do
|
|
287
|
+
cf = Cashflow.new
|
|
288
|
+
cf << Transaction.new(-10000, date: '2014-04-15'.to_date)
|
|
289
|
+
cf << Transaction.new(305.6, date: '2014-05-15'.to_date)
|
|
290
|
+
cf << Transaction.new(500, date: '2014-10-19'.to_date)
|
|
291
|
+
assert_equal '-0.996814607'.to_f.round(3), cf.xirr.to_f.round(3)
|
|
281
292
|
end
|
|
282
293
|
|
|
283
294
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xirr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tubedude
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-03-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -102,14 +102,18 @@ executables: []
|
|
|
102
102
|
extensions: []
|
|
103
103
|
extra_rdoc_files: []
|
|
104
104
|
files:
|
|
105
|
+
- ".DS_Store"
|
|
105
106
|
- ".coveralls.yml"
|
|
106
107
|
- ".gitignore"
|
|
108
|
+
- ".ruby-gemset"
|
|
109
|
+
- ".ruby-version"
|
|
107
110
|
- ".travis.yml"
|
|
108
111
|
- CHANGE_LOG.md
|
|
109
112
|
- Gemfile
|
|
110
113
|
- LICENSE.txt
|
|
111
114
|
- README.md
|
|
112
115
|
- Rakefile
|
|
116
|
+
- drafts.rb
|
|
113
117
|
- lib/xirr.rb
|
|
114
118
|
- lib/xirr/base.rb
|
|
115
119
|
- lib/xirr/bisection.rb
|