finrb 0.1.0 → 0.1.2

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.
data/lib/finrb/rates.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "decimal"
3
+ require_relative 'decimal'
4
4
 
5
5
  module Finrb
6
6
  # the Rate class provides an interface for working with interest rates.
@@ -8,6 +8,47 @@ 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
+ public_constant :TYPES
14
+
15
+ # convert a nominal interest rate to an effective interest rate
16
+ # @return [Flt::DecNum] the effective interest rate
17
+ # @param [Numeric] rate the nominal interest rate
18
+ # @param [Numeric] periods the number of compounding periods per year
19
+ # @example
20
+ # Rate.to_effective(0.05, 4) #=> Flt::DecNum('0.05095')
21
+ # @api public
22
+ def self.to_effective(rate, periods)
23
+ rate = Flt::DecNum.new(rate.to_s)
24
+ periods = Flt::DecNum.new(periods.to_s)
25
+
26
+ if periods.infinite?
27
+ rate.exp - 1
28
+ else
29
+ (((rate / periods) + 1)**periods) - 1
30
+ end
31
+ end
32
+
33
+ # convert an effective interest rate to a nominal interest rate
34
+ # @return [Flt::DecNum] the nominal interest rate
35
+ # @param [Numeric] rate the effective interest rate
36
+ # @param [Numeric] periods the number of compounding periods per year
37
+ # @example
38
+ # Rate.to_nominal(0.06, 365) #=> Flt::DecNum('0.05827')
39
+ # @see https://www.miniwebtool.com/nominal-interest-rate-calculator/
40
+ # @api public
41
+ def self.to_nominal(rate, periods)
42
+ rate = Flt::DecNum.new(rate.to_s)
43
+ periods = Flt::DecNum.new(periods.to_s)
44
+
45
+ if periods.infinite?
46
+ (rate + 1).log
47
+ else
48
+ periods * (((rate + 1)**(1.to_f / periods)) - 1)
49
+ end
50
+ end
51
+
11
52
  # create a new Rate instance
12
53
  # @return [Rate]
13
54
  # @param [Numeric] rate the decimal value of the interest rate
@@ -26,33 +67,30 @@ module Finrb
26
67
 
27
68
  # Set optional attributes..
28
69
  opts.each do |key, value|
29
- send("#{key}=", value)
70
+ __send__("#{key}=", value)
30
71
  end
31
72
 
32
73
  # Set the rate in the proper way, based on the value of type.
33
74
  begin
34
- send("#{TYPES.fetch(type)}=", Flt::DecNum.new(rate.to_s))
75
+ __send__("#{TYPES.fetch(type)}=", Flt::DecNum.new(rate.to_s))
35
76
  rescue KeyError
36
77
  raise(ArgumentError, "type must be one of #{TYPES.keys.join(', ')}", caller)
37
78
  end
38
79
  end
39
80
 
40
- # Accepted rate types
41
- TYPES = { apr: "effective", apy: "effective", effective: "effective", nominal: "nominal" }.freeze
42
-
43
81
  # @return [Integer] the duration for which the rate is valid, in months
44
82
  # @api public
45
83
  attr_accessor :duration
46
- # @return [DecNum] the effective interest rate
84
+ # @return [Flt::DecNum] the effective interest rate
47
85
  # @api public
48
86
  attr_reader :effective
49
- # @return [DecNum] the nominal interest rate
87
+ # @return [Flt::DecNum] the nominal interest rate
50
88
  # @api public
51
89
  attr_reader :nominal
52
90
 
53
91
  # compare two Rates, using the effective rate
54
92
  # @return [Numeric] one of -1, 0, +1
55
- # @param [Rate] rate the comparison Rate
93
+ # @param [Rate] other the comparison Rate
56
94
  # @example Which is better, a nominal rate of 15% compounded monthly, or 15.5% compounded semiannually?
57
95
  # r1 = Rate.new(0.15, :nominal) #=> Rate.new(0.160755, :apr)
58
96
  # r2 = Rate.new(0.155, :nominal, :compounds => :semiannually) #=> Rate.new(0.161006, :apr)
@@ -95,7 +133,7 @@ module Finrb
95
133
 
96
134
  # set the effective interest rate
97
135
  # @return none
98
- # @param [DecNum] rate the effective interest rate
136
+ # @param [Flt::DecNum] rate the effective interest rate
99
137
  # @api private
100
138
  def effective=(rate)
101
139
  @effective = rate
@@ -106,11 +144,11 @@ module Finrb
106
144
  "Rate.new(#{apr.round(6)}, :apr)"
107
145
  end
108
146
 
109
- # @return [DecNum] the monthly effective interest rate
147
+ # @return [Flt::DecNum] the monthly effective interest rate
110
148
  # @example
111
149
  # rate = Rate.new(0.15, :nominal)
112
- # rate.apr.round(6) #=> DecNum('0.160755')
113
- # rate.monthly.round(6) #=> DecNum('0.013396')
150
+ # rate.apr.round(6) #=> Flt::DecNum('0.160755')
151
+ # rate.monthly.round(6) #=> Flt::DecNum('0.013396')
114
152
  # @api public
115
153
  def monthly
116
154
  (effective / 12).round(15)
@@ -118,50 +156,13 @@ module Finrb
118
156
 
119
157
  # set the nominal interest rate
120
158
  # @return none
121
- # @param [DecNum] rate the nominal interest rate
159
+ # @param [Flt::DecNum] rate the nominal interest rate
122
160
  # @api private
123
161
  def nominal=(rate)
124
162
  @nominal = rate
125
163
  @effective = Rate.to_effective(rate, @periods)
126
164
  end
127
165
 
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 https://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
166
  private :compounds=, :effective=, :nominal=
166
167
  end
167
168
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "decimal"
3
+ require_relative 'decimal'
4
4
 
5
5
  module Finrb
6
6
  # the Transaction class provides a general interface for working with individual cash flows.
7
7
  # @api public
8
8
  class Transaction
9
- # @return [DecNum] the cash value of the transaction
9
+ # @return [Flt::DecNum] the cash value of the transaction
10
10
  # @api public
11
11
  attr_reader :amount
12
12
  # @return [Integer] the period number of the transaction
@@ -33,7 +33,7 @@ module Finrb
33
33
 
34
34
  # Set optional attributes..
35
35
  opts.each do |key, value|
36
- send("#{key}=", value)
36
+ __send__("#{key}=", value)
37
37
  end
38
38
  end
39
39
 
@@ -49,12 +49,12 @@ module Finrb
49
49
  @amount = Flt::DecNum.new(value.to_s) || 0
50
50
  end
51
51
 
52
- # @return [DecNum] the difference between the original transaction
52
+ # @return [Flt::DecNum] the difference between the original transaction
53
53
  # amount and the current amount
54
54
  # @example
55
55
  # t = Transaction.new(500)
56
56
  # t.amount = 750
57
- # t.difference #=> DecNum('250')
57
+ # t.difference #=> Flt::DecNum('250')
58
58
  # @api public
59
59
  def difference
60
60
  @amount - @original