Class: Finrb::Rate

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

Overview

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

Constant Summary collapse

TYPES =

Accepted rate types

{ apr: 'effective', apy: 'effective', effective: 'effective', nominal: 'nominal' }.freeze

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:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/finrb/rates.rb', line 64

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



83
84
85
# File 'lib/finrb/rates.rb', line 83

def duration
  @duration
end

#effectiveFlt::DecNum

Returns the effective interest rate.

Returns:

  • (Flt::DecNum)

    the effective interest rate



86
87
88
# File 'lib/finrb/rates.rb', line 86

def effective
  @effective
end

#nominalFlt::DecNum

Returns the nominal interest rate.

Returns:

  • (Flt::DecNum)

    the nominal interest rate



89
90
91
# File 'lib/finrb/rates.rb', line 89

def nominal
  @nominal
end

Class Method Details

.to_effective(rate, periods) ⇒ Flt::DecNum

convert a nominal interest rate to an effective interest rate

Examples:

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

Parameters:

  • rate (Numeric)

    the nominal interest rate

  • periods (Numeric)

    the number of compounding periods per year

Returns:

  • (Flt::DecNum)

    the effective interest rate



22
23
24
25
26
27
28
29
30
31
# File 'lib/finrb/rates.rb', line 22

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

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

.to_nominal(rate, periods) ⇒ Flt::DecNum

convert an effective interest rate to a nominal interest rate

Examples:

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

Parameters:

  • rate (Numeric)

    the effective interest rate

  • periods (Numeric)

    the number of compounding periods per year

Returns:

  • (Flt::DecNum)

    the nominal interest rate

See Also:



41
42
43
44
45
46
47
48
49
50
# File 'lib/finrb/rates.rb', line 41

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

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

Instance Method Details

#<=>(other) ⇒ 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:

  • other (Rate)

    the comparison Rate

Returns:



99
100
101
# File 'lib/finrb/rates.rb', line 99

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

#aprFlt::DecNum

Returns the effective interest rate.

Returns:

  • (Flt::DecNum)

    the effective interest rate



105
106
107
# File 'lib/finrb/rates.rb', line 105

def apr
  effective
end

#apyFlt::DecNum

Returns the effective interest rate.

Returns:

  • (Flt::DecNum)

    the effective interest rate



111
112
113
# File 'lib/finrb/rates.rb', line 111

def apy
  effective
end

#inspectObject



143
144
145
# File 'lib/finrb/rates.rb', line 143

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

#monthlyFlt::DecNum

Returns the monthly effective interest rate.

Examples:

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

Returns:

  • (Flt::DecNum)

    the monthly effective interest rate



153
154
155
# File 'lib/finrb/rates.rb', line 153

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