finrb 0.0.1 → 0.1.1

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
  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