BondCalcMode#

class rateslib.instruments.BondCalcMode(settle_accrual, ytm_accrual, v1, v2, v3, c1, ci, cn)#

Bases: object

Define calculation conventions for FixedRateBond, IndexFixedRateBond and FloatRateNote types.

For a list of BondCalcMode that have already been pre-defined see Securities Defaults.

Parameters:
  • settle_accrual (str or Callable) – The calculation type for accrued interest for physical settlement. See notes.

  • ytm_accrual (str or Callable) – The calculation method for accrued interest used in the YTM formula. Often the same as above but not always (e.g. Canadian GBs). See notes.

  • v1 (str or Callable) – The calculation function that defines discounting of the first period of the YTM formula.

  • v2 (str or Callable) – The calculation function that defines discounting of the regular periods of the YTM formula.

  • v3 (str or Callable) – The calculation function that defines discounting of the last period of the YTM formula.

  • c1 (str or Callable) – The calculation function that determines the cashflow amount in the first period of the YTM formula.

  • ci (str or Callable) – The calculation function that determines the cashflow amount in the interim periods of the YTM formula.

  • cn (str or Callable) – The calculation function that determines the cashflow amount in the final period of the YTM formula.

Notes

For an example custom implementation of a BondCalcMode see the cookbook article: Understanding and Customising FixedRateBond Conventions

Notation

The following notation is used in this section:

  • \(\xi\): The accrual fraction is a float, typically, in [0, 1] which defines the amount of a bond’s current cashflow period that is paid at settlement as accrued interest.

  • \(\xi_y\): The accrual fraction determined in a secondary method, used only in YTM calculations and not for physical settlement. (Almost always \(\xi_y\) and \(\xi\) are the same, for an exception see Canadian GBs)

  • \(r_u\): The number of calendar days between the last (unadjusted) coupon date and settlement. If a long stub this is either; zero if settlement falls before the (unadjusted) quasi-coupon date, or the number of calendar days between those dates.

  • \(s_u\): The number of calendar days between the last (unadjusted) coupon date and the next (unadjusted) coupon date, i.e the number of calendar days in the (unadjusted) coupon period. If a long stub this is the number of calendar days in the (unadjusted) quasi-coupon period.

  • \(\bar{r}_u\): If a long stub, the number of calendar days between the accrual effective date and either; the next (unadjusted) quasi-coupon date, or settlement date, whichever is earliest.

  • \(\bar{s}_u\): If a long stub, the number of calendar days between the prior (unadjusted) quasi-coupon date and the (unadjusted) next quasi-coupon date surrounding the accrual effective date.

  • \(d_i\): The full DCF of coupon period, i, calculated with the convention which determines the physical cashflows.

  • \(f\): The frequency of the coupon as integer, 1-annually, 2-semi, 3-tertiary, 4-quarterly, 6-bi-monthly, 12-monthly.

  • \(\bar{d}_u\): The DCF between settlement and the next (unadjusted) coupon date determined with the convention of the accrual function (which may be different to the convention for determining physical bond cashflows)

  • \(c_i\): A coupon cashflow monetary amount, per 100 nominal, for coupon period, i.

  • \(p_d\): Number of days between unadjusted coupon date and payment date in a coupon period, i.e. the pay delay.

  • \(p_D\) = Number of days between previous payment date and current payment date, in a coupon period.

  • \(C\): The nominal annual coupon rate for the bond.

  • \(y\): The yield-to-maturity for a given bond. The expression of which, i.e. annually or semi-annually is derived from the calculation context.

Accrual Functions

Accrual functions must be supplied to the settle_accrual and ytm_accrual arguments, and must output accrual fractions. The available values are:

  • linear_days: A calendar day, linear proportion used in any period. (Used by UK and German GBs).

    \[\xi = r_u / s_u\]
  • linear_days_long_front_split: A modified version of the above which, only for long stub periods, uses a different formula treating the first quasi period as part of the long stub differently. This adjustment is then scaled according to the length of the period. (Treasury method for US Treasuries, see Section 31B ii A.356, Code of Federal Regulations)

    \[\xi = (\bar{r}_u / \bar{s}_u + r_u / s_u) / ( d_i * f )\]
  • 30u360_backward: For stubs this method reverts to linear_days. Otherwise, determines the DCF, under the required convention, of the remaining part of the coupon period from settlement and deducts this from the full accrual fraction.

    \[\xi = 1 - \bar{d_u} f\]
  • 30u360_forward: Calculates the DCF between last (unadjusted) coupon and settlement, and compares this with DCF between (unadjusted) coupon dates, both measured using ‘30u360’ (See MSRB Rule G-33):

    \[\xi = DCF(prior, settlement) / DCF(prior, next)\]
  • act365f_1y: For stubs this method reverts to linear_days. Otherwise, determines the accrual fraction using an approach that uses ACT365F convention. (Used by Canadian GBs)

    \[\begin{split}\xi = \left \{ \begin{matrix} 1.0 & \text{if, } r_u = s_u \\ 1.0 - f(s_u - r_u) / 365 & \text{if, } r_u \ge 365 / f \\ fr_u / 365 & \text{if, } r_u < 365 / f \\ \end{matrix} \right .\end{split}\]

Custom accrual functions can also be supplied where the input arguments signature should accept the bond object, the settlement date, and the index relating to the period in which the relevant coupon period falls. It should return an accrual fraction upto settlement. As an example the code below shows the implementation of the “linear_days” accrual function:

In [1]: def _linear_days(obj, settlement, acc_idx, *args) -> float:
   ...:      sch = obj.leg1.schedule
   ...:      r_u = (settlement - sch.uschedule[acc_idx]).days
   ...:      s_u = (sch.uschedule[acc_idx + 1] - sch.uschedule[acc_idx]).days
   ...:      return r_u / s_u
   ...: 

Calculation of Accrued Interest

Accrued interest, AI, is then calculated according to the following:

\[\begin{split}&AI = \xi c_i \qquad \text{if not ex-dividend} \\ &AI = (\xi - 1) c_i \qquad \text{if ex-dividend} \\\end{split}\]

And accrued interest for the purpose of YTM calculations, \(AI_y\), is:

\[\begin{split}&AI_y = \xi_y c_i \qquad \text{if not ex-dividend} \\ &AI_y = (\xi_y - 1) c_i \qquad \text{if ex-dividend} \\\end{split}\]

Where in these formula \(c_i\) currently always uses the cashflow method (see below).

YTM Calculation and Required Functions

Yield-to-maturity is calculated using the below formula, where specific discounting and cashflow functions must be provided to determine values based on the conventions of a given bond. The below formula outlines the cases where the number of remaining coupons are 1, 2, or generically >2.

\[\begin{split}P &= v_1 \left ( c_1 + 100 \right ), \quad n = 1 \\ P &= v_1 \left ( c_1 + v3(c_n + 100) \right ), \quad n = 2 \\ P &= v_1 \left ( c_1 + \sum_{i=2}^{n-1} c_i v_2^{i-2} v_{2,i} + c_nv_2^{n-2}v_3 + 100 v_2^{n-2}v_3 \right ), \quad n > 2 \\ Q &= P - AI_y\end{split}\]

where,

\[\begin{split}P &= \text{Dirty price}, \; Q = \text{Clean Price} \\ n &= \text{Coupon periods remaining} \\ c_1 &= \text{Cashflow (per 100) on next coupon date (may be zero if ex-dividend)} \\ c_i &= i \text{'th cashflow (per 100) on subsequent coupon dates} \\ v_1 &= \text{Discount value for the initial, possibly stub, period} \\ v_2 &= \text{General discount value for the interim regular periods} \\ v_{2,i} &= \text{Specific discount value for the i'th interim regular period} \\ v_3 &= \text{Discount value for the final, possibly stub, period} \\\end{split}\]

v2 Functions

v2 forms the core, regular part of discounting the cashflows. v2 functions are required when a bond has more than two coupon remaining. This reflects coupon periods that are never stubs. The available functions are described below:

  • regular: uses the traditional discounting function matching the actual frequency of coupons:

    \[v_2 = \frac{1}{1 + y/f}\]
  • annual: assumes an annually expressed YTM disregarding the actual coupon frequency:

    \[v_2 = \left ( \frac{1}{1 + y} \right ) ^ {1/f}\]
  • annual_pay_adjust: an extension to annual that adjusts the period in scope to account for a delay between its unadjusted coupon end date and the actual payment date. (Used by Italian BTPs)

    \[v_2 = \left ( \frac{1}{1 + y} \right ) ^ {1/f}, \qquad \text{and in the current period} \qquad v_{2,i} = v_2 ^ {(1 + p_d / p_D)}\]

v1 Functions

v1 functions are required for every bond. Its value may, or may not, be dependent upon v2. v1 functions have to handle the cases whereby the coupon period in which settlement falls is

  • The first coupon period, and it may be a stub,

  • A regular interim coupon period,

  • The final coupon period and it may be a stub.

The two most common functions for determining v1 are described below:

  • compounding: If a stub then scaled by the length of the stub. At issue, or on a coupon date, for a regular period, v1 converges to v2.

    \[\begin{split}v_1 = v_2^{g(\xi_y)} \quad \text{where,} \quad g(\xi_y) = \left \{ \begin{matrix} 1-\xi_y & \text{if regular,} \\ (1-\xi_y) f d_i & \text{if stub,} \\ \end{matrix} \right . \\\end{split}\]
  • simple: calculation uses a simple interest formula. At issue, or on a coupon date, for a regular period, v1 converges to a ‘regular’ style v2.

    \[v_1 = \frac{1}{1 + g(\xi_y) y / f} \quad \text{where, } g(\xi_y) \text{ defined as above}\]

Combinations, or extensions, of the two above functions are also required for some bond conventions:

  • compounding_final_simple: uses compounding, unless settlement occurs in the final period of the bond (and in which case n=1) and then the simple method is applied.

  • compounding_stub_act365f: uses compounding, unless settlement occurs in a stub period in which case Act365F convention derives the exponent.

    \[v_1 = v_2^{\bar{d}_u} \qquad \text{if stub.}\]
  • simple_long_stub_compounding: uses simple formula except for long stubs, and the calculation is only different if settlement falls before the quasi-coupon. If settlement occurs before the quasi-coupon date then the entire quasi-coupon period applies regular v2 discounting, and the preliminary component has simple method applied.

    \[v_1 = v_2 \frac{1}{1 + [f d_i(1 - \xi_y) - 1] y / f} \qquad \text{if settlement before quasi-coupon in long stub}\]
  • simple_pay_adjust: adjusts the ‘simple’ method to account for the payment date.

    \[\begin{split}v_1 = \frac{1}{1 + g_p(\xi_y) y / f} \quad \text{where,} \quad g_p(\xi_y) = \left \{ \begin{matrix} 1-\xi_y + p_d / p_D & \text{if regular,} \\ (1-\xi_y + p_d / p_D) f d_i & \text{if stub,} \\ \end{matrix} \right .\end{split}\]
  • compounding_pay_adjust: adjusts the ‘compounding’ method to account for payment date.

    \[v_1 = v_2^{g_p(\xi_y)} \quad \text{where, } g_p(\xi_y) \text{ defined as above}\]
  • compounding_final_simple_pay_adjust: uses compounding unless settlement occurs in the final period of the bond (and in which case n=1) and then the simple_pay_adjust method is applied.

v3 Functions

v3 functions will never have a settlement mid period, and are only used in the case of 2 or more remaining coupon periods. The available functions are:

  • compounding: is identical to v1 ‘compounding’ where \(\xi_y\) is set to zero.

  • compounding_pay_adjust: is identical to v1 ‘compounding_pay_adjust’ where \(\xi_y\) is set to zero.

  • simple: is identical to v1 ‘simple’ where \(\xi_y\) is set to zero.

  • simple_pay_adjust: is identical to v1 ‘simple_pay_adjust’ where \(\xi_y\) is set to zero.

  • simple_30e360: uses simple interest with a DCF calculated under 30e360 convention, irrespective of the bond’s underlying convention.

    \[v_3 = \frac{1}{1+\bar{d}_n y}\]

Custom discount functions can also be supplied where the input arguments signature is shown in the below example. It should return a discount factor. The example shows the implementation of the “regular” discount function:

In [2]: def _v2_(
   ...:     obj,         # the bond object
   ...:     ytm,         # y as defined
   ...:     f,           # f as defined
   ...:     settlement,  # datetime
   ...:     acc_idx,     # the index of the period in which settlement occurs
   ...:     v2,          # the numeric value of v2 already calculated
   ...:     accrual,     # the ytm_accrual function to return accrual fractions
   ...: ):
   ...:     return 1 / (1 + ytm / (100 * f))
   ...: 

Cashflow Generating Functions

Most of the time, for the cashflows shown above in the YTM formula, the actual cashflows, as determined by the native schedule and convention on the bond itself, can be used.

This is because the cashflow often aligns with a typical expected amount, i.e. coupon / frequency. Since this is by definition under the ActActICMA convention and unadjusted 30360 will also tend to return standardised coupons.

However, some bonds use a convention which does not lead to standardised coupons, but have YTM formula definitions which do require standardised coupons. An example is Thai Government Bonds.

The available functions here are:

  • cashflow: determine the cashflow for the period by using the native cashflow calculation under the schedule and convention on the bond.

  • full_coupon: determine the cashflow as a full coupon payment, irrespective of period dates, based on the notional of the period and the coupon rate of the bond. This method is only for fixed rate bonds.

    \[c_i = \frac{-N_i C}{f}\]

Attributes Summary

kwargs

String representation of the parameters for the calculation convention.

Attributes Documentation

kwargs#

String representation of the parameters for the calculation convention.