xirr_newton_calculator 0.0.4 → 0.0.5

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.
@@ -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: