xirr 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 408c3bf957bc9651c987e8677e997866cfd170bc
4
- data.tar.gz: 7b4ffaef9837569c22bd86f97a878b172d3284c9
3
+ metadata.gz: 474f38451b70bce0aab930fb7d7cefd20d9e3aa5
4
+ data.tar.gz: d9eac1f09cf640bc7cb1eb6c99c5e9cbfb2563a1
5
5
  SHA512:
6
- metadata.gz: 6dc5b68ea4821d65b771e4d9ae697a7a24c456d10eabe33638ebf67d1b9c37273d85c838200ac47539238197350def7e20501a7233fb820ff9adf006c91518af
7
- data.tar.gz: d79dba2d39dfce72b0d5c9fc5844e6768160c83f73019525b2e2c9418866d2efea5d5145b0cca808f0afa73101fe7962bfb04aaa77cf2e28c8e2f38d2b1d0295
6
+ metadata.gz: b6d71d8d7d43f56b11e22544276319623ecfc88ac1d7e6d483984450fcc0f9cb823dc1e34b7a2a167151f85154e9a31811c1c6c4df32fe3cceb6e135e5db671c
7
+ data.tar.gz: 0ca6b6c8d79be51df9c866666ccb9180a41aac883d5f99e972d986ab1145a27dfc2bec6976bdb2c713e8c8e50c0fa433dd372ae1524973ef862808db162d30b9
data/.travis.yml CHANGED
@@ -2,6 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - '2.1.2'
4
4
  - '2.0.0'
5
- - '1.9.3'
5
+ # - '1.9.3'
6
6
  script:
7
7
  - bundle exec rake test_units
data/CHANGE_LOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## Version 0.2.3
2
+
3
+ * Major fix to Bisection Engine.
4
+ * Error if provided method is wrong.
5
+ * Bisection: Initial guess is compared to default limits
6
+ * Transaction converts Time to Date.
7
+
8
+ ## Version 0.2.2
9
+
10
+ * Added Tests.
11
+
1
12
  ## Version 0.2.1
2
13
 
3
14
  * Output is rounded to default precision.
data/lib/xirr/base.rb CHANGED
@@ -5,7 +5,7 @@ module Xirr
5
5
  # Days in a year
6
6
  DAYS_IN_YEAR = Xirr.config.days_in_year.to_f
7
7
  # Epsilon: error margin
8
- EPS = Xirr.config.eps
8
+ EPS = Xirr.config.eps.to_f
9
9
 
10
10
  # Base module for XIRR calculation Methods
11
11
  module Base
@@ -11,8 +11,8 @@ module Xirr
11
11
  def xirr(midpoint = nil)
12
12
 
13
13
  # Initial values
14
- left = BigDecimal.new -0.99, Xirr::PRECISION
15
- right = BigDecimal.new 9.99, Xirr::PRECISION
14
+ left = [BigDecimal.new(-0.99, Xirr::PRECISION), cf.irr_guess].min
15
+ right = [BigDecimal.new(9.99, Xirr::PRECISION), cf.irr_guess + 1].max
16
16
  midpoint ||= cf.irr_guess
17
17
  runs = 0
18
18
 
@@ -20,13 +20,13 @@ module Xirr
20
20
  while ((right - left).abs > Xirr::EPS && runs < Xirr.config.iteration_limit.to_i) do
21
21
 
22
22
  runs += 1
23
- npv_positive?(midpoint) ? right = midpoint : left = midpoint
23
+ npv_positive?(midpoint) == npv_positive?(left) ? left = midpoint : right = midpoint
24
24
  midpoint = format_irr(left, right)
25
25
 
26
26
  end
27
27
 
28
28
  if runs >= Xirr.config.iteration_limit.to_i
29
- raise ArgumentError, 'Did not converge'
29
+ raise ArgumentError, "Did not converge after #{runs} tries."
30
30
  end
31
31
 
32
32
  return midpoint.round Xirr::PRECISION
data/lib/xirr/cashflow.rb CHANGED
@@ -55,10 +55,13 @@ module Xirr
55
55
  # @return [Float]
56
56
  # Finds the XIRR according to the method provided. Default to Bisection
57
57
  def xirr(guess = nil, method = Xirr.config.default_method)
58
- _method = if method == :bisection
59
- Bisection.new(self)
60
- else
61
- NewtonMethod.new(self)
58
+ _method = case method
59
+ when :bisection
60
+ Bisection.new(self)
61
+ when :newton_method
62
+ NewtonMethod.new(self)
63
+ else
64
+ raise ArgumentError, "There is no #{method} method"
62
65
  end
63
66
  _method.send :xirr, guess if valid?
64
67
  end
data/lib/xirr/config.rb CHANGED
@@ -6,7 +6,8 @@ module Xirr
6
6
  eps: '1.0e-12',
7
7
  days_in_year: 365,
8
8
  iteration_limit: 100,
9
- precision: 6
9
+ precision: 6,
10
+ default_method: :bisection
10
11
  }
11
12
 
12
13
  # Iterates trhough default values and sets in config
@@ -2,8 +2,7 @@ module Xirr
2
2
 
3
3
  # A unit of the Cashflow.
4
4
  class Transaction
5
- attr_reader :amount
6
- attr_accessor :date
5
+ attr_reader :amount, :date
7
6
 
8
7
  # @example
9
8
  # Transaction.new -1000, date: Date.now
@@ -19,6 +18,13 @@ module Xirr
19
18
  end
20
19
  end
21
20
 
21
+ # Sets the date
22
+ # @param value [Date, Time]
23
+ # @return [Date]
24
+ def date=(value)
25
+ @date = value.kind_of?(Time) ? value.to_date : value
26
+ end
27
+
22
28
  # Sets the amount
23
29
  # @param value [Numeric]
24
30
  # @return [Float]
data/lib/xirr/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Xirr
2
2
  # Version of the Gem
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.3"
4
4
  end
@@ -10,6 +10,36 @@ describe 'Cashflows' do
10
10
  @cf << Transaction.new(-6000, date: '1995-01-01'.to_date)
11
11
  end
12
12
 
13
+ it 'with a wrong method is invalid' do
14
+ assert_raises(ArgumentError) { @cf.xirr(nil, :no_method) }
15
+ end
16
+
17
+ it 'has an Internal Rate of Return on Bisection Method' do
18
+ assert_equal '0.225683'.to_f, @cf.xirr
19
+ end
20
+
21
+ it 'has an Internal Rate of Return on Bisection Method using a Guess' do
22
+ assert_equal '0.225683'.to_f, @cf.xirr(0.15)
23
+ end
24
+
25
+ it 'has an Internal Rate of Return on Newton Method' do
26
+ assert_equal '0.225683'.to_f, @cf.xirr(nil, :newton_method)
27
+ end
28
+
29
+ it 'has an educated guess' do
30
+ assert_equal '0.208'.to_f, @cf.irr_guess
31
+ end
32
+ end
33
+
34
+
35
+ describe 'of an inverted ok investment' do
36
+ before(:all) do
37
+ @cf = Cashflow.new
38
+ @cf << Transaction.new(-1000, date: '1985-01-01'.to_date)
39
+ @cf << Transaction.new(600, date: '1990-01-01'.to_date)
40
+ @cf << Transaction.new(6000, date: '1995-01-01'.to_date)
41
+ end
42
+
13
43
  it 'has an Internal Rate of Return on Bisection Method' do
14
44
  assert_equal '0.225683'.to_f, @cf.xirr
15
45
  end
@@ -38,12 +68,9 @@ describe 'Cashflows' do
38
68
  assert_equal '1.0597572345993451e+284'.to_f, @cf.xirr
39
69
  end
40
70
 
41
- =begin
42
- # FIXME Check why limit is not being enforced
43
- it 'has an Internal Rate of Return on Bisection Method using a Guess' do
44
- assert_equal '0.225683'.to_f, @cf.xirr(0.15)
71
+ it 'has an Internal Rate of Return on Bisection Method using a bad Guess' do
72
+ assert_raises(ArgumentError) { @cf.xirr(0.15) }
45
73
  end
46
- =end
47
74
 
48
75
  it 'has an Internal Rate of Return on Newton Method' do
49
76
  assert_equal '1.0597572345993451e+284'.to_f, @cf.xirr(nil, :newton_method)
@@ -65,6 +92,10 @@ describe 'Cashflows' do
65
92
  assert_raises(ArgumentError) { @cf.valid? }
66
93
  end
67
94
 
95
+ it 'with a wrong method is invalid' do
96
+ assert_raises(ArgumentError) { @cf.xirr(nil, :no_method) }
97
+ end
98
+
68
99
  it 'raises error when xirr is called' do
69
100
  assert_raises(ArgumentError) { @cf.xirr }
70
101
  end
data/xirr.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency 'bundler', '~> 1.6'
22
22
  spec.add_development_dependency 'rake', '~> 10'
23
23
 
24
- spec.required_ruby_version = '>=1.9'
24
+ spec.required_ruby_version = '>=2.0'
25
25
  spec.add_dependency 'activesupport', '~> 4.0'
26
26
  spec.add_development_dependency 'minitest', '~> 5.4'
27
27
  spec.add_development_dependency 'coveralls', '~> 0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xirr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - tubedude
@@ -120,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - '>='
122
122
  - !ruby/object:Gem::Version
123
- version: '1.9'
123
+ version: '2.0'
124
124
  required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  requirements:
126
126
  - - '>='