BondCalcMode#
- class rateslib.instruments.BondCalcMode(settle_accrual, ytm_accrual, v1, v2, v3, c1, ci, cn)#
Bases:
object
Define calculation conventions for
FixedRateBond
,IndexFixedRateBond
andFloatRateNote
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: Cookbook: Understanding and Customising FixedRateBond Conventions
The
BondCalcMode
is used to configure the calculations for accrued interest and yield-to-maturity for a variety of different bonds.The bottom of this page enumerates all of the notation for formulae.
Accrued Interest#
Rateslib makes two types of accrued interest calculations:
Physically settleable accrued interest, AI, returned from the
accrued()
method by default.\[\begin{split}&AI = \xi c_i \qquad \text{if not ex-dividend} \\ &AI = (\xi - 1) c_i \qquad \text{if ex-dividend} \\\end{split}\]Accrued interest for the purpose of determining accurate YTM calculations.
\[\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 both these formula \(c_i\) currently always uses the real
cashflow
method (see below).These two methods are almost always the same, but for an example where they differ consider Canadian government bonds. The calculation mode relies on determining the \(\xi\) and \(\xi_y\) values, known as the accrual fraction. This is achieved by using the following functions:
Accrual Functions
Accrual functions must be supplied to the
settle_accrual
andytm_accrual
arguments. 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 tolinear_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 accrual coupon and settlement, and compares this with DCF between accrual 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 tolinear_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.aschedule[acc_idx]).days ...: s_u = (sch.aschedule[acc_idx + 1] - sch.aschedule[acc_idx]).days ...: return r_u / s_u ...:
Yield-To-Maturity#
Yield-to-maturity in rateslib, for every bond, is calculated using the below formula. The specific discounting and cashflow generating functions must be provided to determine values based on the conventions of that specific bond. The cases where the number of remaining coupons are 1, 2, or generically >2 are outlined explicitly:
\[\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 toannual
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
: usescompounding
, unless settlement occurs in the final period of the bond (and in which case n=1) and then thesimple
method is applied.compounding_stub_act365f
: usescompounding
, 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
: usessimple
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
: usescompounding
unless settlement occurs in the final period of the bond (and in which case n=1) and then thesimple_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}\]
Notation#
The notation used above is described:
\(\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 accrual coupon date and settlement. If a long stub this is either; zero if settlement falls before the accrual quasi-coupon date, or the number of calendar days between those dates.
\(s_u\): The number of calendar days between the last accrual coupon date and the next accrual coupon date, i.e the number of calendar days in the accrual coupon period. If a long stub this is the number of calendar days in the accrual quasi-coupon period.
\(\bar{r}_u\): If a long stub, the number of calendar days between the accrual effective date and either; the next accrual quasi-coupon date, or settlement date, whichever is earliest.
\(\bar{s}_u\): If a long stub, the number of calendar days between the prior accrual quasi-coupon date and the accrual 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 number of coupon periods per annum, e.g. 1-annually, 2-semi, 3-tertiary, 4-quarterly, 6-bi-monthly, 12-monthly.
\(\bar{d}_u\): The DCF between settlement and the next accrual 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.
Attributes Summary
String representation of the parameters for the calculation convention.
Attributes Documentation
- kwargs#
String representation of the parameters for the calculation convention.