1
$\begingroup$

I am trying to match the accrued interest, clean price, dirty price, and duration from the iBoxx underlying data. I've come close to perfectly matching their measurements but have run into an edge case where I'm not sure how best to approach it.

I have a bond issued on 2017-11-09 with an interest accrual start date on 2017-11-14 and maturity date of 2024-11-15. When I create the Schedule object as below:

# Create schedule
    Schedule = ql.Schedule(StartDate, 
                            MaturityDate,
                            ql.Period(CouponFrequency),
                            Calendar,
                            ql.Unadjusted, 
                            ql.ModifiedFollowing,
                            ql.DateGeneration.Backward, 
                            False)

I get the following output when I call

list(Schedule)

I get

[Date(14,11,2017), Date(15,11,2017), Date(15,5,2018), Date(15,11,2018), Date(15,5,2019), Date(15,11,2019), Date(15,5,2020), Date(15,11,2020), Date(15,5,2021), Date(15,11,2021), Date(15,5,2022), Date(15,11,2022), Date(15,5,2023), Date(15,11,2023), Date(15,5,2024), Date(15,11,2024)]

As you can see from the first two entries, we have the start date of interest accrual and then a coupon date the day after (on the semi-annual date associated with the maturity date).

My question is: should the interest accrual reset on 2017-11-15? For reference the cusip is 911312BL9. I found the following information through FactSet that the initial coupon date is in fact 2018-05-15. Therefore, it seems like the way I've constructed my Schedule is incorrect. However, I'm not sure how to adjust my Python code. The difference between my output and iBoxx disappears after 2018-05-15 indicating that they are properly accounting for the fact that interest accrual does not reset on 2017-11-15.

$\endgroup$

1 Answer 1

2
$\begingroup$

Sometimes an odd coupon period is long and sometimes it is short. In your example, it's possible, but unlikely, that the first coupon period is only 5 days long. It's more likely, but not certain, that the first coupon period is 5 days longer than a regular period. It is an extremely bad and dangerous practice to try to guess programmatically which one it is, because sometimes your guess will be wrong. Instead you should obtain the first coupon date as part of your instrument's indicative data and pass it to the scheduler constructor. In Python Quantlib, the first coupon date is the next positional argument to ql.Schedule after EndOfMonth=False

The dates should be in the bond's prospectus. If you get the bond indicative data from a data vendor like Bloomberg, there should be a field for it, but you should check - data vendors sometimes drop the ball.

Your comment mentions Mergent Fixed Income Securities Database (FISD) from FTSE Russel Mergent https://www.mergentonline.com/ . I've never used it myself. The database description reads:

The database, designed for academia, contains issue details on over 140,000 corporate, corporate MTN (medium-term note), supranational, U.S. Agency, and U.S. Treasury debt securities and includes more than 550 data items. Mergent FISD provides details on debt issues and the issuers, as well as transactions by insurance companies.

Sometimes the entire schedule is so bespoke that it cannot be recreated using a programmatic scheduler, and then you have to pass the entire list of dates as a custom schedule. This example doesn't sound so bad as to need that. US911312BL96 looks like a pretty vanilla corporate bond from United Parcel Service.

My typical experience with more exotic and emerging markets bonds and Bloomberg indicative data has been:

  • a bond gets issued

  • Bloomberg's analysts in a low-cost location extract the indicative data and retype into their databases, often with mistakes on the first try

  • lots of Bloomberg customers look at the indicative data on Bloomberg, find errors, and usually tell Bloomberg support (F1 F1) when they do

  • Bloomberg eventually corrects their indicative data

As the result, Bloomberg is effectively crowdsourced, and therefore usually correct, although for recently issues bonds you should watch out for data errors.

$\endgroup$
3
  • $\begingroup$ Thank you for the very quick response. I'm a novice at QuantLib and trying to make sure I learn best practices by replicating a trusted data source. I'll track down the full coupon schedule to make sure the constructor has full information $\endgroup$
    – Nick von T
    Commented Aug 9 at 13:27
  • $\begingroup$ May I ask a follow up question? I'm sourcing coupon info from FISD and have found the first coupon date. Is it typical for the full set of coupon dates to be enumerated or is it safe to take first, last, and frequency and construct the set of dates $\endgroup$
    – Nick von T
    Commented Aug 9 at 13:45
  • 1
    $\begingroup$ A generalised bond or swap schedule may have front and/or back stubs which also have to be specified or implied. Here is a little more detailed info... rateslib.readthedocs.io/en/stable/u_scheduling.html $\endgroup$
    – Attack68
    Commented Aug 9 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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