Skip to content
All library documents

Model Ex-Coupon Periods to Price UK Gilt Accrued Interest

Article Quant Q&A · Author: thoughtnewbie

Summary

This example shows how to obtain correct accrued interest for a fixed-rate UK gilt in QuantLib when the settlement date falls within the ex-coupon period. The bond schedule, coupon, and day-count convention already produce the expected accrued interest on an ordinary date, but the library returns a positive amount where the market quote is negative during the ex-coupon window.

The resolution is to provide the bond constructor with the ex-coupon period and its calendar, as well as the payment calendar. With this information, the same accrued-interest calculation returns a negative amount during the specified window while preserving the ordinary-date result. The example illustrates that ex-coupon treatment must be part of the bond definition for the library to apply it. It gives one bond and one short ex-coupon period as an implementation example, rather than discussing alternative conventions or broader bond-pricing validation.

Key ideas

  • A bond model must include ex-coupon settings to account for negative accrued interest during that period.
  • QuantLib's bond constructor accepts the ex-coupon period and its calendar.
  • The example preserves the ordinary accrued-interest result and adjusts the result during the ex-coupon window.
  • The payment calendar is also supplied when constructing the bond.

Tags

Full text
# Pricing a fixed rate bond with ex-dividend date in QuantLib Python


# Pricing a fixed rate bond with ex-dividend date in QuantLib Python












I'm trying to price a fixed rate bond with ex-dividend date using Python QuantLib. This is a feature of UK Gilts.

On regular days, I'm able to get the correct accrued interest, but on days in the ex-dividend period, I'm unable to determine the correct accrued interest. Any help is appreciated.

Below is my code

```
import QuantLib as ql
import datetime as dt
import numpy as np
import pandas as pd

#ISIN: GB00B54QLM75
issue_date=ql.Date(22, 10, 2009)
maturity_date=ql.Date(22, 1, 2060)
first_cpn_date=ql.Date(22, 1, 2010)
last_cpn_date=ql.Date(22, 7, 2059)
tenor=ql.Period(ql.Semiannual)
calendar=ql.UnitedKingdom()
business_convention=ql.Unadjusted
termination_business_convention=ql.Unadjusted
date_generation=ql.DateGeneration.Forward
end_of_month=False
coupon = .04

fbSchedule=ql.Schedule(issue_date, 
                    maturity_date,
                    tenor,
                    calendar,
                    business_convention,
                    termination_business_convention,
                    date_generation,
                    end_of_month,
                    first_cpn_date,
                    last_cpn_date)
sch = [x for x in fbSchedule]
fbSchedule = ql.Schedule(
    sch,
    calendar,
    business_convention,
    termination_business_convention,
    tenor,
    date_generation,
    end_of_month,
    [True] * (len(sch)-1)
)
cpns = [coupon]

settle_days=1
face_amt = 100.
rdm_amt = 100.
fixedRateBond = ql.FixedRateBond(
    settle_days, 
    face_amt,
    fbSchedule,
    cpns,
    ql.ActualActual(ql.ActualActual.ISMA),
    business_convention,
    rdm_amt,
    issue_date
    )

print(fixedRateBond.accruedAmount(ql.Date(24, 3, 2023)))
#QL: 0.6740331491712714, Blbg: 0.67403
print(fixedRateBond.accruedAmount(ql.Date(14, 7, 2023)))
#QL: 1.9116022099447516, Blbg: -0.08840
```

Edit: I don't think this is a duplicate of Negative Accrued for treasury bonds? as a method to determine negative AI is not described

## Answer by Luigi Ballabio (score 4)

https://quant.stackexchange.com/a/75007

Pass the ex-coupon information to the bond constructor. The library has no way to know otherwise.

```
payment_calendar = ql.UnitedKingdom()
ex_coupon_period = ql.Period(7, ql.Days)
ex_coupon_calendar = ql.UnitedKingdom()

fixedRateBond = ql.FixedRateBond(
    settle_days,
    face_amt,
    fbSchedule,
    cpns,
    ql.ActualActual(ql.ActualActual.ISMA),
    business_convention,
    rdm_amt,
    issue_date,
    payment_calendar,
    ex_coupon_period,
    ex_coupon_calendar,
)

print(fixedRateBond.accruedAmount(ql.Date(24, 3, 2023)))
# 0.6740331491712714
print(fixedRateBond.accruedAmount(ql.Date(14, 7, 2023)))
# -0.08839779005525017
```

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.