1
$\begingroup$

I below are my codes using QuantLib to build a term structure What I would like to do is use that to price any hypothetical bond lets say

startdate : 8 Feb 2016 end date : 8 Feb 2021 coupons : 10% semi

How do I do that?

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)
$\endgroup$
0
$\begingroup$

You're 90% of the way there. From here, you just need to set up a bond product, pass your yield curve into a pricing engine, and then you can price the bond using the engine

# 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()))
$\endgroup$
3
  • $\begingroup$ perfect! thanks @StackG. That was most helpful. btw do you have any example for inflation bonds? i.e. building term structure and valuing linkers? $\endgroup$ – TRex Jul 30 '20 at 7:49
  • $\begingroup$ I don't know much about inflation-linked bonds myself, but this post on StackOverflow (no idea why it is there!) seems to have a working example: stackoverflow.com/questions/33865140/… $\endgroup$ – StackG Jul 30 '20 at 10:21
  • $\begingroup$ ok thanks mate, I couldn't find much material on QuantLib for inflation bonds $\endgroup$ – TRex Jul 31 '20 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.