Bond

簡單的 QuantLib 債券數學

  • November 20, 2019

我是 QuantLib 的新手,正試圖讓它複製一些簡單的債券數學。

假設我們有一張 5 年期債券,年票面金額為 5美元,面值為 100美元,利率為 4%。經典計算得出債券的現值為104.45美元。當我嘗試在 QuantLib-Python 中執行這個簡單的範例時,我得到了 104.70 美元——儘管我嘗試去除日曆約定。

我如何使用 QuantLib 來匹配這個簡單的債券數學?

from QuantLib import *

# Construct yield curve
calc_date = Date(1, 1, 2017)
Settings.instance().evaluationDate = calc_date

spot_dates = [Date(1,1,2017), Date(1,1,2018), Date(1,1,2027)]
spot_rates = [0.0, 0.04, 0.04]

day_count = SimpleDayCounter()
calendar = NullCalendar()
interpolation = Linear()
compounding = Compounded
compounding_frequency = Annual
spot_curve = ZeroCurve(spot_dates, spot_rates, day_count, calendar, interpolation, compounding, compounding_frequency)

spot_curve_handle = YieldTermStructureHandle(spot_curve)

# Construct bond schedule
issue_date = Date(1, 1, 2017)
maturity_date = Date(1, 1, 2022)
tenor = Period(Semiannual)
calendar = NullCalendar()
business_convention = Unadjusted
date_generation = DateGeneration.Backward
month_end = False

schedule = Schedule(issue_date, maturity_date, tenor, calendar, business_convention, business_convention, date_generation, month_end)

# Create FixedRateBond Object

coupon_rate = 0.05
coupons = [coupon_rate]
settlement_days = 0
face_value = 100

fixed_rate_bond = FixedRateBond(settlement_days,
                               face_value,
                               schedule,
                               coupons,
                               day_count)

# Set Valuation engine
bond_engine = DiscountingBondEngine(spot_curve_handle)
fixed_rate_bond.setPricingEngine(bond_engine)

# Calculate present value
value = fixed_rate_bond.NPV()
print(value)

首先,正如學生 T 建議的那樣,您可以檢查現金流是否符合您的預期:

for c in fixed_rate_bond.cashflows():
   print '%20s %12f' % (c.date(), c.amount())

     July 1st, 2017     2.500000
  January 1st, 2018     2.500000
     July 1st, 2018     2.500000
  January 1st, 2019     2.500000
     July 1st, 2019     2.500000
  January 1st, 2020     2.500000
     July 1st, 2020     2.500000
  January 1st, 2021     2.500000
     July 1st, 2021     2.500000
  January 1st, 2022     2.500000
  January 1st, 2022   100.000000

他們看起來沒問題,所以問題一定出在貼現曲線上。一個問題是您將其實例化為:

spot_dates = [Date(1,1,2017), Date(1,1,2018), Date(1,1,2027)]
spot_rates = [0.0, 0.04, 0.04]
...

但這意味著第一年零利率將在 0.0 和 0.04 之間插值,當然這會給您錯誤的折扣因子;所以你應該使用

spot_dates = [Date(1,1,2017), Date(1,1,2018), Date(1,1,2027)]
spot_rates = [0.04, 0.04, 0.04]

反而。不過,這給出了104.67美元的價格,這仍然不是您想要的。下一個問題是您正在以 4% 的利率和年復利頻率初始化曲線;這給你的折扣係數等於 $ B(T) = 1/(1+R)^T $ ,您可以驗證:

for i, c in enumerate(fixed_rate_bond.cashflows()):
   T = day_count.yearFraction(calc_date, c.date())
   B = 1/math.pow(1.04, T)
   print '%20s %12f %12f %12f %12f' % (c.date(), c.amount(), T,
                                       B, spot_curve.discount(c.date()))

     July 1st, 2017     2.500000     0.500000     0.980581     0.980581
  January 1st, 2018     2.500000     1.000000     0.961538     0.961538
     July 1st, 2018     2.500000     1.500000     0.942866     0.942866
  January 1st, 2019     2.500000     2.000000     0.924556     0.924556
     July 1st, 2019     2.500000     2.500000     0.906602     0.906602
  January 1st, 2020     2.500000     3.000000     0.888996     0.888996
     July 1st, 2020     2.500000     3.500000     0.871733     0.871733
  January 1st, 2021     2.500000     4.000000     0.854804     0.854804
     July 1st, 2021     2.500000     4.500000     0.838204     0.838204
  January 1st, 2022     2.500000     5.000000     0.821927     0.821927
  January 1st, 2022   100.000000     5.000000     0.821927     0.821927

由於您有半年一次的優惠券,您可能也想使用半年一次的複利頻率。這給了你折扣因素 $ B(t) = 1/\left(1+\frac{R}{2}\right)^{2T} $ :

for i, c in enumerate(fixed_rate_bond.cashflows()):
   T = day_count.yearFraction(calc_date, c.date())
   B = 1/math.pow(1.02, 2*T)
   print '%20s %12f %12f %12f %12f' % (c.date(), c.amount(), T,
                                       B, spot_curve.discount(c.date()))

     July 1st, 2017     2.500000     0.500000     0.980392     0.980392
  January 1st, 2018     2.500000     1.000000     0.961169     0.961169
     July 1st, 2018     2.500000     1.500000     0.942322     0.942322
  January 1st, 2019     2.500000     2.000000     0.923845     0.923845
     July 1st, 2019     2.500000     2.500000     0.905731     0.905731
  January 1st, 2020     2.500000     3.000000     0.887971     0.887971
     July 1st, 2020     2.500000     3.500000     0.870560     0.870560
  January 1st, 2021     2.500000     4.000000     0.853490     0.853490
     July 1st, 2021     2.500000     4.500000     0.836755     0.836755
  January 1st, 2022     2.500000     5.000000     0.820348     0.820348
  January 1st, 2022   100.000000     5.000000     0.820348     0.820348

通過進一步修正,價格為104.49美元,仍比您預期的高 4 個基點。但此時,您可能還想檢查您的經典計算…

引用自:https://quant.stackexchange.com/questions/32539