xirr_newton_calculator 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,30 @@
1
1
  class XirrNewtonCalculator
2
- # Calculate Xirr using Newton Raphson
3
-
4
- # Arguments
5
- # flows: (Array)
6
- # init_rate: (Fixnum, Bignum)
7
- # max_iteration: (Fixnum)
8
-
9
-
10
- EPS = 10 ** -7
11
-
12
- attr_writer :f_xn
13
-
14
- def initialize(flows, init_rate, max_iteration=1000)
15
- @flows = flows
16
- @x_n = init_rate
17
- @max_iteration = max_iteration
2
+ # Calculate Xirr using Newton Raphson
3
+
4
+ # Arguments
5
+ # flows: (Array)
6
+ # init_rate: (Fixnum, Bignum)
7
+ # max_iteration: (Fixnum)
8
+
9
+ EPS = 10 ** -10
10
+
11
+ def initialize(flows, init_rate, max_iteration=10_000)
12
+ initial_date = Date.parse flows[0].date.to_s
13
+ @flows = flows.collect do |flow|
14
+ {
15
+ amount: flow.amount,
16
+ diff_date: (Date.parse(flow.date.to_s) - initial_date) / 365.0
17
+ }
18
+ end
19
+ @x_n = init_rate
20
+ @max_iteration = max_iteration
18
21
  end
19
22
 
20
23
  def calculate
21
- @f_xn = f(@x_n)
22
- iteration = 0
23
- while @f_xn.abs >= EPS && iteration <= @max_iteration
24
- @f_xn = f(@x_n)
25
- @x_n = next_value(@x_n)
26
- iteration += 1
24
+ f(@x_n)
25
+ @max_iteration.times do
26
+ break if @f_xn.abs < EPS
27
+ @x_n = next_value(@x_n)
27
28
  end
28
29
  @x_n
29
30
  end
@@ -33,24 +34,18 @@ class XirrNewtonCalculator
33
34
  # Argument X_n
34
35
  # Returns X_n+1
35
36
  def next_value(x)
36
- x - @f_xn.to_f/dfdx(x)
37
+ x - f(x) / dfdx(x)
37
38
  end
38
39
 
39
40
  def dfdx(x)
40
- @flows[1..-1].inject(0) do |result, flow|
41
- diff_date = (Date.parse(flow.date.to_s) - Date.parse(@flows[0].date.to_s))/365
42
- result += flow.amount * (-diff_date) / ((1.0 + x) ** (diff_date + 1))
43
- end
41
+ @flows[1..-1].inject(0) do |result, flow|
42
+ result += flow[:amount] * (-flow[:diff_date]) / ((1.0 + x) ** (flow[:diff_date] + 1.0))
43
+ end
44
44
  end
45
45
 
46
46
  def f(x)
47
- @f_xn = @flows.inject(0) do |result, flow|
48
- diff_date = (Date.parse(flow.date.to_s) - Date.parse(@flows[0].date.to_s))/365
49
- result += flow.amount / ((1 + x) ** diff_date)
50
- end
51
- end
52
-
53
- def discount_factor_to_irr (disc_fac)
54
- 1.0/disc_fac - 1
47
+ @f_xn = @flows.inject(0) do |result, flow|
48
+ result += flow[:amount] / ((1.0 + x) ** flow[:diff_date])
49
+ end
55
50
  end
56
51
  end
@@ -60,8 +60,8 @@ describe "XirrNewtonCalculator" do
60
60
  end
61
61
 
62
62
  it "returns proper value for x=1" do
63
- xirr_calculator.stub(dfdx: 2)
64
- xirr_calculator.f_xn = 1
63
+ xirr_calculator.stub(dfdx: 2.0)
64
+ xirr_calculator.stub(f: 1.0)
65
65
  expect(xirr_calculator.send(:next_value,1)).to eq 0.5
66
66
  end
67
67
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xirr_newton_calculator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: