Logo

BondPriceFromZeroes

Updated 2023-10-12 15:37:20

Syntax

SELECT [westclintech].[wct].[BondPricefromZeroes](
  <@Settlement, datetime,>
 ,<@Maturity, datetime,>
 ,<@Rate, sql_variant,>
 ,<@CurveSpread, float,>
 ,<@Redemption, float,>
 ,<@Frequency, float,>
 ,<@Basis, nvarchar(4000),>
 ,<@LastCouponDate, datetime,>
 ,<@FirstCouponDate, datetime,>
 ,<@IssueDate, datetime,>
 ,<@CCZero, nvarchar(max),>
 ,<@CurveType, nvarchar(4000),>
 ,<@CurveStartDate, datetime,>
 ,<@CurveDayCount, nvarchar(4000),>
 ,<@CurveFrequency, int,>
 ,<@InterpMethod, nvarchar(4000),>)

Description

Use the scalar function BondPriceFromZeroes to calculate the (clean) price from the z-spread of a bond based on the supplied curve. The Z-spread is entered in decimal format (i.e. 1 basis point = .0001)

Arguments

@FirstCouponDate

For bonds where the first coupon period is either longer or shorter than a regular coupon period, the date of the first coupon payment.

@Basis

Interest basis code for the bond; the day-count convention used in the calculation of the accrued interest.

@Frequency

Coupon frequency of the bond; the number of times that the coupon interest is paid per year.

@LastCouponDate

For bonds where the last coupon period is either longer or shorter than the regular coupon period, the last coupon date prior to the maturity date.

@CurveStartDate

The start date for the curve; used to calculate the time-in-years associated with the coupon dates.

@Rate

Coupon rate of the bond (.01 = 1%). For stepped-rate bonds, an SQL statement which returns a result table consisting of the coupon start dates and the associated coupon rates.

@CurveDayCount

The day-count convention used in calculating the time-in-years associated with the coupon dates. Valid values are (0,1,2,3,4,21); see YEARFRAC documentation for more details.

@CCZero

An SQL statement which produces a resultant table containing 2 columns; the time in years and the rates to be used in the OAS calculation.

@IssueDate

For bonds where the first coupon period is either longer or short than a regular coupon period, the start date for the first period coupon interest.

@CurveFrequency

The compounding frequency used in the calculation of the discount factors when the supplied curve is the spot curve. Valid Values are (1,2,4).

@CurveSpread

Z-spread

@Settlement

Settlement date of the bond.

@CurveType

Identifies the curve in @CCZero as either a spot curve (S) or a continuously compounded zero coupon curve (CC). Valid values are ('S', 'CC').

@InterpMethod

The interpolation method to calculate the rate associated with the coupon dates; use 'L' for linear interpolation and 'S' for cubic spline interpolation.

@Maturity

Maturity date of the bond.

@Redemption

Redemption value of the bond.

Return Type

float

Remarks

If @Settlement is NULL then @Settlement = GETDATE().

If @Maturity is NULL then @Maturity = GETDATE().

If @Rate is NULL then @rate = 0.

If @CurveSpread is NULL then @CurveSpread = 0.

If @Redemption is NULL then @Redemption = 100.

If @Frequency is NULL then @Frequency = 2.

If @Basis is NULL then @Basis = 0.

If @CurveType is NULL then @CurveType = 'CC'.

If @CurveStartDate is NULL then @CurveStartDate = @Settlement.

If @CurveDayCount is NULL then @CurveDayCount = 1.

If @CurveFrequency is NULL then @CurveFrequency = 2.

If @CurveInterpMethod is NULL then @CurveInterpMethod = 'S'.

Examples

Example #1

In this example we put the continuously compounded zeroes into the #ccz temp table and then calculate the price for a bond maturing on 2023-10-01 with a coupon rate of 5.25% paying interest semi-annually. The Z-spread is 327.6 basis points.

SELECT *

INTO #ccz

FROM

(

    VALUES

        (0.011, 0.0031936941106789),

        (0.25, 0.00319251640948496),

        (0.50, 0.0042807233899723),

        (1, 0.00544437632630534),

        (2, 0.00727274510130153),

        (3, 0.00859818036980457),

        (4, 0.0101034030456584),

        (5, 0.0116083325279126),

        (7, 0.0144258819802952),

        (10, 0.0163078262966277),

        (20, 0.0203301487469184),

        (30, 0.0250383019093584)

) n (T, z);

SELECT wct.BondPricefromZeroes(   '2016-11-28',         --@Settlement

                                  '2023-10-01',         --@Maturity

                                  0.0525,               --@Rate

                                  .03276,               --@CurveSpread

                                  100,                  --@Redemption

                                  2,                    --@Frequency

                                  0,                    --@Basis

                                  NULL,                 --@LastCouponDate

                                  NULL,                 --@FirstCouponDate

                                  NULL,                 --@IssueDate

                                  'SELECT * FROM #ccz', --@ZeroRate

                                  NULL,                 --@CurveType

                                  NULL,                 --@CurveStartDate

                                  NULL,                 --@CurveDayCount

                                  NULL,                 --@CurveFrequency

                                  NULL                  --@InterpMethod

                              ) as [Price];

This produces the following result.

{"columns":[{"field":"Price","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"Price":"103.502027365186"}]}

Example #2

In this example we use the same curve as from the previous example, but we are going to calculate the price for a stepped rate bond.

--Put the step information into the #step table
SELECT date_step,
       rate_step
INTO   #step
  FROM (   VALUES ('2020-10-01', .0425),
                  ('2024-10-01', .0625)) n (date_step, rate_step);

--The bond to be evaluated
SELECT wct.BondPricefromZeroes('2016-11-28', --@Settlement
                               '2026-10-01', --@Maturity
                               'SELECT date_step, rate_step FROM #step', --@Rate
                               .00836, --@Spread
                               100, --@Redemption
                               2, --@Frequency
                               0, --@Basis
                               NULL, --@LastCouponDate
                               NULL, --@FirstCouponDate
                               NULL, --@IssueDate
                               'SELECT * FROM #ccz', --@ZeroRate
                               NULL, --@CurveType
                               NULL, --@CurveStartDate
                               NULL, --@CurveDayCount
                               NULL, --@CurveFrequency
                               NULL --@InterpMethod
       ) [Price];

This produces the following result.

{"columns":[{"field":"Price","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"Price":"103.501622687138"}]}

Example #3

In this example we will calculate the price for multiple bonds using a single SQL statement. We will use the same CMT curve as in the previous example, which is stored in the temp table #z. We populate the #bonds table with some information about the bonds. We then calculate the the price for all the bonds in the SELECT.

--Establish the CMT curve

SELECT *

INTO #par

FROM

(

    VALUES

        (0.25, 0.00396),

        (0.5, 0.00520),

        (1, 0.00614),

        (2, 0.00823),

        (3, 0.00987),

        (4, 0.01138),

        (5, 0.01290),

        (7, 0.01605),

        (10, 0.01839),

        (20, 0.02216),

        (30, 0.02593)

) n (T, r);

--Convert the CMT curve to continuously compounded zeroes

SELECT *

INTO #z

FROM wct.CMTCURVE('SELECT * FROM #par', 'S', 2)

WHERE bootstrap = 'False';

--Enter some bonds into a table

SELECT *

INTO #bonds

FROM

(

    VALUES

        ('A', '2025-11-03', 0.0333, 226.7),

        ('B', '2023-05-12', 0.0447, 252),

        ('C', '2029-07-17', 0.0654, 413.6),

        ('D', '2022-08-06', 0.0673, 264.8),

        ('E', '2030-02-18', 0.0649, 404.1),

        ('F', '2024-08-17', 0.047, 237.4),

        ('G', '2023-04-07', 0.0488, 253.6),

        ('H', '2026-05-29', 0.0584, 227.2),

        ('I', '2023-11-06', 0.0426, 245.1),

        ('J', '2027-04-20', 0.0572, 338.9)

) n (id_bond, maturity, rate, spread);

SELECT b.id_bond,

       ROUND(wct.BondPricefromZeroes(   '2016-11-28',       --@Settlement

                                        b.maturity,         --@Maturity

                                        b.rate,             --@Rate

                                        b.spread / 10000,   --@Spread

                                        NULL,               --@Redemption

                                        2,                  --@Frequency

                                        0,                  --@Basis

                                        NULL,               --@LastCouponDate

                                        NULL,               --@FirstCouponDate

                                        NULL,               --@IssueDate

                                        'SELECT * FROM #z', --@ZeroRate

                                        NULL,               --@CurveType

                                        NULL,               --@CurveStartDate

                                        NULL,               --@CurveDayCount

                                        NULL,               --@CurveFrequency

                                        NULL                --@InterpMethod

                                    ),

             3

            ) as [Price]

FROM #bonds b;

This produces the following result.

{"columns":[{"field":"id_bond"},{"field":"Price","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"id_bond":"A","Price":"95.01"},{"id_bond":"B","Price":"102.649"},{"id_bond":"C","Price":"104.995"},{"id_bond":"D","Price":"113.757"},{"id_bond":"E","Price":"105.369"},{"id_bond":"F","Price":"104.604"},{"id_bond":"G","Price":"104.895"},{"id_bond":"H","Price":"114.426"},{"id_bond":"I","Price":"101.56"},{"id_bond":"J","Price":"104.505"}]}

See Also

CMTCURVE - Constant Maturity Treasury curve

LOGNORMALIRLATTICE - LogNormal Interest Rate Lattice

OAC - Option Adjusted Convexity

OAD - Calculate the option-adjusted duration on a bond.

OAS - Option Adjusted Spread

PRICEFROMIRLATTICE - Bond Pricing using Option Adjusted Spread

PRICEFROMZEROESTVF - Zero Volatility spread details

ZSPREAD - Calculate the zero-volatility or static spread on a bond.