1
$\begingroup$

I am using QuantLib to generate a US Treasury curve from 1y, 3y, 5y, and 10y yield quotes. However, after building the curve and running zeroRate on it, it returns a number that is about 0.012% different to the actual quote (1.972% vs 1.96% quote). What is the difference between these two numbers? Shouldn't they be almost identical?

Thanks in advance!

import QuantLib as ql

maturities = [ql.Period('1Y'), ql.Period('3Y'), ql.Period('5Y'), ql.Period('10Y')]
yields = [0.0191, 0.0171, 0.0174, 0.0196]


coupon_frequency = ql.UnitedStates.GovernmentBond
settlement_days = 0
face_amount = 100.0
day_count = ql.ActualActual(ql.ActualActual.Bond)
calendar = ql.UnitedStates()
convention = ql.Unadjusted
generation = ql.DateGeneration.Backward
end_of_month = False

calc_date = ql.Date(5,7,2019)
ql.Settings.instance().evaluationDate = calc_date

bond_helpers = []
for r, m in zip(yields, maturities):
    termination_date = calendar.advance(calc_date, m, convention)
    schedule = ql.Schedule(calc_date,
                           termination_date, 
                           ql.Period(coupon_frequency), 
                           calendar,
                           convention, 
                           convention, 
                           generation,
                           end_of_month,
                          )

    bond_helper = ql.FixedRateBondHelper(ql.QuoteHandle(ql.SimpleQuote(face_amount)),
                                         settlement_days,
                                         face_amount,
                                         schedule,
                                         [r],
                                         day_count,
                                         convention,
                                        )
    bond_helpers.append(bond_helper)

curve = ql.PiecewiseLogCubicDiscount(calc_date, bond_helpers, day_count)

test_maturity = calendar.advance(calc_date, ql.Period('10Y'), convention)

test_maturity, 0.0196, curve.zeroRate(test_maturity, day_count, ql.Compounded, coupon_frequency).rate()
(Date(5,7,2029), 0.0196, 0.019727996796473413)
$\endgroup$
  • $\begingroup$ Simply put, your inputs to the model are coupon bonds, but the outputs are zero coupon rates (i.e., coupon = 0). Given that the curve is upward sloping, it is expected that zero rates are higher than par coupon rates. I recommend going through some of the questions regarding par rates, zero rates, and forward rates in this SE. $\endgroup$ – Helin Jul 5 at 21:06

Your Answer

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

Browse other questions tagged or ask your own question.