financial_calculator 2.1.0 → 3.0.0

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.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: financial_calculator
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Falzone
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-25 00:00:00.000000000 Z
11
+ date: 2018-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: flt
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.16.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: The financial calculator library provides a Ruby interface for performing
126
140
  common financial calculations (NPV, IRR, etc.).
127
141
  email: michael.falzone@gmail.com
@@ -131,34 +145,40 @@ extra_rdoc_files:
131
145
  - README.md
132
146
  - COPYING
133
147
  - COPYING.LESSER
134
- - HISTORY
148
+ - CHANGELOG.md
135
149
  files:
136
150
  - ".gitignore"
137
151
  - ".rbenv-version"
138
152
  - ".travis.yml"
139
153
  - ".yardopts"
154
+ - CHANGELOG.md
140
155
  - COPYING
141
156
  - COPYING.LESSER
142
157
  - Gemfile
143
- - HISTORY
144
158
  - README.md
145
159
  - Rakefile
146
160
  - financial_calculator.gemspec
147
161
  - lib/financial_calculator.rb
148
162
  - lib/financial_calculator/amortization.rb
149
- - lib/financial_calculator/cashflows.rb
150
- - lib/financial_calculator/decimal.rb
163
+ - lib/financial_calculator/irr.rb
164
+ - lib/financial_calculator/npv.rb
165
+ - lib/financial_calculator/pv.rb
151
166
  - lib/financial_calculator/rates.rb
152
167
  - lib/financial_calculator/transaction.rb
153
168
  - lib/financial_calculator/version.rb
169
+ - lib/financial_calculator/xirr.rb
170
+ - lib/financial_calculator/xnpv.rb
154
171
  - spec/amortization_spec.rb
155
- - spec/cashflows_spec.rb
156
- - spec/decimal_spec.rb
172
+ - spec/irr_spec.rb
173
+ - spec/npv_spec.rb
174
+ - spec/pv_spec.rb
157
175
  - spec/rates_spec.rb
158
176
  - spec/spec_helper.rb
159
177
  - spec/transaction/interest_spec.rb
160
178
  - spec/transaction/payment_spec.rb
161
179
  - spec/transaction_spec.rb
180
+ - spec/xirr_spec.rb
181
+ - spec/xnpv_spec.rb
162
182
  homepage: https://rubygems.org/gems/financial_calculator
163
183
  licenses:
164
184
  - LGPL-3.0
@@ -185,10 +205,13 @@ specification_version: 4
185
205
  summary: A library for financial modelling in Ruby.
186
206
  test_files:
187
207
  - spec/amortization_spec.rb
188
- - spec/cashflows_spec.rb
189
- - spec/decimal_spec.rb
208
+ - spec/irr_spec.rb
209
+ - spec/npv_spec.rb
210
+ - spec/pv_spec.rb
190
211
  - spec/rates_spec.rb
191
212
  - spec/spec_helper.rb
192
213
  - spec/transaction/interest_spec.rb
193
214
  - spec/transaction/payment_spec.rb
194
215
  - spec/transaction_spec.rb
216
+ - spec/xirr_spec.rb
217
+ - spec/xnpv_spec.rb
data/HISTORY DELETED
@@ -1,47 +0,0 @@
1
- = Version 2.0.0
2
- 23 Jul 2013
3
-
4
- * Removed Integer#months, Integer#years, and replaced Numeric#to_d by Numeric#to_s in the interest of Rails compatibility.
5
- * Converted unit tests from the shoulda framework to minitest.
6
- * Removed octal numbers in test_cashflow.rb
7
- * Thanks to @thadd, @bramswenson, and @xpe for their contributions to this release!
8
-
9
- = Version 1.1.2
10
- 16 Jun 2012
11
-
12
- * Bugfix: Array#irr and Array#xirr check for a valid sequence of cash flows.
13
- * Bugfix: Integer#months and Integer#years no longer collide with Rails methods.
14
-
15
- = Version 1.1.0
16
- 11 Sep 2011
17
-
18
- * Added XNPV and XIRR functions, with basic testing.
19
- * Bugfix: Array#sum no longer collides with the Array#sum defined in Rails.
20
- * Bugfix: Numeric#amortize now correctly calls Finance::Amortization#new.
21
-
22
- = Version 1.0.0
23
- 20 Jul 2011
24
-
25
- * Moved to Ruby 1.9.
26
- * All classes are now contained within the +Finance+ namespace.
27
- * LOTS of additional documentation and examples.
28
- * Introduced _shoulda_ for unit tests, to make things a little more readable.
29
- * Bugfix: The +amortize+ Numeric method now accepts a variable number of rates.
30
- * Some code refactoring and clean-up for a small performance increase.
31
-
32
- = Version 0.2.0
33
- 28 Jun 2011
34
-
35
- * Added support for adjustable rate mortgages.
36
- * Added support for additional payments.
37
-
38
- = Version 0.1.1
39
- 21 Jun 2011
40
-
41
- * Code examples in README now display correctly in the online documentation.
42
-
43
- = Version 0.1.0
44
- 21 Jun 2011
45
-
46
- * Support for fixed-rate mortgage amortization.
47
- * NPV, IRR array methods for cash flow analysis.
@@ -1,127 +0,0 @@
1
- require_relative 'decimal'
2
- require_relative 'rates'
3
-
4
- require 'bigdecimal'
5
- require 'bigdecimal/newton'
6
- include Newton
7
-
8
- module FinancialCalculator
9
- # Provides methods for working with cash flows (collections of transactions)
10
- # @api public
11
- module Cashflow
12
- # Base class for working with Newton's Method.
13
- # @api private
14
- class Function
15
- values = {
16
- eps: "1.0e-16",
17
- one: "1.0",
18
- two: "2.0",
19
- ten: "10.0",
20
- zero: "0.0"
21
- }
22
-
23
- values.each do |key, value|
24
- define_method key do
25
- BigDecimal(value)
26
- end
27
- end
28
-
29
- def initialize(transactions, function)
30
- @transactions = transactions
31
- @function = function
32
- end
33
-
34
- def values(x)
35
- value = @transactions.send(@function, Flt::DecNum.new(x[0].to_s))
36
- [ BigDecimal(value.to_s) ]
37
- end
38
- end
39
-
40
- # calculate the internal rate of return for a sequence of cash flows
41
- # @return [DecNum] the internal rate of return
42
- # @example
43
- # [-4000,1200,1410,1875,1050].irr #=> 0.143
44
- # @see http://en.wikipedia.org/wiki/Internal_rate_of_return
45
- # @api public
46
- def irr
47
- # Make sure we have a valid sequence of cash flows.
48
- positives, negatives = self.partition{ |i| i >= 0 }
49
- if positives.empty? || negatives.empty?
50
- raise ArgumentError, "Calculation does not converge."
51
- end
52
-
53
- func = Function.new(self, :npv)
54
- rate = [ func.one ]
55
- nlsolve( func, rate )
56
- rate[0]
57
- end
58
-
59
- def method_missing(name, *args, &block)
60
- return self.inject(:+) if name.to_s == "sum"
61
- super
62
- end
63
-
64
- # calculate the net present value of a sequence of cash flows
65
- # @return [DecNum] the net present value
66
- # @param [Numeric] rate the discount rate to be applied
67
- # @example
68
- # [-100.0, 60, 60, 60].npv(0.1) #=> 49.211
69
- # @see http://en.wikipedia.org/wiki/Net_present_value
70
- # @api public
71
- def npv(rate)
72
- self.collect! { |entry| Flt::DecNum.new(entry.to_s) }
73
-
74
- rate, total = Flt::DecNum.new(rate.to_s), Flt::DecNum.new(0.to_s)
75
- self.each_with_index do |cashflow, index|
76
- total += cashflow / (1 + rate) ** index
77
- end
78
-
79
- total
80
- end
81
-
82
- # calculate the internal rate of return for a sequence of cash flows with dates
83
- # @return [Rate] the internal rate of return
84
- # @example
85
- # @transactions = []
86
- # @transactions << Transaction.new(-1000, :date => Time.new(1985,01,01))
87
- # @transactions << Transaction.new( 600, :date => Time.new(1990,01,01))
88
- # @transactions << Transaction.new( 600, :date => Time.new(1995,01,01))
89
- # @transactions.xirr(0.6) #=> Rate("0.024851", :apr, :compounds => :annually)
90
- # @api public
91
- def xirr(iterations=100)
92
- # Make sure we have a valid sequence of cash flows.
93
- positives, negatives = self.partition{ |t| t.amount >= 0 }
94
- if positives.empty? || negatives.empty?
95
- raise ArgumentError, "Calculation does not converge."
96
- end
97
-
98
- func = Function.new(self, :xnpv)
99
- rate = [ func.one ]
100
- nlsolve( func, rate )
101
- Rate.new(rate[0], :apr, :compounds => :annually)
102
- end
103
-
104
- # calculate the net present value of a sequence of cash flows
105
- # @return [DecNum]
106
- # @example
107
- # @transactions = []
108
- # @transactions << Transaction.new(-1000, :date => Time.new(1985,01,01))
109
- # @transactions << Transaction.new( 600, :date => Time.new(1990,01,01))
110
- # @transactions << Transaction.new( 600, :date => Time.new(1995,01,01))
111
- # @transactions.xnpv(0.6).round(2) #=> -937.41
112
- # @api public
113
- def xnpv(rate)
114
- rate = Flt::DecNum.new(rate.to_s)
115
- start = self[0].date
116
-
117
- self.inject(0) do |sum, t|
118
- n = t.amount / ( (1 + rate) ** ((t.date-start) / Flt::DecNum.new(31536000.to_s))) # 365 * 86400
119
- sum + n
120
- end
121
- end
122
- end
123
- end
124
-
125
- class Array
126
- include FinancialCalculator::Cashflow
127
- end
@@ -1,21 +0,0 @@
1
- require 'rubygems'
2
- require 'flt'
3
- include Flt
4
-
5
- DecNum.context.define_conversion_from(BigDecimal) do |x, context|
6
- DecNum(x.to_s)
7
- end
8
-
9
- DecNum.context.define_conversion_to(BigDecimal) do |x|
10
- BigDecimal.new(x.to_s)
11
- end
12
-
13
- class Numeric
14
- def to_d
15
- if self.instance_of? DecNum
16
- self
17
- else
18
- DecNum self.to_s
19
- end
20
- end
21
- end
@@ -1,66 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- shared_examples_for 'the values do not converge' do
4
- it 'should raise an ArgumentError' do
5
- expect { subject }.to raise_error ArgumentError
6
- end
7
- end
8
-
9
- describe "Cashflows" do
10
- let(:transactions) do
11
- [
12
- Transaction.new(-1000, :date => Time.new(1985, 1, 1)),
13
- Transaction.new( 600, :date => Time.new(1990, 1, 1)),
14
- Transaction.new( 600, :date => Time.new(1995, 1, 1))
15
- ]
16
- end
17
-
18
- describe '#irr' do
19
- let(:flows) { [-4000, 1200, 1410, 1875, 1050] }
20
-
21
- subject { flows.irr.round(3) }
22
-
23
- it { is_expected.to eql D('0.143') }
24
-
25
- context 'when called on an array of Transactions' do
26
- let(:flows) { transactions }
27
-
28
- it 'should raise a NoMethodError' do
29
- expect { subject }.to raise_error NoMethodError
30
- end
31
- end
32
-
33
- context 'when the values do not converge' do
34
- let(:flows) { [10, 20, 30] }
35
- it_behaves_like 'the values do not converge'
36
- end
37
- end
38
-
39
- describe '#npv' do
40
- let(:flows) { [-100.0, 60, 60, 60] }
41
-
42
- subject { flows.npv(0.1).round(3) }
43
-
44
- it { is_expected.to eql D('49.211') }
45
- end
46
-
47
- describe '#xirr' do
48
- let(:xirr_transactions) { transactions }
49
-
50
- subject { xirr_transactions.xirr.effective.round(6) }
51
-
52
- it { is_expected.to eql D('0.024851') }
53
-
54
- context 'when the values do not converge' do
55
- let(:xirr_transactions) { transactions[1,3] }
56
-
57
- it_behaves_like 'the values do not converge'
58
- end
59
- end
60
-
61
- describe '#xnpv' do
62
- subject { transactions.xnpv(0.6).round(2) }
63
-
64
- it { is_expected.to eql -937.41 }
65
- end
66
- end
@@ -1,24 +0,0 @@
1
- require_relative 'spec_helper'
2
- require_relative '../lib/financial_calculator/decimal.rb'
3
-
4
- describe "Numeric" do
5
- let(:dec_num) { D('12.123') }
6
-
7
- subject { dec_num }
8
-
9
- describe 'it converts to a BigDecimal' do
10
- subject { dec_num.convert_to BigDecimal }
11
-
12
- it { is_expected.to be_a BigDecimal }
13
- end
14
-
15
- describe '#to_d' do
16
- context 'when already a Flt::DecNum' do
17
- let(:dec_num) { D('12.123') }
18
-
19
- subject { dec_num.to_d }
20
-
21
- it { is_expected.to be_a Flt::DecNum }
22
- end
23
- end
24
- end