債券

Quantlib:建立期限結構後如何為債券定價

  • July 30, 2020

下面是我使用 QuantLib 建構期限結構的程式碼 我想做的是用它來為任何假設的債券定價讓我們說

開始日期:2016 年 2 月 8 日結束日期:2021 年 2 月 8 日優惠券:10% 半

我怎麼做?

import matplotlib
matplotlib.use('macosx')
import matplotlib.pyplot as plt
import QuantLib as ql
import pandas as pd


# Deposit rates
depo_maturities = [ql.Period(1,ql.Months),ql.Period(3,ql.Months),ql.Period(6,ql.Months)]
depo_cpn = [.149,.165,.155] #yields they are trading at


maturity_days = [299,845,1210,1485,1895,2306,2671,3128,3494,3904,4453,5275,7101,8699,10526,13629,18834]


# Coupon Bonds
bond_maturities = [ql.Period(i, ql.Days) for i in maturity_days]
bond_cpn = [1.5,.5,.75,1,.625,1.5,1.25,1.625,.875,4.75]
bond_rates = [.106,.114,.151,.187,.252,.214,.272,.311,.4089,.474]
bond_quotes = [101.161,100.896,101.987,103.301,101.926,108.078,107.088,111.111,104.374,144.568]


bond_long_cpn = [4.25, 4.5, 4.25, 3.25, 1.75, 1.75, 1.625]  # coupons
bond_long_rates = [.593, .667, .767, .858, .848, .669, .543]  # yields
bond_long_quotes = [142.974, 152.719, 162.806, 151.432, 123.016, 135.634, 148.58]

'''####### Depo Helpers #########'''

calc_date = ql.Date(24, 3, 2020)
ql.Settings.instance().evaluationDate = calc_date

calendar = ql.UnitedKingdom()
business_convention = ql.Unadjusted
day_count = ql.Thirty360()
end_of_month = True
settlement_days = 0
face_amount = 100
coupon_frequency = ql.Period(ql.Annual)

# Create depo helpers
depo_helpers = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(r / 100.0)),
                                    m,
                                    settlement_days,
                                    calendar,
                                    business_convention,
                                    end_of_month,
                                    day_count)
               for r, m in zip(depo_cpn, depo_maturities)]

'''####### Bonds Helpers #########'''

# day_count = ql.Thirty360()
day_count = ql.Actual365Fixed()
end_of_month = True
settlement_days = 2

# create fixed rate bond helpers from fixed rate bonds
bond_cpn += bond_long_cpn
# bond_maturities += bond_long_maturities
bond_quotes += bond_long_quotes
bond_rates += bond_long_rates

bond_helpers = []
for r, m, q in zip(bond_cpn, bond_maturities, bond_quotes):
   termination_date = calc_date + m
   quote = ql.QuoteHandle(ql.SimpleQuote(q))
   schedule = ql.MakeSchedule(calc_date, termination_date, frequency=ql.Annual)
   helper = ql.FixedRateBondHelper(quote, settlement_days, face_amount, schedule, [r / 100.0], day_count,
                                   business_convention)
   bond_helpers.append(helper)

# The yield curve is constructed by putting the two helpers together.
rate_helpers = depo_helpers + bond_helpers
yieldcurve = ql.PiecewiseLogCubicDiscount(calc_date, rate_helpers, day_count)

# The spot cpn is obtined from yieldcurve object using the zeroRate method.
spots = []
tenors = []
for d in yieldcurve.dates():
   yrs = day_count.yearFraction(calc_date, d)
   compounding = ql.Compounded
   freq = ql.Annual
   zero_rate = yieldcurve.zeroRate(yrs, compounding, freq)
   tenors.append(yrs)
   eq_rate = zero_rate.equivalentRate(day_count, compounding, freq, calc_date, d).rate()
   spots.append(100 * eq_rate)

你已經完成了 90% 的路。從這裡,您只需設置一個債券產品,將您的收益率曲線傳遞給定價引擎,然後您就可以使用該引擎為債券定價

# Create a bond instrument
start_date, end_date = ql.Date(8, 2, 2020), ql.Date(8, 2, 2021)
coupons = [0.10]
coupon_freq = ql.Period(ql.Semiannual)

semiannual_bond = ql.FixedRateBond(settlement_days, calendar, 100, start_date, end_date, coupon_freq, coupons, day_count)

# Put the yield curve into a curve handler, pass to a bond pricing engine
rates_ts = ql.YieldTermStructureHandle(yieldcurve)
bond_engine = ql.DiscountingBondEngine(rates_ts)

# Pair the bond engine and the bond, and price!
semiannual_bond.setPricingEngine(bond_engine)

print(semiannual_bond.NPV())
print(semiannual_bond.cleanPrice())
print(semiannual_bond.accruedAmount())

print()
print("Cashflows remaining: ")
for c in semiannual_bond.cashflows():
   print('%20s %12f' % (c.date(), c.amount()))

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