eqRangeAccrualOptionPricer

First introduced in version: 3.00.6

Syntax

eqRangeAccrualOptionPricer(instrument, pricingDate, spot, discountCurve, dividendCurve, volSurf, [setting], [model], [method])

Details

Prices an equity range accrual option with the Black-Scholes model and the analytic method. An equity range accrual option is a path-dependent structured derivative whose payoff depends on the proportion of fixing dates on which the underlying price stays within a specified range.

Currently, model only supports "BlackScholes" and method only supports "Analytic".

Parameters

All input vectors must have the same length. Scalar inputs are automatically expanded to match the length of other vectors.

instrument: An INSTRUMENT scalar or vector specifying the equity range accrual option to be priced. For field requirements, see Instrument Field Description.

pricingDate: A DATE scalar or vector specifying the pricing date.

spot: A numeric scalar or vector specifying the spot price of the underlying asset.

discountCurve: A MKTDATA scalar or vector specifying the discount curve (IrYieldCurve). It can be constructed with parseMktData.

dividendCurve: A MKTDATA scalar or vector specifying the dividend curve (DividendCurve). It can be constructed with eqDividendCurveBuilder.

volSurf: A MKTDATA scalar or vector specifying the equity option volatility surface (EqVolatilitySurface). It can be constructed with eqVolatilitySurfaceBuilder.

setting (optional): A dictionary specifying whether to calculate Greeks. It supports the following keys. The value of each key is BOOL, and the default value is false:

Key Description
calcDelta Whether to calculate Delta, the sensitivity of the option price to the underlying asset price.
calcGamma Whether to calculate Gamma, the sensitivity of Delta to the underlying asset price.
calcVega Whether to calculate Vega, the sensitivity of the option price to the underlying asset volatility.
calcTheta Whether to calculate Theta, the sensitivity of the option price to the passage of time.
calcRhoIr Whether to calculate RhoIr, the sensitivity of the option price to the risk-free interest rate.
calcRhoDividend Whether to calculate RhoDividend, the sensitivity of the option price to the dividend yield.

model (optional): A STRING scalar specifying the pricing model. Currently, only "BlackScholes" is supported. The default value is "BlackScholes".

method (optional): A STRING scalar specifying the pricing method. Currently, only "Analytic" is supported. The default value is "Analytic".

Returns

  • If setting is not specified, returns a DOUBLE scalar or vector indicating the net present value (NPV) of the option.
  • If setting is specified, returns a dictionary or vector of dictionaries containing npv and the Greeks requested by setting. Possible keys include npv, delta, gamma, vega, theta, rhoIr, and rhoDividend.

Examples

The following example builds a discount curve, a dividend curve, and an equity option volatility surface, and then prices an equity range accrual option.

// =====================================================
// 1. Set the pricing date, reference date, and underlying spot price
// =====================================================
pricingDate = 2026.02.13
referenceDate = pricingDate
spot = 3.1140
// =====================================================
// 2. Input the option market data
// =====================================================
termDates = [2026.02.25, 2026.03.25, 2026.06.24, 2026.09.23]
callPrices = matrix(
    [0.2655, 0.2155, 0.1656, 0.1156, 0.0318, 0.0039, 0.0015, 0.0008, 0.0003, 0.0001],
    [0.2690, 0.2248, 0.1770, 0.1385, 0.0697, 0.0303, 0.0128, 0.0069, 0.0046, 0.0036],
    [0.3030, 0.2655, 0.2278, 0.1970, 0.1431, 0.0991, 0.0677, 0.0479, 0.0346, 0.0254],
    [0.3330, 0.2987, 0.2681, 0.2388, 0.1883, 0.1448, 0.1139, 0.0899, 0.0715, 0.0574]
)
putPrices = matrix(
    [0.0004, 0.0009, 0.0021, 0.0045, 0.0218, 0.0939, 0.1901, 0.2896, 0.3908, 0.4916],
    [0.0125, 0.0165, 0.0229, 0.0316, 0.0616, 0.1250, 0.2029, 0.2967, 0.3962, 0.4948],
    [0.0396, 0.0507, 0.0634, 0.0798, 0.1253, 0.1814, 0.2499, 0.3321, 0.4175, 0.5077],
    [0.0651, 0.0798, 0.0973, 0.1180, 0.1662, 0.2250, 0.2952, 0.3651, 0.4508, 0.5342]
)
strikes = matrix(
    [2.8500, 2.9000, 2.9500, 3.0000, 3.1000, 3.2000, 3.3000, 3.4000, 3.5000, 3.6000],
    [2.8500, 2.9000, 2.9500, 3.0000, 3.1000, 3.2000, 3.3000, 3.4000, 3.5000, 3.6000],
    [2.8500, 2.9000, 2.9500, 3.0000, 3.1000, 3.2000, 3.3000, 3.4000, 3.5000, 3.6000],
    [2.8500, 2.9000, 2.9500, 3.0000, 3.1000, 3.2000, 3.3000, 3.4000, 3.5000, 3.6000]
)
// =====================================================
// 3. Construct the CNY discount zero-coupon yield curve
// =====================================================
discountCurveDict = {
    "mktDataType": "Curve", "curveType": "IrYieldCurve", "curveName": "CNY_FR_007",
    "referenceDate": referenceDate, "currency": "CNY", "dayCountConvention": "Actual365",
    "compounding": "Continuous", "interpMethod": "Linear", "extrapMethod": "Flat",
    "dates": [referenceDate + 1, referenceDate + 7, referenceDate + 14, referenceDate + 21,
              referenceDate + 30, referenceDate + 61, referenceDate + 91, referenceDate + 182,
              referenceDate + 273, referenceDate + 365, referenceDate + 547, referenceDate + 730,
              referenceDate + 1095],
    "values": [0.016134, 0.016107, 0.016102, 0.016102, 0.016102, 0.016103, 0.016029,
               0.015832, 0.015889, 0.015898, 0.015561, 0.015583, 0.015892]
}
discountCurve = parseMktData(discountCurveDict)
// =====================================================
// 4. Construct the dividend curve using call-put parity
// =====================================================
dividendCurve = eqDividendCurveBuilder(
    referenceDate, termDates, "CallPutParity", ,
    callPrices, putPrices, strikes, spot, discountCurve, "Actual365", "510050"
)
// =====================================================
// 5. Prepare the option prices used to build the volatility surface
// =====================================================
optionPrices = matrix(
    [0.0004, 0.0009, 0.0021, 0.0045, 0.0218, 0.0039, 0.0015, 0.0008, 0.0003, 0.0001],
    [0.0125, 0.0165, 0.0229, 0.0316, 0.0616, 0.0303, 0.0128, 0.0069, 0.0046, 0.0036],
    [0.0396, 0.0507, 0.0634, 0.0798, 0.1253, 0.0991, 0.0677, 0.0479, 0.0346, 0.0254],
    [0.0651, 0.0798, 0.0973, 0.1180, 0.1662, 0.1448, 0.1139, 0.0899, 0.0715, 0.0574]
)
payoffTypes = matrix(
    ["Put", "Put", "Put", "Put", "Put", "Call", "Call", "Call", "Call", "Call"],
    ["Put", "Put", "Put", "Put", "Put", "Call", "Call", "Call", "Call", "Call"],
    ["Put", "Put", "Put", "Put", "Put", "Call", "Call", "Call", "Call", "Call"],
    ["Put", "Put", "Put", "Put", "Put", "Call", "Call", "Call", "Call", "Call"]
)
// =====================================================
// 6. Construct the equity option SABR volatility surface
// =====================================================
volSurface = eqVolatilitySurfaceBuilder(
    referenceDate, termDates, strikes, optionPrices, payoffTypes, spot,
    discountCurve, dividendCurve, "SABR", "50ETF_SABR_20260213"
)
// =====================================================
// 7. Construct the equity range accrual option product
// =====================================================
option = {
    "productType": "Option",
    "optionType": "RangeAccrualOption",
    "assetType": "EqRangeAccrualOption",
    "instrumentId": "0001",
    "notionalAmount": 1000000.0,
    "notionalCurrency": "CNY",
    "maturity": 2026.06.01,
    "delivery": 2026.06.01,
    "underlying": "50ETF",
    "direction": "Buy",
    "dayCountConvention": "Actual365",
    "lowerBarrier": 2.95,
    "upperBarrier": 3.25,
    "coupon": 0.1,
    "fixingDates": [2026.04.01, 2026.05.01],
    "discountCurve": "CNY_FR_007",
    "dividendCurve": "510050"
}
instrument = parseInstrument(option)
// =====================================================
// 8. Set the pricing output fields
// =====================================================
setting = {
    "calcDelta": true,
    "calcGamma": true,
    "calcVega": true,
    "calcTheta": true,
    "calcRhoIr": true,
    "calcRhoDividend": true
}
// =====================================================
// 9. Call the equity range accrual option pricer
// =====================================================
result = eqRangeAccrualOptionPricer(
    instrument,
    pricingDate,
    spot,
    discountCurve,
    dividendCurve,
    volSurface,
    setting
)
// =====================================================
// 10. Output the pricing result
// =====================================================
print(result)

Instrument Field Description

Field Name Data Type Description Required
productType STRING Must be "Option". Yes
optionType STRING Must be "RangeAccrualOption". Yes
assetType STRING Must be "EqRangeAccrualOption". Yes
instrumentId STRING The instrument ID, which can be customized for OTC options. No
maturity DATE The maturity date. Yes
delivery DATE The delivery date. The default value is maturity. No
coupon DOUBLE The coupon rate. Yes
lowerBarrier DOUBLE The lower boundary of the accrual range. Yes
upperBarrier DOUBLE The upper boundary of the accrual range. Yes
fixingDates DATE vector The fixing date sequence. It must be in ascending order. Yes
direction STRING The buy/sell direction. It can be "Buy" or "Sell". The default value is "Buy". No
dayCountConvention STRING The day count convention. It can be "ActualActualISDA", "ActualActualISMA", "Actual365", or "Actual360". Yes
underlying STRING The underlying name, such as "50ETF". Yes
notionalAmount DOUBLE The notional amount. Yes
notionalCurrency STRING The notional currency. The default value is "CNY". No
discountCurve STRING The name of the discount curve used for pricing. The default value is an empty string. No
dividendCurve STRING The name of the dividend curve used for pricing. The default value is an empty string. No

Related functions: parseInstrument, parseMktData, eqDividendCurveBuilder, eqVolatilitySurfaceBuilder