Class: Istox::Quant::Bond

Inherits:
Object
  • Object
show all
Defined in:
lib/istox/quant/bond.rb

Constant Summary collapse

DEFAULT_APPROXIMATION_ERROR =
0.00001

Instance Method Summary collapse

Constructor Details

#initialize(coupon: nil, maturity_date: nil, years: nil, coupon_frequency: nil, coupon_payment_dates: nil, face_value: 100, days_of_year: 365) ⇒ Bond

Returns a new instance of Bond.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/istox/quant/bond.rb', line 16

def initialize(coupon: nil, maturity_date: nil, years: nil, coupon_frequency: nil, coupon_payment_dates: nil, face_value: 100, days_of_year: 365)
  raise "Invalid coupon #{coupon}" if (coupon.nil? || !is_number?(coupon))
  raise "Invalid maturity_date #{maturity_date}" if (maturity_date.nil? || maturity_date.methods.include?("strftime"))
  raise "Invalid years #{years}" if (years.nil? || !is_number?(years))
  raise "Invalid coupon_frequency #{days_of_year}" if (coupon_frequency.nil? || !is_number?(coupon))
  raise "Invalid coupon_payment_dates #{coupon_payment_dates}" if (coupon_payment_dates.nil? || coupon_payment_dates.count == 0 || coupon_payment_dates.any? { |date| date > maturity_date.to_date })
  raise "Invalid days_of_year #{days_of_year}" if (days_of_year != 365 && days_of_year != 360)

  @coupon               = coupon.to_d
  @maturity_date        = maturity_date.to_date
  @years                = years
  @coupon_frequency     = coupon_frequency.to_d
  @days_of_year         = days_of_year.to_d
  @face_value           = face_value
  @coupon_payment_dates = coupon_payment_dates.map(&:to_date).sort
  @start_date           = (@maturity_date-(years*12).to_i.months)
end

Instance Method Details

#coupon_payments(from_date) ⇒ Object

def interest_payments(from_date)

payments = []
date = @maturity_date
while date >= from_date
  payments << date
  date = date.prev_month(12/@coupon_frequency)
end
payments.sort

end



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/istox/quant/bond.rb', line 50

def coupon_payments(from_date)
  payments = []

  @coupon_payment_dates.each do |payment_date|
    if payment_date > from_date
      payments << payment_date
    end
  end

  payments.sort
end

#price(ytm, date, ex_coupon_date: nil, fees: 0) ⇒ Object



34
35
36
37
38
# File 'lib/istox/quant/bond.rb', line 34

def price(ytm, date, ex_coupon_date: nil, fees: 0)
  # price_for_irr(irr_from_ytm(ytm), date, fees: fees)
  price = price_for_irr(ytm/@coupon_frequency, date, ex_coupon_date: ex_coupon_date, fees: fees)
  price
end

#ytm(date, ex_coupon_date: nil, price: 100, fees: 0, approximation_error: DEFAULT_APPROXIMATION_ERROR) ⇒ Object



62
63
64
65
# File 'lib/istox/quant/bond.rb', line 62

def ytm(date, ex_coupon_date: nil, price: 100, fees: 0, approximation_error: DEFAULT_APPROXIMATION_ERROR)
  ytm_down, ytm_up = ytm_limits(price, date, ex_coupon_date: ex_coupon_date, fees: fees)
  approximate_ytm(ytm_down, ytm_up, price, date, ex_coupon_date: ex_coupon_date, fees: fees, approximation_error: approximation_error)
end