Class: Finance::Rate

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/finance/rates.rb

Overview

the Rate class provides an interface for working with interest rates.

Constant Summary

TYPES =

Accepted rate types

{ :apr       => "effective",
  :apy       => "effective",
  :effective => "effective",
  :nominal   => "nominal"
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rate, type, opts = {}) ⇒ Rate

create a new Rate instance

Examples:

create a 3.5% APR rate

Rate.new(0.035, :apr) #=> Rate(0.035, :apr)

Parameters:

  • rate (Numeric)

    the decimal value of the interest rate

  • type (Symbol)

    a valid rate type

  • opts (optional, Hash) (defaults to: {})

    set optional attributes

Options Hash (opts):

  • :duration (String)

    a time interval for which the rate is valid

  • :compounds (String) — default: :monthly

    the number of compounding periods per year

See Also:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/finance/rates.rb', line 90

def initialize(rate, type, opts={})
  # Default monthly compounding.
  opts = { :compounds => :monthly }.merge opts

  # Set optional attributes..
  opts.each do |key, value|
    send("#{key}=", value)
  end

  # Set the rate in the proper way, based on the value of type.
  begin
    send("#{TYPES.fetch(type)}=", Flt::DecNum.new(rate.to_s))
  rescue KeyError
    raise ArgumentError, "type must be one of #{TYPES.keys.join(', ')}", caller
  end
end

Instance Attribute Details

#durationInteger

Returns the duration for which the rate is valid, in months

Returns:

  • (Integer)

    the duration for which the rate is valid, in months



19
20
21
# File 'lib/finance/rates.rb', line 19

def duration
  @duration
end

#effectiveDecNum

Returns the effective interest rate

Returns:

  • (DecNum)

    the effective interest rate



22
23
24
# File 'lib/finance/rates.rb', line 22

def effective
  @effective
end

#nominalDecNum

Returns the nominal interest rate

Returns:

  • (DecNum)

    the nominal interest rate



25
26
27
# File 'lib/finance/rates.rb', line 25

def nominal
  @nominal
end

Class Method Details

.to_effective(rate, periods) ⇒ DecNum

convert a nominal interest rate to an effective interest rate

Examples:

Rate.to_effective(0.05, 4) #=> DecNum('0.05095')

Parameters:

  • rate (Numeric)

    the nominal interest rate

  • periods (Numeric)

    the number of compounding periods per year

Returns:

  • (DecNum)

    the effective interest rate



137
138
139
140
141
142
143
144
145
# File 'lib/finance/rates.rb', line 137

def Rate.to_effective(rate, periods)
  rate, periods = Flt::DecNum.new(rate.to_s), Flt::DecNum.new(periods.to_s)

  if periods.infinite?
    rate.exp - 1
  else
    (1 + rate / periods) ** periods - 1
  end
end

.to_nominal(rate, periods) ⇒ DecNum

convert an effective interest rate to a nominal interest rate

Examples:

Rate.to_nominal(0.06, 365) #=> DecNum('0.05827')

Parameters:

  • rate (Numeric)

    the effective interest rate

  • periods (Numeric)

    the number of compounding periods per year

Returns:

  • (DecNum)

    the nominal interest rate

See Also:



155
156
157
158
159
160
161
162
163
# File 'lib/finance/rates.rb', line 155

def Rate.to_nominal(rate, periods)
  rate, periods = Flt::DecNum.new(rate.to_s), Flt::DecNum.new(periods.to_s)

  if periods.infinite?
    (rate + 1).log
  else
    periods * ((1 + rate) ** (1 / periods) - 1)
  end
end

Instance Method Details

#<=>(rate) ⇒ Numeric

compare two Rates, using the effective rate

Examples:

Which is better, a nominal rate of 15% compounded monthly, or 15.5% compounded semiannually?

r1 = Rate.new(0.15, :nominal) #=> Rate.new(0.160755, :apr)
r2 = Rate.new(0.155, :nominal, :compounds => :semiannually) #=> Rate.new(0.161006, :apr)
r1 <=> r2 #=> -1

Parameters:

  • rate (Rate)

    the comparison Rate

Returns:



35
36
37
# File 'lib/finance/rates.rb', line 35

def <=>(rate)
  @effective <=> rate.effective
end

#aprDecNum

Returns the effective interest rate

Returns:

  • (DecNum)

    the effective interest rate



41
42
43
# File 'lib/finance/rates.rb', line 41

def apr
  self.effective
end

#apyDecNum

Returns the effective interest rate

Returns:

  • (DecNum)

    the effective interest rate



47
48
49
# File 'lib/finance/rates.rb', line 47

def apy
  self.effective
end

#inspectObject



107
108
109
# File 'lib/finance/rates.rb', line 107

def inspect
  "Rate.new(#{self.apr.round(6)}, :apr)"
end

#monthlyDecNum

Returns the monthly effective interest rate

Examples:

rate = Rate.new(0.15, :nominal)
rate.apr.round(6) #=> DecNum('0.160755')
rate.monthly.round(6) #=> DecNum('0.013396')

Returns:

  • (DecNum)

    the monthly effective interest rate



117
118
119
# File 'lib/finance/rates.rb', line 117

def monthly
  (self.effective / 12).round(15)
end