Calculating a Bond Z-Spread with QuantLib and a Zero Curve
Summary
This document addresses a Python interface issue encountered when calculating the z-spread of a fixed-rate corporate bond against a zero curve built from swap rates. The supplied example constructs a curve, bond schedule, and bond, then passes them to QuantLib’s bond z-spread function; the call fails with an overload type error.
The accepted explanation identifies the relevant argument mismatch: the function expects a term structure, while the example wraps the curve in a yield-term-structure handle. Passing the underlying curve directly is suggested as the fix. This is a narrow implementation note based on the cited QuantLib interface and version context; it does not explain z-spread theory, validate the input curve construction, or discuss bond pricing conventions beyond the example.
Key ideas
- QuantLib’s bond z-spread function expects a term structure argument in the shown interface.
- Wrapping the zero curve in a yield-term-structure handle can cause the overload type error described.
- The suggested resolution is to pass the curve itself to the function.
- The example concerns a fixed-rate corporate bond valued against a zero curve derived from swap rates.
Tags
Full text
# QuantLib Python: Calculate ZSpread
# QuantLib Python: Calculate ZSpread
I am trying to use `quantlib-python` to calculate the z-spread of a fixed rate US corporate bond using a zero curve from swap rates provided.
Here is the provided curve with dates, zeroes and discount factors.
```
{'date': {0: Timestamp('2020-01-16 00:00:00'),
1: Timestamp('2020-01-23 00:00:00'),
2: Timestamp('2020-02-18 00:00:00'),
3: Timestamp('2020-03-16 00:00:00'),
4: Timestamp('2020-04-16 00:00:00'),
5: Timestamp('2020-06-17 00:00:00'),
6: Timestamp('2020-09-16 00:00:00'),
7: Timestamp('2020-12-16 00:00:00'),
8: Timestamp('2021-03-17 00:00:00'),
9: Timestamp('2021-06-16 00:00:00'),
10: Timestamp('2021-09-15 00:00:00'),
11: Timestamp('2021-12-15 00:00:00'),
12: Timestamp('2022-01-18 00:00:00'),
13: Timestamp('2022-07-18 00:00:00'),
14: Timestamp('2023-01-17 00:00:00'),
15: Timestamp('2023-07-17 00:00:00'),
16: Timestamp('2024-01-16 00:00:00'),
17: Timestamp('2024-07-16 00:00:00')},
'rate': {0: 1.5730452119529836,
1: 1.5730452119025795,
2: 1.7279111508652356,
3: 1.7913216016440803,
4: 1.8674426107576636,
5: 1.8294634933805565,
6: 1.7852819839324852,
7: 1.740006104698466,
8: 1.707636622424058,
9: 1.6797318490155533,
10: 1.6591129486236866,
11: 1.6405257638334003,
12: 1.6361045982494105,
13: 1.622831403886238,
14: 1.6095006947274282,
15: 1.6096802648009056,
16: 1.6098318250594712,
17: 1.6176504630707633},
'df': {0: 1.0,
1: 0.9996953731036011,
2: 0.9984718446661575,
3: 0.9970321675811668,
4: 0.9953638349734837,
5: 0.9923904015148071,
6: 0.988220850440741,
7: 0.9842443665336315,
8: 0.9803113137907096,
9: 0.9765817360374307,
10: 0.9728825409783471,
11: 0.9692140750801099,
12: 0.9678487049444453,
13: 0.9603121753425592,
14: 0.9530038843473384,
15: 0.9453899093059526,
16: 0.9378779089627198,
17: 0.930064389274982}}
```
Here is the code I have after I load the curve as `df`.
```
df.columns = ['date', 'rate', 'df']
day_count = ql.Thirty360(ql.Thirty360.USA)
dates = [ql.Date(d.day, d.month, d.year) for d in df['date']]
crv = ql.ZeroCurve(dates, df['rate'], day_count, ql.UnitedStates(ql.UnitedStates.GovernmentBond))
crv = ql.YieldTermStructureHandle(crv)
start = ql.Date(1,11,2013)
maturity = ql.Date(1,11,2023)
schedule = ql.MakeSchedule(start, maturity, ql.Period('6M'))
settlement_days = 2
interest = ql.FixedRateLeg(schedule, day_count, [100.], [0.0345])
bond = ql.Bond(settlement_days, ql.TARGET(), start, interest)
today = ql.Date(14, 1, 2020)
ql.Settings.instance().evaluationDate = today
ql.BondFunctions.zSpread(bond,86.22,crv,day_count,ql.Compounded,ql.Annual)
```
I am receiving the error `TypeError: Wrong number or type of arguments for overloaded function 'BondFunctions_zSpread` and am not sure which input is causing the error or how to resolve.
## Answer by Luigi Ballabio (score 3, accepted)
https://quant.stackexchange.com/a/79024
You can see the interface of `zSpread` declared at https://github.com/lballabio/QuantLib-SWIG/blob/v1.33/SWIG/bondfunctions.i#L146.
It takes a shared_ptr to term structure (which in Python means a term structure), not a handle. If you avoid the `crv = ql.YieldTermStructureHandle(crv)`, it should work.
## Answer by Sane (score -1)
https://quant.stackexchange.com/a/79021
The error message suggests that there may be an issue with the number or type of arguments you are passing to the `BondFunctions.zSpread` function.
The `BondFunctions.zSpread` function typically takes the following arguments:
`Bond object` the bond for which you want to calculate the z-spread. `cleanPrice` the clean price of the bond. `curve` the yield term structure handle. `dayCount` the day count convention. `compounding` the compounding frequency. `frequency`: the coupon frequency.
Make sure that you are passing the correct arguments in the correct order.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.