bondZSpreadCalculator

First introduced in version: 3.00.6.1

Syntax

bondZSpreadCalculator(instrument, calcDate, dirtyPrice, discountCurve, [spreadCurve])

Details

Calculates a bond's zero-volatility spread (Z-Spread) from its market dirty price and a discount curve. Z-Spread is a constant spread added to the discount rates for all remaining cash flows so that their total present value equals the market dirty price.

If spreadCurve is specified, the function solves for an additional constant spread on top of the discount curve and the existing credit spread curve. Otherwise, the credit spread is treated as zero.

The compounding field of the discount curve specifies the interest convention: "Simple" (simple interest), "Compounded" (discrete compounding), or "Continuous" (continuous compounding).

Arguments

Note: All input vectors must have the same length. Scalar inputs are extended to match the vector length. A vector of length 1 is still treated as a vector and is not extended as a scalar.

instrument is an INSTRUMENT scalar or vector representing the bond, which can be created with parseInstrument. For a fixed-rate bond, set bondType to "FixedRateBond". See the bond product field specifications in bondPricer for details.

calcDate is a DATE scalar or vector specifying the calculation date. It must match referenceDate of the corresponding discount curve.

dirtyPrice is an integral or floating-point scalar or vector specifying the market dirty price, including accrued interest. Values must be positive and non-NULL. The price must use the same notional basis as the bond's nominal field. For example, when nominal is 100, supply the dirty price per 100 face value.

discountCurve is a MKTDATA scalar or vector representing the discount curve. Its curveType must be "IrYieldCurve". Use parseMktData to parse a curve dictionary into a MKTDATA object. See its interest rate yield curve specifications for the required fields.

spreadCurve (optional) is a MKTDATA scalar or vector representing an existing credit spread curve. Its curveType must be "IrYieldCurve". When omitted or set to NULL, the credit spread is treated as zero. When it is supplied, the return value is the additional spread over the existing credit spread.

Returns

Returns a DOUBLE scalar when all inputs are scalars, or a DOUBLE vector of the same length as the input vectors when any input is a vector.

The result is expressed as a decimal. For example, 0.01 represents 1%, or 100 bp.

Examples

Example 1. Calculate the Z-Spread of a fixed-rate bond with face value 100, an annual coupon rate of 3%, annual coupon payments, and a five-year term. The calculation date is the accrual start date, the market dirty price is 100, and the discount curve is flat at 2% with annual discrete compounding.

valuationDate = 2025.01.01
couponBondSpec = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",
    "nominal": 100.0,
    "start": 2025.01.01,
    "maturity": 2030.01.01,
    "issuePrice": 100.0,
    "coupon": 0.03,
    "frequency": "Annual",
    "dayCountConvention": "ActualActualISDA"
}
couponBond = parseInstrument(obj=couponBondSpec)

discountSpec = {
    "mktDataType": "Curve",
    "curveType": "IrYieldCurve",
    "referenceDate": valuationDate,
    "currency": "CNY",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Compounded",
    "frequency": "Annual",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "dates": [2026.01.01, 2030.01.01],
    "values": [0.02, 0.02]
}
discountCurve = parseMktData(dict=discountSpec)

bondSpread = bondZSpreadCalculator(
    instrument=couponBond,
    calcDate=valuationDate,
    dirtyPrice=100.0,
    discountCurve=discountCurve
)
round(bondSpread, 8)
// output: 0.01

The resulting Z-Spread is 0.01, or 100 bp.

Example 2. Use the bond, calculation date, and discount curve from Example 1, and specify an additional credit spread curve that is flat at 0.5%.

creditSpec = {
    "mktDataType": "Curve",
    "curveType": "IrYieldCurve",
    "referenceDate": valuationDate,
    "currency": "CNY",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Compounded",
    "frequency": "Annual",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "dates": [2026.01.01, 2030.01.01],
    "values": [0.005, 0.005]
}
creditCurve = parseMktData(dict=creditSpec)

additionalSpread = bondZSpreadCalculator(
    instrument=couponBond,
    calcDate=valuationDate,
    dirtyPrice=100.0,
    discountCurve=discountCurve,
    spreadCurve=creditCurve
)
round(additionalSpread, 8)
// output: 0.005

The additional spread returned is 0.005, or 50 bp.

Example 3. Use the bond, calculation date, and discount curve from Example 1 to calculate Z-Spreads for dirty prices of 98, 100, and 102 in one call. The scalar instrument, calcDate, and discountCurve inputs are extended to match the dirtyPrice vector.

marketPrices = [98.0, 100.0, 102.0]
spreadValues = bondZSpreadCalculator(
    instrument=couponBond,
    calcDate=valuationDate,
    dirtyPrice=marketPrices,
    discountCurve=discountCurve
)
round(spreadValues, 8)
// output: [0.01442238,0.01,0.00568655]

Related functions: bondPricer, parseInstrument, parseMktData