Constructing a Bond Discount Curve with Rateslib’s Global Solver
Summary
The document explains how to infer a discount curve from fixed-rate bond prices using Rateslib. It contrasts sequential bootstrapping, which solves curve values in maturity order and relies on suitable instrument and curve conditions, with Rateslib’s global optimization approach. The latter fits a chosen curve structure to instrument prices and can handle structures that do not meet bootstrap requirements.
For a basic bond curve, the example places curve nodes at bond maturities and uses log-linear interpolation, then supplies the bonds and their clean market prices to a solver. The resulting curve holds discount factors, which can be queried for dates or used to derive overnight forward rates. Zero rates are not returned directly in the described workflow; they must be calculated from discount factors for selected dates. The method’s output depends on the specified instruments, curve nodes, interpolation, and pricing inputs.
Key ideas
- Rateslib fits curves with a global solver rather than sequentially bootstrapping them.
- The solver uses instrument prices together with a specified curve structure.
- A basic bond curve can place nodes at bond maturities and use log-linear interpolation.
- The solved curve contains discount factors that can be queried by date.
- Zero rates must be calculated from the curve’s discount factors for the desired dates.
Tags
Full text
# Bootstrap a Bond Curve in Rateslib
# Bootstrap a Bond Curve in Rateslib
Is it possible to get a Zero coupon curve from a set of FixedRateBond in rateslib?
I tried looking in the documentation but didn't find a way of doing it.
There's something called CurveSolver but it seems like you need to supply a Curve to it.
From a set of FixedRateBond and their prices or YTM observed in the market I would like to derive a zero coupon curve.
## Answer by Attack68 (score 1, accepted)
https://quant.stackexchange.com/a/80656
"Bootstrapping" is a name of one specific method to construct a curve from a given set of instruments. Bootstrapping works by sequentially solving values on the curve usually in ascending order of maturity of the instruments. To bootstrap a curve a few conditions must be met, which is usually why some software allow a curve to be created directly from bond instruments, becuase that software automatically creates an inflexible but suitable curve from the maturity of the instruments and then sequentially computes the necessary discount factors.
Rateslib does not bootstrap. It uses an alternate method to construct curves which is much more flexible. That being a "global optimiser".
Any curve that can be bootstrapped can be solved by a global optimiser, but it is not true that any curve solved by a global optimiser can be bootstrapped becuase bootstrapped curves require those aformentioned conditions. Thus, rateslib can indirectly bootstrap your curve, by solving it globally.
In order to solve curves in rateslib you need to do 2 things:
- Define the Instruments whose prices will instruct the Curve.
- Define the structure of the Curve which will be solved to suit those Instrument prices.
Since you just want a basic 'bootstrap' curve, the default structure you are looking for is to put nodes at the maturity of each bond, and use log linear interpolation.
```
from rateslib import * # Python 3.12, Rateslib 1.4.0
bonds = [
FixedRateBond(dt(1999, 9, 26), "3y", spec="us_gb", curves="bond", fixed_rate=2.5),
FixedRateBond(dt(1998, 3, 15), "7y", spec="us_gb", curves="bond", fixed_rate=2.75),
FixedRateBond(dt(1999, 5, 22), "10y", spec="us_gb", curves="bond", fixed_rate=3.0),
]
curve = Curve(
nodes={
dt(2000, 1, 1): 1.0, # <-- TODAY
dt(2002, 9, 26): 1.0, # <-- Bond Maturity
dt(2005, 3, 15): 1.0, # <-- Bond Maturity
dt(2009, 5, 22): 1.0, # <-- Bond Maturity
},
interpolation="log_linear",
id="bond"
)
solver = Solver(
curves=[curve],
instruments=bonds,
s=[100, 100, 100], # <-- Clean price of each bond
)
```
The `Curve` constructed contains discount factors. You can extract a discount factor for any date using Pythons `__getitem__`, i.e.
```
curve[dt(2003, 4, 5)]
# 0.919685
```
Or you can plot overnight forward rates from the curve:
```
curve.plot("1b")
```
To calculate zero rates and plot them, you have to loop through all the dates you want and perform the calculation for a zero rate from a discount factor manually.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.