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
|