BondFuture#

class rateslib.instruments.BondFuture(coupon, delivery, basket, nominal=NoInput.blank, contracts=NoInput.blank, calendar=NoInput.blank, currency=NoInput.blank, calc_mode=NoInput.blank)#

Bases: Sensitivities

Create a bond future derivative.

Parameters:
  • coupon (float) – The nominal coupon rate set on the contract specifications.

  • delivery (datetime or 2-tuple of datetimes) – The delivery window first and last delivery day, or a single delivery day.

  • basket (tuple of FixedRateBond) – The bonds that are available as deliverables.

  • nominal (float, optional) – The nominal amount of the contract.

  • contracts (int, optional) – The number of contracts owned or short.

  • calendar (str, optional) – The calendar to define delivery days within the delivery window.

  • currency (str, optional) – The currency (3-digit code) of the settlement contract.

  • calc_mode (str, optional) – The method to calculate conversion factors. See notes.

Notes

Conversion factors (CFs) calc_mode are:

  • “ytm” which calculates the CF as the clean price percent of par with the bond having a yield-to-maturity on the first delivery day in the delivery window.

  • “ust_short” which applies to CME 2y, 3y and 5y treasury futures. See CME Treasury Conversion Factors.

  • “ust_long” which applies to CME 10y and 30y treasury futures.

Examples

The dlv() method is a summary method which displays many attributes simultaneously in a DataFrame. This example replicates the Bloomberg screen print in the publication The Futures Bond Basis: Second Edition (p77) by Moorad Choudhry. To replicate that publication exactly no calendar has been provided. A more modern Bloomberg would probably consider the London business day calendar and this would affect the metrics of the third bond to a small degree (i.e. set calendar=”ldn”)

In [1]: kws = dict(
   ...:     frequency="S",
   ...:     ex_div=7,
   ...:     convention="ActActICMA",
   ...:     currency="gbp",
   ...:     settle=1,
   ...:     curves="gilt_curve"
   ...: )
   ...: 

In [2]: bonds = [
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2009, 12, 7), fixed_rate=5.75, **kws),
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2011, 7, 12), fixed_rate=9.00, **kws),
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2010, 11, 25), fixed_rate=6.25, **kws),
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2012, 8, 6), fixed_rate=9.00, **kws),
   ...: ]
   ...: 

In [3]: prices=[102.732, 131.461, 107.877, 134.455]

In [4]: ytms=[bond.ytm(price, dt(2000, 3, 16)) for bond, price in zip(bonds, prices)]

In [5]: future = BondFuture(
   ...:     delivery=(dt(2000, 6, 1), dt(2000, 6, 30)),
   ...:     coupon=7.0,
   ...:     basket=bonds,
   ...:     nominal=100000,
   ...:     contracts=10,
   ...:     currency="gbp",
   ...: )
   ...: 

In [6]: future.dlv(
   ...:     future_price=112.98,
   ...:     prices=[102.732, 131.461, 107.877, 134.455],
   ...:     repo_rate=6.24,
   ...:     settlement=dt(2000, 3, 16),
   ...:     convention="Act365f",
   ...: )
   ...: 
Out[6]: 
                Bond  Price  YTM  C.Factor  Gross Basis  Implied Repo  Actual Repo  Net Basis
0  5.750% 07-12-2009 102.73 5.38      0.91        -0.56          7.38         6.24      -0.34
1  9.000% 12-07-2011 131.46 5.27      1.15         1.24          3.56         6.24       1.03
2  6.250% 25-11-2010 107.88 5.28      0.94         1.12          2.20         6.24       1.28
3  9.000% 06-08-2012 134.46 5.19      1.16         3.18         -1.41         6.24       3.01

Various other metrics can be extracted in isolation including, notional, and conversion factors (cfs), gross_basis(), net_basis(), implied_repo(), ytm(), duration(), convexity(), ctd_index(),

In [7]: future.cfs
Out[7]: (0.9142254519590044, 1.152570524483184, 0.9449311626312817, 1.1619558330528528)

In [8]: future.notional
Out[8]: -1000000

In [9]: future.gross_basis(
   ...:     future_price=112.98,
   ...:     prices=prices,
   ...: )
   ...: 
Out[9]: 
(-0.5571915623283274,
 1.2435821438898813,
 1.1186772459177803,
 3.177229981688697)

In [10]: future.net_basis(
   ....:     future_price=112.98,
   ....:     prices=prices,
   ....:     repo_rate=6.24,
   ....:     settlement=dt(2000, 3, 16),
   ....:     delivery=dt(2000, 6, 30),
   ....:     convention="Act365f"
   ....: )
   ....: 
Out[10]: 
(-0.3436542561467206,
 1.0336684511125043,
 1.2758661359273589,
 3.0103709249974315)

In [11]: future.implied_repo(
   ....:     future_price=112.98,
   ....:     prices=prices,
   ....:     settlement=dt(2000, 3, 16)
   ....: )
   ....: 
Out[11]: 
(7.280230878873247,
 3.5158540419955497,
 2.1696209356561105,
 -1.3952912833468138)

In [12]: future.ytm(future_price=112.98)
Out[12]: (5.301960107610736, 5.339807671798653, 5.391831098248339, 5.437566603312508)

In [13]: future.duration(future_price=112.98)
Out[13]: (8.20178546111166, 8.501520935536226, 8.69035086967293, 9.041578306005354)

In [14]: future.convexity(future_price=112.98)
Out[14]: 
(0.7283734047262407,
 0.8301477419758643,
 0.8327576470105787,
 0.9509416768492558)

In [15]: future.ctd_index(
   ....:     future_price=112.98,
   ....:     prices=prices,
   ....:     settlement=dt(2000, 3, 16)
   ....: )
   ....: 
Out[15]: 0

As opposed to the analogue methods above, we can also use the digital methods, npv(), rate(), but we need to create Curves and a Solver in the usual way.

In [16]: gilt_curve = Curve(
   ....:     nodes={
   ....:         dt(2000, 3, 15): 1.0,
   ....:         dt(2009, 12, 7): 1.0,
   ....:         dt(2010, 11, 25): 1.0,
   ....:         dt(2011, 7, 12): 1.0,
   ....:         dt(2012, 8, 6): 1.0,
   ....:     },
   ....:     id="gilt_curve",
   ....: )
   ....: 

In [17]: solver = Solver(
   ....:     curves=[gilt_curve],
   ....:     instruments=[(b, (), {"metric": "ytm"}) for b in bonds],
   ....:     s=ytms,
   ....:     id="gilt_solver",
   ....:     instrument_labels=["5.75% '09", "9% '11", "6.25% '10", "9% '12"],
   ....: )
   ....: 
SUCCESS: `func_tol` reached after 6 iterations (levenberg_marquardt), `f_val`: 1.4029004547912916e-13, `time`: 0.1202s

Sensitivities are also available; delta() gamma().

In [18]: future.delta(solver=solver)
Out[18]: 
local_ccy                             gbp
display_ccy                           gbp
type        solver      label            
instruments gilt_solver 5.75% '09 -814.17
                        9% '11      -0.00
                        6.25% '10    0.00
                        9% '12       0.00

The delta of a BondFuture is individually assigned to the CTD. If the CTD changes the delta is reassigned.

In [19]: solver.s = [5.3842, 5.2732, 5.2755, 5.52]

In [20]: solver.iterate()
SUCCESS: `func_tol` reached after 6 iterations (levenberg_marquardt), `f_val`: 2.316093834907418e-16, `time`: 0.1362s

In [21]: future.delta(solver=solver)
Out[21]: 
local_ccy                             gbp
display_ccy                           gbp
type        solver      label            
instruments gilt_solver 5.75% '09   32.57
                        9% '11      -0.00
                        6.25% '10   -0.00
                        9% '12    -928.63

In [22]: future.gamma(solver=solver)
Out[22]: 
type                                                    instruments                        
solver                                                  gilt_solver                        
label                                                     5.75% '09 9% '11 6.25% '10 9% '12
local_ccy display_ccy type        solver      label                                        
gbp       gbp         instruments gilt_solver 5.75% '09       -0.00  -0.00     -0.00  -0.03
                                              9% '11          -0.00   0.00     -0.00   0.00
                                              6.25% '10       -0.00  -0.00      0.00   0.00
                                              9% '12          -0.03   0.00      0.00   0.99

Attributes Summary

cfs

Return the conversion factors for each bond in the ordered basket.

notional

Return the notional as number of contracts multiplied by contract nominal.

Methods Summary

cashflows_table([curves, solver, fx, base])

cms(prices, settlement, shifts[, delivery, ...])

Perform CTD multi-security analysis.

convexity(future_price[, delivery])

Return the second derivative of price w.r.t.

ctd_index(future_price, prices, settlement)

Determine the index of the CTD in the basket from implied repo rate.

delta(*args, **kwargs)

Calculate the delta of the Instrument.

dlv(future_price, prices, repo_rate, settlement)

Return an aggregated DataFrame of metrics similar to the Bloomberg DLV function.

duration(future_price[, metric, delivery])

Return the (negated) derivative of price w.r.t.

gamma(*args, **kwargs)

Calculate the gamma of the Instrument.

gross_basis(future_price, prices[, ...])

Calculate the gross basis of each bond in the basket.

implied_repo(future_price, prices, settlement)

Calculate the implied repo of each bond in the basket using the proceeds method.

net_basis(future_price, prices, repo_rate, ...)

Calculate the net basis of each bond in the basket via the proceeds method of repo.

npv([curves, solver, fx, base, local])

Determine the monetary value of the bond future position.

rate([curves, solver, fx, base, metric, ...])

Return various pricing metrics of the security calculated from Curve s.

ytm(future_price[, delivery])

Calculate the yield-to-maturity of the bond future.

Attributes Documentation

cfs#

Return the conversion factors for each bond in the ordered basket.

Return type:

tuple

Notes

This method uses the traditional calculation of obtaining a clean price for each bond on the first delivery date assuming the yield-to-maturity is set as the nominal coupon of the bond future, and scaled to 100.

Warning

Some exchanges, such as EUREX, specify their own conversion factors’ formula which differs slightly in the definition of yield-to-maturity than the implementation offered by rateslib. This results in small differences and is potentially explained in the way dates, holidays and DCFs are handled by each calculator.

For ICE-LIFFE and gilt futures the methods between the exchange and rateslib align which results in accurate values. Official values can be validated against the document ICE-LIFFE Jun23 Long Gilt.

For an equivalent comparison with values which do not exactly align see EUREX Jun23 Bond Futures.

Examples

In [1]: kws = dict(
   ...:     stub="ShortFront",
   ...:     frequency="S",
   ...:     calendar="ldn",
   ...:     currency="gbp",
   ...:     convention="ActActICMA",
   ...:     ex_div=7,
   ...:     settle=1,
   ...: )
   ...: 

In [2]: bonds = [
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2009, 12, 7), fixed_rate=5.75, **kws),
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2011, 7, 12), fixed_rate=9.00, **kws),
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2010, 11, 25), fixed_rate=6.25, **kws),
   ...:     FixedRateBond(dt(1999, 1, 1), dt(2012, 8, 6), fixed_rate=9.00, **kws),
   ...: ]
   ...: 

In [3]: future = BondFuture(
   ...:     delivery=(dt(2000, 6, 1), dt(2000, 6, 30)), coupon=7.0, basket=bonds
   ...: )
   ...: 

In [4]: future.cfs
Out[4]: (0.9142254519590044, 1.152570524483184, 0.9449311626312817, 1.1619558330528528)
notional#

Return the notional as number of contracts multiplied by contract nominal.

Return type:

float

Methods Documentation

cashflows_table(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank)#
cms(prices, settlement, shifts, delivery=NoInput.blank, dirty=False)#

Perform CTD multi-security analysis.

Parameters:
  • prices (sequence of float, Dual, Dual2) – The prices of the bonds in the deliverable basket (ordered).

  • settlement (datetime) – The settlement date of the bonds.

  • shifts (list of float) – The scenarios to analyse.

  • delivery (datetime, optional) – The date of the futures delivery. If not given uses the final delivery day.

  • dirty (bool) – Whether the bond prices are given including accrued interest. Default is False.

Return type:

DataFrame

Notes

This method only operates when the CTD basket has multiple securities

convexity(future_price, delivery=NoInput.blank)#

Return the second derivative of price w.r.t. ytm .

Parameters:
  • future_price (float) – The price of the future.

  • delivery (datetime, optional) – The delivery date of the contract. If not given uses the last delivery day in the delivery window.

Return type:

float

See also

FixedRateBond.convexity

Calculate the convexity of a FixedRateBond.

Example

In [1]: risk = future.duration(112.98)

In [2]: convx = future.convexity(112.98)

In [3]: convx
Out[3]: 
(0.7283734047262407,
 0.8301477419758643,
 0.8327576470105787,
 0.9509416768492558)

Observe the change in risk duration when the prices is increased by 1bp.

In [4]: future.duration(112.98)
Out[4]: (8.20178546111166, 8.501520935536226, 8.69035086967293, 9.041578306005354)

In [5]: future.duration(112.98 + risk[0] / 100)
Out[5]: (8.20906950450452, 8.509530163283793, 8.698210628688548, 9.050204961493332)
ctd_index(future_price, prices, settlement, delivery=NoInput.blank, dirty=False, ordered=False)#

Determine the index of the CTD in the basket from implied repo rate.

Parameters:
  • future_price (float) – The price of the future.

  • prices (sequence of float, Dual, Dual2) – The prices of the bonds in the deliverable basket (ordered).

  • settlement (datetime) – The settlement date of the bonds.

  • delivery (datetime, optional) – The date of the futures delivery. If not given uses the final delivery day.

  • dirty (bool) – Whether the bond prices are given including accrued interest.

  • ordered (bool, optional) – Whether to return the sorted order of CTD indexes and not just a single index for the specific CTD.

Return type:

int

delta(*args, **kwargs)#

Calculate the delta of the Instrument.

For arguments see Sensitivities.delta().

dlv(future_price, prices, repo_rate, settlement, delivery=NoInput.blank, convention=NoInput.blank, dirty=False)#

Return an aggregated DataFrame of metrics similar to the Bloomberg DLV function.

Parameters:
  • future_price (float, Dual, Dual2) – The price of the future.

  • prices (sequence of float, Dual, Dual2) – The prices of the bonds in the deliverable basket (ordered).

  • repo_rate (float, Dual, Dual2 or list/tuple of such) – The repo rates of the bonds to delivery.

  • settlement (datetime) – The settlement date of the bonds.

  • delivery (datetime, optional) – The date of the futures delivery. If not given uses the final delivery day.

  • convention (str, optional) – The day count convention applied to the repo rates.

  • dirty (bool) – Whether the bond prices are given including accrued interest. Default is False.

Return type:

DataFrame

duration(future_price, metric='risk', delivery=NoInput.blank)#

Return the (negated) derivative of price w.r.t. ytm .

Parameters:
  • future_price (float) – The price of the future.

  • metric (str) – The specific duration calculation to return. See notes.

  • delivery (datetime, optional) – The delivery date of the contract.

Return type:

float

See also

FixedRateBond.duration

Calculation the risk of a FixedRateBond.

Example

In [1]: risk = future.duration(112.98)

In [2]: risk
Out[2]: (8.20178546111166, 8.501520935536226, 8.69035086967293, 9.041578306005354)

The difference in yield is shown to be 1bp for the CTD (index: 0) when the futures price is adjusted by the risk amount.

In [3]: future.ytm(112.98)
Out[3]: (5.301960107610736, 5.339807671798653, 5.391831098248339, 5.437566603312508)

In [4]: future.ytm(112.98 + risk[0] / 100)
Out[4]: (5.29196454544367, 5.330164780141207, 5.382397556462216, 5.42849974015735)
gamma(*args, **kwargs)#

Calculate the gamma of the Instrument.

For arguments see Sensitivities.gamma().

gross_basis(future_price, prices, settlement=NoInput.blank, dirty=False)#

Calculate the gross basis of each bond in the basket.

Parameters:
  • future_price (float, Dual, Dual2) – The price of the future.

  • prices (sequence of float, Dual, Dual2) – The prices of the bonds in the deliverable basket (ordered).

  • settlement (datetime) – The settlement date of the bonds, required only if dirty is True.

  • dirty (bool) – Whether the bond prices are given including accrued interest.

Return type:

tuple

implied_repo(future_price, prices, settlement, delivery=NoInput.blank, convention=NoInput.blank, dirty=False)#

Calculate the implied repo of each bond in the basket using the proceeds method.

Parameters:
  • future_price (float, Dual, Dual2) – The price of the future.

  • prices (sequence of float, Dual, Dual2) – The prices of the bonds in the deliverable basket (ordered).

  • settlement (datetime) – The settlement date of the bonds.

  • delivery (datetime, optional) – The date of the futures delivery. If not given uses the final delivery day.

  • convention (str, optional) – The day count convention used in the rate.

  • dirty (bool) – Whether the bond prices are given including accrued interest.

Return type:

tuple

net_basis(future_price, prices, repo_rate, settlement, delivery=NoInput.blank, convention=NoInput.blank, dirty=False)#

Calculate the net basis of each bond in the basket via the proceeds method of repo.

Parameters:
  • future_price (float, Dual, Dual2) – The price of the future.

  • prices (sequence of float, Dual, Dual2) – The prices of the bonds in the deliverable basket (ordered).

  • repo_rate (float, Dual, Dual2 or list/tuple of such) – The repo rates of the bonds to delivery.

  • settlement (datetime) – The settlement date of the bonds, required only if dirty is True.

  • delivery (datetime, optional) – The date of the futures delivery. If not given uses the final delivery day.

  • convention (str, optional) – The day count convention applied to the repo rates.

  • dirty (bool) – Whether the bond prices are given including accrued interest.

Return type:

tuple

npv(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank, local=False)#

Determine the monetary value of the bond future position.

This method is mainly included to calculate risk sensitivities. The monetary value of bond futures is not usually a metric worth considering. The profit or loss of a position based on entry level is a more common metric, however the initial value of the position does not affect the risk.

See BaseDerivative.npv().

rate(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank, metric='future_price', delivery=NoInput.blank)#

Return various pricing metrics of the security calculated from Curve s.

Parameters:
  • curves (Curve, str or list of such) –

    A single Curve or id or a list of such. A list defines the following curves in the order:

    • Forecasting Curve for leg1.

    • Discounting Curve for leg1.

  • solver (Solver, optional) – The numerical Solver that constructs Curves from calibrating instruments.

  • fx (float, FXRates, FXForwards, optional) – The immediate settlement FX rate that will be used to convert values into another currency. A given float is used directly. If giving a FXRates or FXForwards object, converts from local currency into base.

  • base (str, optional) – The base currency to convert cashflows into (3-digit code), set by default. Only used if fx is an FXRates or FXForwards object.

  • metric (str in {"future_price", "ytm"}, optional) – Metric returned by the method.

  • delivery (datetime, optional) – The date of the futures delivery. If not given uses the final delivery day.

Return type:

float, Dual, Dual2

Notes

This method determines the ‘futures_price’ and ‘ytm’ by assuming a net basis of zero and pricing from the cheapest to delivery (CTD).

ytm(future_price, delivery=NoInput.blank)#

Calculate the yield-to-maturity of the bond future.

Parameters:
  • future_price (float, Dual, Dual2) – The price of the future.

  • delivery (datetime, optional) – The future delivery day on which to calculate the yield. If not given aligns with the last delivery day specified on the future.

Return type:

tuple