xirr_newton_calculator 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/xirr_newton_calculator.rb +10 -9
- data/spec/xirr_newton_calculator_spec.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTI0ZmIwMmEyM2JiNTQyNjRhOWQ1NzE5NzUzYTU5MWIwYmU3Mjg1NQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NWQ5NmI3NzNhN2Y0MmM5OWViZTE0MGI4NzNhYzFhZDc5NWU1OTAyMg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OTUyZTYwYzk1MDE4ZGNkMmEwZjlmYWZlMTljMWE3NWM2NjE0MzI0YTY1M2Yw
|
10
|
+
MmUyM2Y0NzViNWYyYTM2ODA4MTg2MmI0OWQ2OGZmZjNjMDEwNzUxMTlmMjhl
|
11
|
+
YjdlYzc3ZjZmMDM1OGQwOTdjMzAzNTY2ZTNmMTM1MjI0YzQ3MWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjhlZmY1ZjQ2ZWY4YzYxN2Q1ZTcyMDRmZGE1NWY1ZTFmZWRhMTYzY2JhODA4
|
14
|
+
N2E5ZjAzOGNlOTUyNjE2OTk2M2NhZDA5MDY0MTM3MzE0MTlmNTRkNmEwNTE5
|
15
|
+
ZmFlOWEzYzg5ZWY4NTQ2NWQ3YzA0NWFhY2EyOGJmMGU1ZWQ5OWQ=
|
@@ -6,23 +6,24 @@ class XirrNewtonCalculator
|
|
6
6
|
# init_rate: (Fixnum, Bignum)
|
7
7
|
# max_iteration: (Fixnum)
|
8
8
|
|
9
|
-
|
9
|
+
FlowStruct = Struct.new(:amount, :diff_date)
|
10
|
+
EPS = 10 ** -7
|
10
11
|
|
11
12
|
def initialize(flows, init_rate, max_iteration=10_000)
|
12
13
|
initial_date = Date.parse flows[0].date.to_s
|
13
14
|
@flows = flows.collect do |flow|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
FlowStruct.new(
|
16
|
+
flow.amount,
|
17
|
+
(Date.parse(flow.date.to_s) - initial_date) / 365.0
|
18
|
+
)
|
18
19
|
end
|
19
20
|
@x_n = init_rate
|
20
21
|
@max_iteration = max_iteration
|
21
22
|
end
|
22
23
|
|
23
24
|
def calculate(eps = EPS)
|
24
|
-
f(@x_n)
|
25
25
|
@max_iteration.times do
|
26
|
+
f(@x_n)
|
26
27
|
break if @f_xn.abs < eps
|
27
28
|
@x_n = next_value(@x_n)
|
28
29
|
end
|
@@ -34,18 +35,18 @@ class XirrNewtonCalculator
|
|
34
35
|
# Argument X_n
|
35
36
|
# Returns X_n+1
|
36
37
|
def next_value(x)
|
37
|
-
x -
|
38
|
+
x - @f_xn.to_f / dfdx(x)
|
38
39
|
end
|
39
40
|
|
40
41
|
def dfdx(x)
|
41
42
|
@flows[1..-1].inject(0) do |result, flow|
|
42
|
-
result += flow
|
43
|
+
result += flow.amount * (-flow.diff_date) / ((1.0 + x) ** (flow.diff_date + 1.0))
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
47
|
def f(x)
|
47
48
|
@f_xn = @flows.inject(0) do |result, flow|
|
48
|
-
result += flow
|
49
|
+
result += flow.amount / ((1.0 + x) ** flow.diff_date)
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
@@ -61,7 +61,7 @@ describe "XirrNewtonCalculator" do
|
|
61
61
|
|
62
62
|
it "returns proper value for x=1" do
|
63
63
|
xirr_calculator.stub(dfdx: 2.0)
|
64
|
-
xirr_calculator.
|
64
|
+
xirr_calculator.instance_variable_set(:@f_xn, 1)
|
65
65
|
expect(xirr_calculator.send(:next_value,1)).to eq 0.5
|
66
66
|
end
|
67
67
|
end
|