finrb 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b72e5d95b3aa441749bbee34bca785ca86672b0cfcc88c93d1112f7e23711c92
4
- data.tar.gz: ccafe9aadb9b906f8666f3367bae4c197f72590e09271da4f58e363dff528aaf
3
+ metadata.gz: b999dd6faadf24d9020be497526bbf8a2614fbcc994232e84b8d2cc693eb283f
4
+ data.tar.gz: 5611c3ab6cc8abc69e95fdb58e3d5913c1e47eaaf599f0aa097ba82f1377893b
5
5
  SHA512:
6
- metadata.gz: 887939c488c423d841e409688d40f1c064591a1e52548787d5f20424ca63c50fc9eba081388dcf73700a2f0e71708ed3873dd348d1a4e284d1e23a4efb4d7c7a
7
- data.tar.gz: 3f0174c556ac2760e01235e891cfeb8665a3f81eac55c41137ae08d9aa1e2c1534b401c23b5dd24c30df97797d04d6dc5c6125830857e1292d5e6fd013767a12
6
+ metadata.gz: a631f3777e169081228e91e08f94835780e479a63604828a89c649cf8ca0303d2ef2a9ad11de60376c14bc14d2652e700455523d232d45d4581ddb06b430e8c4
7
+ data.tar.gz: 74d40ad091e7cc2756e58371ea53bf10ade3b5e6573be78813cfadfb90c67e54d7595bc57947d4b9f5b5b74fb9423dc835a10541144a65b9747c0017f6cb297f
data/CHANGELOG.md CHANGED
@@ -1,74 +1,89 @@
1
1
  # finrb changelog
2
2
 
3
+ ## 0.1.1
4
+
5
+ - documentation additions and fixes
6
+ - refactoring
7
+ - bugfixes and test suite migration to rspec
8
+
9
+ ## 0.1.0
10
+
11
+ - sets ruby dependency to >= 3
12
+ - update/fix dependencies
13
+ - adds docker files for develop/test
14
+ - fix license files
15
+ - port [FinCal](https://github.com/felixfan/FinCal) library to ruby.
16
+ - readme update, api reference file outside main readme.
17
+
3
18
  # Finance gem changelog
4
19
 
5
20
  ## Version 2.0.2
6
21
 
7
22
  19 March 2019
8
23
 
9
- * Fix BigDecimal deprecation warning
10
- * Support Ruby 2.6.2
11
- * Update dependencies
24
+ - Fix BigDecimal deprecation warning
25
+ - Support Ruby 2.6.2
26
+ - Update dependencies
12
27
 
13
28
  ## Version 2.0.1
14
29
 
15
30
  17 October 2017
16
31
 
17
- * Added Support for configuration file to set up default eps and guess for IRR & XIRR
18
- * Added guess rate for IRR & XIRR
19
- * NVP now does not change the given cashflow array
32
+ - Added Support for configuration file to set up default eps and guess for IRR & XIRR
33
+ - Added guess rate for IRR & XIRR
34
+ - NVP now does not change the given cashflow array
20
35
 
21
36
  ## Version 2.0.0
22
37
 
23
38
  23 Jul 2013
24
39
 
25
- * Removed Integer#months, Integer#years, and replaced Numeric#to_d by Numeric#to_s in the interest of Rails compatibility.
26
- * Converted unit tests from the shoulda framework to minitest.
27
- * Removed octal numbers in test_cashflow.rb
28
- * Thanks to @thadd, @bramswenson, and @xpe for their contributions to this release!
40
+ - Removed Integer#months, Integer#years, and replaced Numeric#to_d by Numeric#to_s in the interest of Rails compatibility.
41
+ - Converted unit tests from the shoulda framework to minitest.
42
+ - Removed octal numbers in test_cashflow.rb
43
+ - Thanks to @thadd, @bramswenson, and @xpe for their contributions to this release!
29
44
 
30
45
  ## Version 1.1.2
31
46
 
32
47
  16 Jun 2012
33
48
 
34
- * Bugfix: Array#irr and Array#xirr check for a valid sequence of cash flows.
35
- * Bugfix: Integer#months and Integer#years no longer collide with Rails methods.
49
+ - Bugfix: Array#irr and Array#xirr check for a valid sequence of cash flows.
50
+ - Bugfix: Integer#months and Integer#years no longer collide with Rails methods.
36
51
 
37
52
  ## Version 1.1.0
38
53
 
39
54
  11 Sep 2011
40
55
 
41
- * Added XNPV and XIRR functions, with basic testing.
42
- * Bugfix: Array#sum no longer collides with the Array#sum defined in Rails.
43
- * Bugfix: Numeric#amortize now correctly calls Finrb::Amortization#new.
56
+ - Added XNPV and XIRR functions, with basic testing.
57
+ - Bugfix: Array#sum no longer collides with the Array#sum defined in Rails.
58
+ - Bugfix: Numeric#amortize now correctly calls Finrb::Amortization#new.
44
59
 
45
60
  ## Version 1.0.0
46
61
 
47
62
  20 Jul 2011
48
63
 
49
- * Moved to Ruby 1.9.
50
- * All classes are now contained within the +Finrb+ namespace.
51
- * LOTS of additional documentation and examples.
52
- * Introduced _shoulda_ for unit tests, to make things a little more readable.
53
- * Bugfix: The +amortize+ Numeric method now accepts a variable number of rates.
54
- * Some code refactoring and clean-up for a small performance increase.
64
+ - Moved to Ruby 1.9.
65
+ - All classes are now contained within the +Finrb+ namespace.
66
+ - LOTS of additional documentation and examples.
67
+ - Introduced _shoulda_ for unit tests, to make things a little more readable.
68
+ - Bugfix: The +amortize+ Numeric method now accepts a variable number of rates.
69
+ - Some code refactoring and clean-up for a small performance increase.
55
70
 
56
71
  ## Version 0.2.0
57
72
 
58
73
  28 Jun 2011
59
74
 
60
- * Added support for adjustable rate mortgages.
61
- * Added support for additional payments.
75
+ - Added support for adjustable rate mortgages.
76
+ - Added support for additional payments.
62
77
 
63
78
  ## Version 0.1.1
64
79
 
65
80
  21 Jun 2011
66
81
 
67
- * Code examples in README now display correctly in the online documentation.
82
+ - Code examples in README now display correctly in the online documentation.
68
83
 
69
84
  ## Version 0.1.0
70
85
 
71
86
  21 Jun 2011
72
87
 
73
- * Support for fixed-rate mortgage amortization.
74
- * NPV, IRR array methods for cash flow analysis.
88
+ - Support for fixed-rate mortgage amortization.
89
+ - NPV, IRR array methods for cash flow analysis.
data/README.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # finrb
2
2
 
3
+ [![CI](https://github.com/ncs1/finrb/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ncs1/finrb/actions/workflows/ci.yml)
4
+ [![CodeQL](https://github.com/ncs1/finrb/actions/workflows/codeql.yml/badge.svg)](https://github.com/ncs1/finrb/actions/workflows/codeql.yml)
5
+ [![RuboCop](https://github.com/ncs1/finrb/actions/workflows/rubocop.yml/badge.svg)](https://github.com/ncs1/finrb/actions/workflows/rubocop.yml)
6
+
7
+ <!-- TOC depthfrom:2 -->
8
+
9
+ - [Overview](#overview)
10
+ - [Features](#features)
11
+ - [Configuration](#configuration)
12
+ - [API and examples](#api-and-examples)
13
+ - [Resources](#resources)
14
+ - [Acknowledgements](#acknowledgements)
15
+ - [License](#license)
16
+
17
+ <!-- /TOC -->
18
+
3
19
  Ruby gem for financial calculations/modeling.
4
20
 
5
21
  finrb forked from the ruby [finance](https://github.com/Edward-Intelligence/finance) gem.
@@ -10,66 +26,103 @@ finrb forked from the ruby [finance](https://github.com/Edward-Intelligence/fina
10
26
 
11
27
  Currently implemented features include:
12
28
 
13
- * Uses the [flt](https://github.com/jgoizueta/flt) gem to ensure precision decimal arithmetic in all calculations.
14
- * Fixed-rate mortgage amortization (30/360).
15
- * Interest rates
16
- * Various cash flow computations, such as NPV and IRR.
17
- * Adjustable rate mortgage amortization.
18
- * Payment modifications (i.e., how does paying an additional $75 per month affect the amortization?)
19
- * Utils class provides basic financial calculation utilities (ported from R's [FinCal](https://github.com/felixfan/FinCal) library):
20
- * Computing bank discount yield (BDY) for a T-bill
21
- * Computing money market yield (MMY) for a T-bill
22
- * Cash ratio - Liquidity ratios measure the firm's ability to satisfy its short-term obligations as they come due.
23
- * Computing Coefficient of variation
24
- * Cost of goods sold and ending inventory under three methods (FIFO,LIFO,Weighted average)
25
- * Current ratio - Liquidity ratios measure the firm's ability to satisfy its short-term obligations as they come due.
26
- * Depreciation Expense Recognition - double-declining balance (DDB), the most common declining balance method, which applies two times the straight-line rate to the declining balance.
27
- * Debt ratio - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
28
- * Diluted Earnings Per Share
29
- * Computing the rate of return for each period
30
- * Convert stated annual rate to the effective annual rate
31
- * Convert stated annual rate to the effective annual rate with continuous compounding
32
- * Bond-equivalent yield (BEY), 2 x the semiannual discount rate
33
- * Computing HPR, the holding period return
34
- * Equivalent/proportional Interest Rates
35
- * Basic Earnings Per Share
36
- * Financial leverage - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
37
- * Estimate future value (fv)
38
- * Estimate future value of an annuity
39
- * Estimate future value (fv) of a single sum
40
- * Computing the future value of an uneven cash flow series
41
- * Geometric mean return
42
- * Gross profit margin - Evaluate a company's financial performance
43
- * Harmonic mean, average price
44
- * Computing HPR, the holding period return
45
- * Bond-equivalent yield (BEY), 2 x the semiannual discount rate
46
- * Convert holding period return to the effective annual rate
47
- * Computing money market yield (MMY) for a T-bill
48
- * Computing IRR, the internal rate of return
49
- * Calculate the net increase in common shares from the potential exercise of stock options or warrants
50
- * Long-term debt-to-equity - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
51
- * Computing HPR, the holding period return
52
- * Estimate the number of periods
53
- * Net profit margin - Evaluate a company's financial performance
54
- * Computing NPV, the PV of the cash flows less the initial (time = 0) outlay
55
- * Estimate period payment
56
- * Estimate present value (pv)
57
- * Estimate present value (pv) of an annuity
58
- * Estimate present value of a perpetuity
59
- * Estimate present value (pv) of a single sum
60
- * Computing the present value of an uneven cash flow series
61
- * Quick ratio - Liquidity ratios measure the firm's ability to satisfy its short-term obligations as they come due.
62
- * Convert a given norminal rate to a continuous compounded rate
63
- * Convert a given continuous compounded rate to a norminal rate
64
- * Rate of return for a perpetuity
65
- * Computing Sampling error
66
- * Computing Roy's safety-first ratio
67
- * Computing Sharpe Ratio
68
- * Depreciation Expense Recognition - Straight-line depreciation (SL) allocates an equal amount of depreciation each year over the asset's useful life
69
- * Total debt-to-equity - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
70
- * Computing TWRR, the time-weighted rate of return
71
- * Calculate weighted average shares - weighted average number of common shares
72
- * Weighted mean as a portfolio return
29
+ - Uses the [flt](https://github.com/jgoizueta/flt) gem to ensure precision decimal arithmetic in all calculations.
30
+ - Fixed-rate mortgage amortization (30/360).
31
+ - Interest rates
32
+ - Various cash flow computations, such as NPV and IRR.
33
+ - Adjustable rate mortgage amortization.
34
+ - Payment modifications (i.e., how does paying an additional $75 per month affect the amortization?)
35
+ - Utils class provides basic financial calculation utilities (ported from R's [FinCal](https://github.com/felixfan/FinCal) library):
36
+
37
+ - Basic Earnings Per Share
38
+
39
+ - Bond-equivalent yield (BEY), 2 x the semiannual discount rate
40
+
41
+ - Calculate the net increase in common shares from the potential exercise of stock options or warrants
42
+
43
+ - Calculate weighted average shares - weighted average number of common shares
44
+
45
+ - Cash ratio - Liquidity ratios measure the firm's ability to satisfy its short-term obligations as they come due.
46
+
47
+ - Computing Coefficient of variation
48
+
49
+ - Computing HPR, the holding period return
50
+
51
+ - Computing IRR, the internal rate of return
52
+
53
+ - Computing NPV, the PV of the cash flows less the initial (time = 0) outlay
54
+
55
+ - Computing Roy's safety-first ratio
56
+
57
+ - Computing Sampling error
58
+
59
+ - Computing Sharpe Ratio
60
+
61
+ - Computing TWRR, the time-weighted rate of return
62
+
63
+ - Computing bank discount yield (BDY) for a T-bill
64
+
65
+ - Computing money market yield (MMY) for a T-bill
66
+
67
+ - Computing the future value of an uneven cash flow series
68
+
69
+ - Computing the present value of an uneven cash flow series
70
+
71
+ - Computing the rate of return for each period
72
+
73
+ - Convert a given continuous compounded rate to a norminal rate
74
+
75
+ - Convert a given norminal rate to a continuous compounded rate
76
+
77
+ - Convert holding period return to the effective annual rate
78
+
79
+ - Convert stated annual rate to the effective annual rate (with continuous compounding)
80
+
81
+ - Cost of goods sold and ending inventory under three methods (FIFO,LIFO,Weighted average)
82
+
83
+ - Current ratio - Liquidity ratios measure the firm's ability to satisfy its short-term obligations as they come due.
84
+
85
+ - Debt ratio - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
86
+
87
+ - Depreciation Expense Recognition - Straight-line depreciation (SL) allocates an equal amount of depreciation each year over the asset's useful life
88
+
89
+ - Depreciation Expense Recognition - double-declining balance (DDB), the most common declining balance method, which applies two times the straight-line rate to the declining balance.
90
+
91
+ - Diluted Earnings Per Share
92
+
93
+ - Equivalent/proportional Interest Rates
94
+
95
+ - Estimate future value (fv) (of a single sum)
96
+
97
+ - Estimate future value of an annuity
98
+
99
+ - Estimate period payment
100
+
101
+ - Estimate present value (pv) (of a single sum) (of an annuity)
102
+
103
+ - Estimate present value of a perpetuity
104
+
105
+ - Estimate the number of periods
106
+
107
+ - Financial leverage - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
108
+
109
+ - Geometric mean return
110
+
111
+ - Gross profit margin - Evaluate a company's financial performance
112
+
113
+ - Harmonic mean, average price
114
+
115
+ - Long-term debt-to-equity - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
116
+
117
+ - Net profit margin - Evaluate a company's financial performance
118
+
119
+ - Quick ratio - Liquidity ratios measure the firm's ability to satisfy its short-term obligations as they come due.
120
+
121
+ - Rate of return for a perpetuity
122
+
123
+ - Total debt-to-equity - Solvency ratios measure the firm's ability to satisfy its long-term obligations.
124
+
125
+ - Weighted mean as a portfolio return
73
126
 
74
127
  ### Configuration
75
128
 
@@ -90,9 +143,14 @@ See [api.md](docs/api.md)
90
143
 
91
144
  ## Resources
92
145
 
93
- * [RubyGems Page](https://rubygems.org/gems/finrb)
94
- * [Source Code](http://github.com/ncs1/finrb)
95
- * [Bug Tracker](https://github.com/ncs1/finrb/issues)
146
+ - [RubyGems Page](https://rubygems.org/gems/finrb)
147
+ - [Source Code](https://github.com/ncs1/finrb)
148
+ - [Bug Tracker](https://github.com/ncs1/finrb/issues)
149
+
150
+ ## Acknowledgements
151
+
152
+ - Martin Bjeldbak Madsen (@martinbjeldbak), Bill Kranec (@wkranec) - original [finance](https://github.com/Edward-Intelligence/finance) gem maintainers.
153
+ - Yanhui Fan (@felixfan) - maintainer of [FinCal](https://github.com/felixfan/FinCal) library.
96
154
 
97
155
  ## License
98
156
 
@@ -34,6 +34,26 @@ module Finrb
34
34
  # @api public
35
35
  attr_reader :rates
36
36
 
37
+ # @return [DecNum] the periodic payment due on a loan
38
+ # @param [DecNum] principal the initial amount of the loan or investment
39
+ # @param [Rate] rate the applicable interest rate (per period)
40
+ # @param [Integer] periods the number of periods needed for repayment
41
+ # @note in most cases, you will probably want to use rate.monthly when calling this function outside of an Amortization instance.
42
+ # @example
43
+ # rate = Rate.new(0.0375, :apr, :duration => (30 * 12))
44
+ # rate.duration #=> 360
45
+ # Amortization.payment(200000, rate.monthly, rate.duration) #=> DecNum('-926.23')
46
+ # @see https://en.wikipedia.org/wiki/Amortization_calculator
47
+ # @api public
48
+ def self.payment(principal, rate, periods)
49
+ if rate.zero?
50
+ # simplified formula to avoid division-by-zero when interest rate is zero
51
+ -(principal / periods).round(2)
52
+ else
53
+ -(principal * (rate + (rate / (((rate + 1)**periods) - 1)))).round(2)
54
+ end
55
+ end
56
+
37
57
  # create a new Amortization instance
38
58
  # @return [Amortization]
39
59
  # @param [DecNum] principal the initial amount of the loan or investment
@@ -54,7 +74,7 @@ module Finrb
54
74
 
55
75
  # compare two Amortization instances
56
76
  # @return [Numeric] -1, 0, or +1
57
- # @param [Amortization]
77
+ # @param [Amortization] other
58
78
  # @api public
59
79
  def ==(other)
60
80
  (principal == other.principal) && (rates == other.rates) && (payments == other.payments)
@@ -67,7 +87,7 @@ module Finrb
67
87
  # amt.additional_payments #=> [DecNum('-100.00'), DecNum('-100.00'), ... ]
68
88
  # @api public
69
89
  def additional_payments
70
- @transactions.select(&:payment?).map(&:difference)
90
+ @transactions.filter_map { |trans| trans.difference if trans.payment? }
71
91
  end
72
92
 
73
93
  # amortize the balance of loan with the given interest rate
@@ -155,27 +175,7 @@ module Finrb
155
175
  # amt.interest[0,6].sum #=> DecNum('5603.74')
156
176
  # @api public
157
177
  def interest
158
- @transactions.select(&:interest?).map(&:amount)
159
- end
160
-
161
- # @return [DecNum] the periodic payment due on a loan
162
- # @param [DecNum] principal the initial amount of the loan or investment
163
- # @param [Rate] rate the applicable interest rate (per period)
164
- # @param [Integer] periods the number of periods needed for repayment
165
- # @note in most cases, you will probably want to use rate.monthly when calling this function outside of an Amortization instance.
166
- # @example
167
- # rate = Rate.new(0.0375, :apr, :duration => (30 * 12))
168
- # rate.duration #=> 360
169
- # Amortization.payment(200000, rate.monthly, rate.duration) #=> DecNum('-926.23')
170
- # @see http://en.wikipedia.org/wiki/Amortization_calculator
171
- # @api public
172
- def self.payment(principal, rate, periods)
173
- if rate.zero?
174
- # simplified formula to avoid division-by-zero when interest rate is zero
175
- -(principal / periods).round(2)
176
- else
177
- -(principal * (rate + (rate / (((1 + rate)**periods) - 1)))).round(2)
178
- end
178
+ @transactions.filter_map { |trans| trans.amount if trans.interest? }
179
179
  end
180
180
 
181
181
  # @return [Array] the amount of the payment in each period
@@ -185,7 +185,7 @@ module Finrb
185
185
  # amt.payments.sum #=> DecNum('-500163.94')
186
186
  # @api public
187
187
  def payments
188
- @transactions.select(&:payment?).map(&:amount)
188
+ @transactions.filter_map { |trans| trans.amount if trans.payment? }
189
189
  end
190
190
  end
191
191
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'config'
3
4
  require_relative 'decimal'
4
5
  require_relative 'rates'
5
6
 
@@ -40,10 +41,10 @@ module Finrb
40
41
 
41
42
  # calculate the internal rate of return for a sequence of cash flows
42
43
  # @return [DecNum] the internal rate of return
43
- # @param [Numeric] Initial guess rate, Defaults to 1.0
44
+ # @param [Numeric] guess Initial guess rate, Defaults to 1.0
44
45
  # @example
45
46
  # [-4000,1200,1410,1875,1050].irr #=> 0.143
46
- # @see http://en.wikipedia.org/wiki/Internal_rate_of_return
47
+ # @see https://en.wikipedia.org/wiki/Internal_rate_of_return
47
48
  # @api public
48
49
  def irr(guess = nil)
49
50
  # Make sure we have a valid sequence of cash flows.
@@ -67,7 +68,7 @@ module Finrb
67
68
  # @param [Numeric] rate the discount rate to be applied
68
69
  # @example
69
70
  # [-100.0, 60, 60, 60].npv(0.1) #=> 49.211
70
- # @see http://en.wikipedia.org/wiki/Net_present_value
71
+ # @see https://en.wikipedia.org/wiki/Net_present_value
71
72
  # @api public
72
73
  def npv(rate)
73
74
  cashflows = map { |entry| Flt::DecNum.new(entry.to_s) }
@@ -75,7 +76,7 @@ module Finrb
75
76
  rate = Flt::DecNum.new(rate.to_s)
76
77
  total = Flt::DecNum.new(0.to_s)
77
78
  cashflows.each_with_index do |cashflow, index|
78
- total += cashflow / ((1 + rate)**index)
79
+ total += cashflow / ((rate + 1)**index)
79
80
  end
80
81
 
81
82
  total
@@ -120,7 +121,7 @@ module Finrb
120
121
  rate = Flt::DecNum.new(rate.to_s)
121
122
 
122
123
  sum do |t|
123
- t.amount / ((1 + rate)**(date_diff(start, t.date) / days_in_period))
124
+ t.amount / ((rate + 1)**(date_diff(start, t.date) / days_in_period))
124
125
  end
125
126
  end
126
127
 
@@ -152,9 +153,7 @@ module Finrb
152
153
 
153
154
  def valid(guess)
154
155
  if guess.nil?
155
- unless Finrb.config.guess.is_a?(Numeric)
156
- raise(ArgumentError, 'Invalid Guess. Default guess should be a [Numeric] value.')
157
- end
156
+ raise(ArgumentError, 'Invalid Guess. Default guess should be a [Numeric] value.') unless Finrb.config.guess.is_a?(Numeric)
158
157
 
159
158
  Finrb.config.guess
160
159
  else
data/lib/finrb/decimal.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubygems'
4
3
  require 'flt'
4
+ require 'rubygems'
5
5
  include Flt
6
6
 
7
7
  DecNum.context.define_conversion_from(BigDecimal) do |x, _context|
@@ -13,7 +13,7 @@ DecNum.context.define_conversion_to(BigDecimal) do |x|
13
13
  end
14
14
 
15
15
  class Numeric
16
- def to_d
16
+ def to_dec
17
17
  if instance_of?(DecNum)
18
18
  self
19
19
  else
data/lib/finrb/rates.rb CHANGED
@@ -8,6 +8,45 @@ module Finrb
8
8
  # @api public
9
9
  class Rate
10
10
  include Comparable
11
+ # Accepted rate types
12
+ TYPES = { apr: 'effective', apy: 'effective', effective: 'effective', nominal: 'nominal' }.freeze
13
+ # convert a nominal interest rate to an effective interest rate
14
+ # @return [DecNum] the effective interest rate
15
+ # @param [Numeric] rate the nominal interest rate
16
+ # @param [Numeric] periods the number of compounding periods per year
17
+ # @example
18
+ # Rate.to_effective(0.05, 4) #=> DecNum('0.05095')
19
+ # @api public
20
+ def self.to_effective(rate, periods)
21
+ rate = Flt::DecNum.new(rate.to_s)
22
+ periods = Flt::DecNum.new(periods.to_s)
23
+
24
+ if periods.infinite?
25
+ rate.exp - 1
26
+ else
27
+ (((rate / periods) + 1)**periods) - 1
28
+ end
29
+ end
30
+
31
+ # convert an effective interest rate to a nominal interest rate
32
+ # @return [DecNum] the nominal interest rate
33
+ # @param [Numeric] rate the effective interest rate
34
+ # @param [Numeric] periods the number of compounding periods per year
35
+ # @example
36
+ # Rate.to_nominal(0.06, 365) #=> DecNum('0.05827')
37
+ # @see https://www.miniwebtool.com/nominal-interest-rate-calculator/
38
+ # @api public
39
+ def self.to_nominal(rate, periods)
40
+ rate = Flt::DecNum.new(rate.to_s)
41
+ periods = Flt::DecNum.new(periods.to_s)
42
+
43
+ if periods.infinite?
44
+ (rate + 1).log
45
+ else
46
+ periods * (((rate + 1)**(1.to_f / periods)) - 1)
47
+ end
48
+ end
49
+
11
50
  # create a new Rate instance
12
51
  # @return [Rate]
13
52
  # @param [Numeric] rate the decimal value of the interest rate
@@ -17,8 +56,8 @@ module Finrb
17
56
  # @option opts [String] :compounds (:monthly) the number of compounding periods per year
18
57
  # @example create a 3.5% APR rate
19
58
  # Rate.new(0.035, :apr) #=> Rate(0.035, :apr)
20
- # @see http://en.wikipedia.org/wiki/Effective_interest_rate
21
- # @see http://en.wikipedia.org/wiki/Nominal_interest_rate
59
+ # @see https://en.wikipedia.org/wiki/Effective_interest_rate
60
+ # @see https://en.wikipedia.org/wiki/Nominal_interest_rate
22
61
  # @api public
23
62
  def initialize(rate, type, opts = {})
24
63
  # Default monthly compounding.
@@ -37,9 +76,6 @@ module Finrb
37
76
  end
38
77
  end
39
78
 
40
- # Accepted rate types
41
- TYPES = { apr: 'effective', apy: 'effective', effective: 'effective', nominal: 'nominal' }.freeze
42
-
43
79
  # @return [Integer] the duration for which the rate is valid, in months
44
80
  # @api public
45
81
  attr_accessor :duration
@@ -52,7 +88,7 @@ module Finrb
52
88
 
53
89
  # compare two Rates, using the effective rate
54
90
  # @return [Numeric] one of -1, 0, +1
55
- # @param [Rate] rate the comparison Rate
91
+ # @param [Rate] other the comparison Rate
56
92
  # @example Which is better, a nominal rate of 15% compounded monthly, or 15.5% compounded semiannually?
57
93
  # r1 = Rate.new(0.15, :nominal) #=> Rate.new(0.160755, :apr)
58
94
  # r2 = Rate.new(0.155, :nominal, :compounds => :semiannually) #=> Rate.new(0.161006, :apr)
@@ -125,43 +161,6 @@ module Finrb
125
161
  @effective = Rate.to_effective(rate, @periods)
126
162
  end
127
163
 
128
- # convert a nominal interest rate to an effective interest rate
129
- # @return [DecNum] the effective interest rate
130
- # @param [Numeric] rate the nominal interest rate
131
- # @param [Numeric] periods the number of compounding periods per year
132
- # @example
133
- # Rate.to_effective(0.05, 4) #=> DecNum('0.05095')
134
- # @api public
135
- def self.to_effective(rate, periods)
136
- rate = Flt::DecNum.new(rate.to_s)
137
- periods = Flt::DecNum.new(periods.to_s)
138
-
139
- if periods.infinite?
140
- rate.exp - 1
141
- else
142
- ((1 + (rate / periods))**periods) - 1
143
- end
144
- end
145
-
146
- # convert an effective interest rate to a nominal interest rate
147
- # @return [DecNum] the nominal interest rate
148
- # @param [Numeric] rate the effective interest rate
149
- # @param [Numeric] periods the number of compounding periods per year
150
- # @example
151
- # Rate.to_nominal(0.06, 365) #=> DecNum('0.05827')
152
- # @see http://www.miniwebtool.com/nominal-interest-rate-calculator/
153
- # @api public
154
- def self.to_nominal(rate, periods)
155
- rate = Flt::DecNum.new(rate.to_s)
156
- periods = Flt::DecNum.new(periods.to_s)
157
-
158
- if periods.infinite?
159
- (rate + 1).log
160
- else
161
- periods * (((1 + rate)**(1 / periods)) - 1)
162
- end
163
- end
164
-
165
164
  private :compounds=, :effective=, :nominal=
166
165
  end
167
166
  end