instrumentPricer

首发版本:3.00.4

语法

instrumentPricer(instrument, pricingDate, marketData)

详情

对一个或多个金融合约(可为相同类型或不同类型)进行定价。

在 DolphinDB 中,每个金融合约可抽象为一个 INSTRUMENT 类型,定价需要用到的市场数据(即期/曲线/曲面)也可抽象为 MKTDATA 类型。系统根据既定规则,将合约与对应的市场数据自动匹配,从而进行批量定价。
注:
DolphinDB 还提供了基础定价函数,如 bondPricerirDepositPricer 等。instrumentPricer 与这些函数的区别在于:
  • 基础定价函数针对单一资产类型设计,每个函数只能对特定类型的金融工具定价。用户需要手动指定每个定价函数所需的具体市场数据参数(如折现曲线、远期曲线、即期汇率、波动率曲面等),不同函数的市场数据参数各不相同。对多种资产类型定价时,需要分别调用不同函数并编写 if-else 逻辑进行分发。
  • instrumentPricer 提供统一的定价接口,系统根据合约信息自动确定所需市场数据的名称(如折现曲线名、远期曲线名),再从 marketData(无论是向量、嵌套字典、引擎句柄还是自定义函数)中按该名称查找对应对象(具体匹配规则参考下文资产中的说明)。不同类型的合约可放入同一向量中批量定价。

参数

instrument INSTRUMENT 类型对象,表示需要定价的金融工具。可以是单个合约,也可以是多个合约。

pricingDate DATE 类型标量,表示定价日,即计算合约价值所对应的日期。

marketData MKTDATA 类型向量/嵌套字典/ 市场数据引擎句柄/用户自定义函数,表示市场数据。

  • MKTDATA 类型向量:

    • 若为曲线类市场数据,需指定 curveName 字段。

    • 若为曲面类市场数据,需指定 surfaceName 字段。

  • 嵌套字典的结构如下:

    • 第一层:key 为数据类别,可选值:"Price", "Curve", "Surface"。

    • 第二层:key 为定价日期(DATE 类型标量)。

    • 第三层:key 为曲线或曲面名称,value 为对应的 MKTDATA 类型标量。

  • 自定义函数:参数为 (kind,date,name)。

返回值

  • instrument 为标量:返回 DOUBLE 类型标量,表示该合约的定价结果。

  • instrument 为向量:返回 DOUBLE 类型向量,依次表示输入合约的定价结果。

instrument 和 marketData 的匹配规则

instrumentmarketData 之间不是按位置一一对应,而是按名称查找。无论 instrumentmarketData 是否以向量形式传入,系统都会先确定每个合约定价所需的市场数据名称,再在 marketData 中查找同名的 MKTDATA 对象。

  1. 系统根据 instrument 中的显式字段(如 discountCurve、forwardCurve)或下文定义的预定义规则,确定该合约需要哪些市场数据名称。

  2. 系统在 marketData 中按名称查找对应的 MKTDATA 对象,并用于定价。

因此,instrumentmarketData 即使都是向量,长度也不要求一致;只要 marketData 中包含所有合约定价所需的命名市场数据即可。

下文将按金融工具类型说明 instrumentmarketData 的匹配规则。每个资产类型章节中的表格和规则说明,即为该类型的完整预定义规则;系统会按照这些规则确定所需市场数据的名称,并据此在 marketData 中完成匹配。

债券(Bond)

债券定价需要用到折现曲线。用户可以通过 discountCurve 字段指定折现曲线名称,例如:

bond = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",
    "instrumentId": "1382011.IB",
    "start": 2013.01.14,
    "maturity": 2028.01.14,
    "issuePrice": 100.0,
    "coupon": 0.058,
    "frequency": "Annual",
    "dayCountConvention": "ActualActualISDA",
    "currency": "CNY",              //可选字段 
    "subType": "MTN",               //可选字段
    "creditRating": "AAA",          //可选字段
    "discountCurve": "CNY_MTN_AAA"  //可选字段
}

定价时的折现曲线选择规则如下:

  • 如果 discountCurve 已指定,则优先使用 discountCurve 的值。

  • 如果 discountCurve 未指定:
    • 指定了 currency,subType 和 creditRating,系统会选择名为 currency + "_" + subType + "_" + creditRating 的折现曲线。
    • 指定了 currency,且 subType 为 TREASURY_BONDCENTRAL_BANK_BILLCDB_BONDEIBC_BONDADBC_BOND 之一,则不需要 creditRating,系统会选择名为 currency + "_" + subType 的折现曲线。
    • 指定了 currency,且 subType 不为 TREASURY_BONDCENTRAL_BANK_BILLCDB_BONDEIBC_BONDADBC_BOND 之一,同时未指定 creditRating,系统会选择名为 currency + "_TREASURY_BOND" 的折现曲线。
    • 指定了 currency,且未指定 subType 和 creditRating,系统会选择名为 currency + "_TREASURY_BOND" 的折现曲线。
    • currency,subType 和 creditRating 均未指定,系统会选择名为 "CNY_TREASURY_BOND" 的折现曲线。

浮动利率债券定价还需要远期曲线:

  • 贴现曲线的选择规则与其他债券相同。

  • 必须在 INSTRUMENT 的 forwardCurve 字段中指定远期曲线名称,并在 marketData 中提供同名 IrYieldCurve。系统不会为浮动利率债券自动生成默认远期曲线名称。

  • 若指定 spreadCurve,还须在 marketData 中提供同名利差曲线。

国债期货(BondFutures)

无需指定 discountCurve,函数会使用其标的债券(underlying)的 discountCurve。

存款(Deposit)

存款定价仅需指定折现曲线 discountCurve:

  • 如果 discountCurve 已指定,则使用用户指定的曲线进行定价。

  • 如果未指定,则根据币种自动匹配折现曲线,规则如下:

currency discountCurve
CNY CNY_FR_007
USD USD_SOFR
EUR EUR_ESTR

利率互换(IrFixedFloatingSwap)

利率互换定价需要传入三条曲线:discountCurve、forwardCurve 和 assetPriceCurve。当前版本仅支持以 FR_007 和 SHIBOR_3M 作为浮动参考利率的利率互换。

  • 如果用户在 instrument 中指定了相应曲线,则使用用户指定的曲线进行定价。

  • 如果未指定,则根据币种和浮动利率基准自动匹配三条默认曲线,如下表所示:

currency iborIndex discountCurve forwardCurve assetPriceCurve
CNY FR_007 CNY_FR_007 CNY_FR_007 PRICE_FR_007
CNY SHIBOR_3M CNY_FR_007 CNY_SHIBOR_3M PRICE_SHIBOR_3M

其中 assetPriceCurve 填入的是浮动参考利率的历史数据,用于计算定价日起第一笔现金流的浮动利率。

外汇远期(FxForward)/ 外汇掉期(FxSwap)

这两类线性产品定价需要绑定 domesticCurve 和 foreignCurve,并基于 currencyPair 获取相应的 FxSpot。

  • 若用户在 instrument 中指定了 domesticCurve 和 foreignCurve,则直接使用用户指定的曲线。

  • 若未指定,则系统会根据货币对自动匹配默认曲线,如下表所示:

currencyPair domesticCurve foreignCurve
USDCNY CNY_FR_007 USD_USDCNY_FX
EURCNY CNY_FR_007 EUR_EURCNY_FX
EURUSD USD_SOFR EUR_EURUSD_FX

其中 foreignCurve 是根据外汇掉期交易,并结合利率平价公式推导得到的外币隐含即期曲线。

外汇欧式期权(FxEuropeanOption)

外汇期权定价除需使用 domesticCurve 与 foreignCurve 外,还依赖 FxSpot 和 FxVolatilitySurface。

这两个市场数据均可根据期权的 underlying(货币对) 自动匹配。

  • 若用户在 instrument 中明确指定,则优先使用用户提供的 domesticCurve、foreignCurve。

  • 若未指定,则系统会根据 currencyPair 自动匹配,规则如下:

currencyPair fxSpot domesticCurve foreignCurve volSurf
USDCNY USDCNY CNY_FR_007 USD_USDCNY_FX USDCNY
EURCNY EURCNY CNY_FR_007 EUR_EURCNY_FX EURCNY
EURUSD EURUSD USD_SOFR EUR_EURUSD_FX EURUSD

例子

本节展示 instrumentPricer 在不同场景下的使用方法。

首先,定义多种类型的金融工具(外汇远期、外汇掉期、外汇欧式期权、债券、国债期货、存款、利率互换)以及对应的市场数据(即期汇率、收益率曲线、波动率曲面、历史价格曲线)。

第一步:定义待定价的合约

fxFwd1 = {
    "productType": "Forward",
    "forwardType": "FxForward",
    "expiry": 2025.10.08,
    "delivery": 2025.10.10,
    "currencyPair": "USDCNY",
    "direction": "Buy",
    "notionalCurrency": "USD",
    "notionalAmount": 1E6,
    "strike": 7.2
}
fxFwdUsdCny = parseInstrument(fxFwd1)
fxFwd2 = {
    "productType": "Forward",
    "forwardType": "FxForward",
    "expiry": 2025.10.08,
    "delivery": 2025.10.10,
    "currencyPair": "EURCNY",
    "direction": "Buy",
    "notionalCurrency": "EUR",
    "notionalAmount": 1E6,
    "strike": 8.2
}
fxFwdEurCny = parseInstrument(fxFwd2)

创建外汇掉期。

// 外汇远期
fxFwd1 = {
    "productType": "Forward",
    "forwardType": "FxForward",
    "expiry": 2025.10.08,
    "delivery": 2025.10.10,
    "currencyPair": "USDCNY",
    "direction": "Buy",
    "notionalCurrency": "USD",
    "notionalAmount": 1E6,
    "strike": 7.2
}
fxFwdUsdCny = parseInstrument(fxFwd1)

fxFwd2 = {
    "productType": "Forward",
    "forwardType": "FxForward",
    "expiry": 2025.10.08,
    "delivery": 2025.10.10,
    "currencyPair": "EURCNY",
    "direction": "Buy",
    "notionalCurrency": "EUR",
    "notionalAmount": 1E6,
    "strike": 8.2
}
fxFwdEurCny = parseInstrument(fxFwd2)

// 外汇掉期
fxSwap1 = {
    "productType": "Swap",
    "swapType": "FxSwap",
    "currencyPair": "USDCNY",
    "direction": "Buy",
    "notionalCurrency": "USD",
    "notionalAmount": 1E6,
    "nearStrike": 7.2,
    "nearExpiry": 2025.12.08,
    "nearDelivery": 2025.12.10,
    "farStrike": 7.3,
    "farExpiry": 2026.06.08,
    "farDelivery": 2026.06.10
}
fxSwapUsdCny = parseInstrument(fxSwap1)

fxSwap2 = {
    "productType": "Swap",
    "swapType": "FxSwap",
    "currencyPair": "EURCNY",
    "direction": "Buy",
    "notionalCurrency": "EUR",
    "notionalAmount": 1E6,
    "nearStrike": 8.2,
    "nearExpiry": 2025.12.08,
    "nearDelivery": 2025.12.10,
    "farStrike": 8.3,
    "farExpiry": 2026.06.08,
    "farDelivery": 2026.06.10
}
fxSwapEurCny = parseInstrument(fxSwap2)

// 外汇欧式期权
fxOption1 = {
    "productType": "Option",
    "optionType": "EuropeanOption",
    "assetType": "FxEuropeanOption",
    "notionalCurrency": "USD",
    "notionalAmount": 1E6,
    "strike": 7.0,
    "maturity": 2025.12.08,
    "payoffType": "Call",
    "dayCountConvention": "Actual365",
    "underlying": "USDCNY"
}
fxOptionUsdCny = parseInstrument(fxOption1)

fxOption2 = {
    "productType": "Option",
    "optionType": "EuropeanOption",
    "assetType": "FxEuropeanOption",
    "notionalCurrency": "EUR",
    "notionalAmount": 1E6,
    "strike": 8.0,
    "maturity": 2025.12.08,
    "payoffType": "Call",
    "dayCountConvention": "Actual365",
    "underlying": "EURCNY"
}
fxOptionEurCny = parseInstrument(fxOption2)

// 债券
bond1 = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",
    "instrumentId": "220010.IB",
    "start": 2020.12.25,
    "maturity": 2031.12.25,
    "issuePrice": 100.0,
    "coupon": 0.0149,
    "frequency": "Annual",
    "dayCountConvention": "ActualActualISDA",
    "discountCurve": "CNY_TREASURY_BOND"
}
bond = parseInstrument(bond1)

// 国债期货
bondFut1 = {
    "productType": "Futures",
    "futuresType": "BondFutures",
    "instrumentId": "T2509",
    "nominal": 100.0,
    "maturity": 2025.09.12,
    "settlement": 2025.09.16,
    "underlying": bond1,
    "nominalCouponRate": 0.03
}
bondFut = parseInstrument(bondFut1)

// 存款
deposit1 = {
    "productType": "Cash",
    "assetType": "Deposit",
    "start": 2025.06.15,
    "maturity": 2025.12.15,
    "rate": 0.02,
    "dayCountConvention": "Actual360",
    "notionalCurrency": "CNY",
    "notionalAmount": 1E6,
    "payReceive": "Receive"
}
deposit = parseInstrument(deposit1)

// 利率互换
irs1 = {
    "productType": "Swap",
    "swapType": "IrSwap",
    "irSwapType": "IrFixedFloatingSwap",
    "start": 2025.06.16,
    "maturity": 2028.06.16,
    "frequency": "Quarterly",
    "fixedRate": 0.018,
    "calendar": "CFET",
    "fixedDayCountConvention": "Actual365",
    "floatingDayCountConvention": "Actual365",
    "payReceive": "Pay",
    "iborIndex": "FR_007",
    "spread": 0.0001,
    "notionalCurrency": "CNY",
    "notionalAmount": 1E8
}
irs = parseInstrument(irs1)

第二步:定义定价需要用到的市场数据

aod = 2025.08.18

fxSpot1 = {
    "mktDataType": "Price",
    "priceType": "FxSpotRate",
    "spotDate": aod + 2,
    "referenceDate": aod,
    "value": 7.1627,
    "unit": "USDCNY"
}
fxSpotUsdCny = parseMktData(fxSpot1)

fxSpot2 = {
    "mktDataType": "Price",
    "priceType": "FxSpotRate",
    "spotDate": aod + 2,
    "referenceDate": aod,
    "value": 8.3768,
    "unit": "EURCNY"
}
fxSpotEurCny = parseMktData(fxSpot2)

curve1 = {
    "mktDataType": "Curve",
    "curveType": "IrYieldCurve",
    "curveName": "CNY_FR_007",
    "referenceDate": aod,
    "currency": "CNY",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Continuous",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
        2026.02.24, 2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
    "values":[1.4759, 1.5331, 1.5697, 1.5239, 1.4996, 1.5144, 1.5209,
        1.5539, 1.5461, 1.5316, 1.5376, 1.5435, 1.5699] / 100.0
}
curveCnyFr007 = parseMktData(curve1)

curve2 = {
    "mktDataType": "Curve",
    "curveType": "IrYieldCurve",
    "curveName": "USD_USDCNY_FX",
    "referenceDate": aod,
    "currency": "USD",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Continuous",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
        2026.02.24, 2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
    "values":[4.3345, 4.3801, 4.3119, 4.3065, 4.2922, 4.2196, 4.1599,
        4.0443, 4.0244, 3.9698, 3.7740, 3.6289, 3.5003] / 100.0
}
curveUsdUsdCnyFx = parseMktData(curve2)

curve3 = {
    "mktDataType": "Curve",
    "curveType": "IrYieldCurve",
    "curveName": "EUR_EURCNY_FX",
    "referenceDate": aod,
    "currency": "EUR",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Continuous",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
        2026.02.24, 2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
    "values":[1.9165, 1.9672, 1.8576, 1.8709, 1.8867, 1.8749, 1.8700,
        1.8576, 1.9253, 1.9738, 1.9908, 1.9850, 2.0362] / 100.0
}
curveEurEurCnyFx = parseMktData(curve3)

surf1 = {
    "surfaceName": "USDCNY",
    "mktDataType": "Surface",
    "surfaceType": "FxVolatilitySurface",
    "referenceDate": aod,
    "smileMethod": "Linear",
    "termDates": [2025.08.21, 2026.08.20],
    "volSmiles":[{"strikes": [6.5, 7, 7.5], "vols": [0.1, 0.1, 0.1]}, {"strikes": [6.5, 7, 7.5], "vols": [0.1, 0.1, 0.1]}],
    "currencyPair": "USDCNY"
}
surfUsdCny = parseMktData(surf1)

surf2 = {
    "surfaceName": "EURCNY",
    "mktDataType": "Surface",
    "surfaceType": "FxVolatilitySurface",
    "referenceDate": aod,
    "smileMethod": "Linear",
    "termDates": [2025.08.21, 2026.08.20],
    "volSmiles":[{"strikes": [7.5, 8.0, 8.5], "vols": [0.1, 0.1, 0.1]}, {"strikes": [7.5, 8.0, 8.5], "vols": [0.1, 0.1, 0.1]}],
    "currencyPair": "EURCNY"
}
surfEurCny = parseMktData(surf2)

bondCurve = {
    "mktDataType": "Curve",
    "curveType": "IrYieldCurve",
    "referenceDate": aod,
    "currency": "CNY",
    "curveName": "CNY_TREASURY_BOND",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Compounded",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "frequency": "Annual",
    "dates":[2025.09.18, 2025.11.18, 2026.02.18, 2026.08.18, 2027.08.18, 2028.08.18, 2030.08.18,
        2032.08.18, 2035.08.18, 2040.08.18, 2045.08.18, 2055.08.18, 2065.08.18, 2075.08.18],
    "values":[1.3000, 1.3700, 1.3898, 1.3865, 1.4299, 1.4471, 1.6401,
        1.7654, 1.7966, 1.9930, 2.1834, 2.1397, 2.1987, 2.2225] / 100.0
}
curveCnyTreasuryBond = parseMktData(bondCurve)

fr007HistCurve = {
    "mktDataType": "Curve",
    "curveType": "AssetPriceCurve",
    "curveName": "PRICE_FR_007",
    "referenceDate": aod,
    "currency": "CNY",
    "dates":[2025.05.09, 2025.05.12, 2025.05.13, 2025.05.14, 2025.05.15, 2025.05.16, 2025.05.19, 2025.05.20,
        2025.05.21, 2025.05.22, 2025.05.23, 2025.05.26, 2025.05.27, 2025.05.28, 2025.05.29, 2025.05.30,
        2025.06.03, 2025.06.04, 2025.06.05, 2025.06.06, 2025.06.09, 2025.06.10, 2025.06.11, 2025.06.12,
        2025.06.13, 2025.06.16, 2025.06.17, 2025.06.18, 2025.06.19, 2025.06.20, 2025.06.23, 2025.06.24,
        2025.06.25, 2025.06.26, 2025.06.27, 2025.06.30, 2025.07.01, 2025.07.02, 2025.07.03, 2025.07.04,
        2025.07.07, 2025.07.08, 2025.07.09, 2025.07.10, 2025.07.11, 2025.07.14, 2025.07.15, 2025.07.16,
        2025.07.17, 2025.07.18, 2025.07.21, 2025.07.22, 2025.07.23, 2025.07.24, 2025.07.25, 2025.07.28,
        2025.07.29, 2025.07.30, 2025.07.31, 2025.08.01, 2025.08.04, 2025.08.05, 2025.08.06, 2025.08.07,
        2025.08.08, 2025.08.11, 2025.08.12, 2025.08.13, 2025.08.14, 2025.08.15],
    "values":[1.6000, 1.5600, 1.5300, 1.5500, 1.5500, 1.6300, 1.6500, 1.6000, 1.5900, 1.5800,
        1.6300, 1.7000, 1.7000, 1.7000, 1.7500, 1.7500, 1.5900, 1.5800, 1.5700, 1.5600,
        1.5500, 1.5500, 1.5600, 1.5900, 1.5900, 1.5700, 1.5500, 1.5600, 1.5679, 1.6000,
        1.5700, 1.8500, 1.8300, 1.8400, 1.8500, 1.9500, 1.6036, 1.5800, 1.5200, 1.5000,
        1.5000, 1.5100, 1.5100, 1.5300, 1.5200, 1.5500, 1.6000, 1.5400, 1.5400, 1.5000,
        1.5000, 1.4800, 1.5000, 1.6000, 1.7500, 1.6400, 1.6200, 1.6300, 1.6000, 1.5000,
        1.4800, 1.4700, 1.4800, 1.4900, 1.4600, 1.4600, 1.4600, 1.4800, 1.4800, 1.4900] \ 100
}
priceCurveFr007 = parseMktData(fr007HistCurve)

场景一:向量形式的批量定价

当拥有一组静态市场数据时,可以直接将多个合约放入一个 INSTRUMENT 向量,并将所需的 Price、Curve、Surface 等市场数据放入 MKTDATA 向量。系统会自动根据合约中的名称字段或默认匹配规则查找对应市场数据。本例演示如何通过一个统一接口同时定价外汇远期、外汇掉期、外汇欧式期权、债券、国债期货、存款和利率互换。

注意:合约向量与市场数据向量的长度不需要一致,系统完全基于名称进行自动匹配。

instruments = [fxFwdUsdCny, fxFwdEurCny, fxSwapUsdCny, fxSwapEurCny,
    fxOptionUsdCny, fxOptionEurCny, bond, bondFut, deposit, irs]

mktData = [fxSpotUsdCny, fxSpotEurCny, curveCnyFr007, curveUsdUsdCnyFx, curveEurEurCnyFx,
    surfUsdCny, surfEurCny, curveCnyTreasuryBond, priceCurveFr007]

pricingDate = aod
// 系统自动按名称匹配,不要求合约向量和市场数据向量长度一致
results1 = instrumentPricer(instruments, pricingDate, mktData)
print(results1)
// output: [-65560.1519,171923.5349,180871.3848,117636.4977,29773.4419,50067.7879,99.6008,107.7764,1005141.9397,-651143.5256]

场景二:嵌套字典形式的市场数据

在处理多日期、多资产类别的历史回测或复杂组合定价时,推荐使用嵌套字典。通过构建三层结构(类别 -> 日期 -> 名称)的嵌套字典,可以同时管理 Price、Curve 和 Surface 等不同类型的市场数据。这种结构化存储方式便于大规模数据检索,也更适合按日期组织历史市场数据

// 层级 3:名称
spots = dict(STRING, MKTDATA)
spots["USDCNY"] = fxSpotUsdCny
spots["EURCNY"] = fxSpotEurCny
curves = dict(STRING, MKTDATA)
curves["CNY_FR_007"] = curveCnyFr007
curves["USD_USDCNY_FX"] = curveUsdUsdCnyFx
curves["EUR_EURCNY_FX"] = curveEurEurCnyFx
curves["CNY_TREASURY_BOND"] = curveCnyTreasuryBond
curves["PRICE_FR_007"] = priceCurveFr007
surfs = dict(STRING, MKTDATA)
surfs["USDCNY"] = surfUsdCny
surfs["EURCNY"] = surfEurCny
// 层级 2:日期
dSpots = dict(DATE, ANY)
dSpots[aod] = spots
dCurves = dict(DATE, ANY)
dCurves[aod] = curves
dSurfs = dict(DATE, ANY)
dSurfs[aod] = surfs
// 层级 1:类别
mktDict = dict(STRING, ANY)
mktDict["Price"] = dSpots
mktDict["Curve"] = dCurves
mktDict["Surface"] = dSurfs
results2 = instrumentPricer(instruments, aod, mktDict)
print(results2)
// output: [-65560.1519,171923.5349,180871.3848,117636.4977,29773.4419,50067.7879,99.6008,107.7764,1005141.9397,-651143.5256]
// 该结果与向量形式 results1 一致,说明不同 marketData 组织形式不影响名称匹配结果。

场景三:使用市场数据引擎

instrumentPricer 支持将 createMktDataEngine 创建的引擎句柄作为 marketData 传入。该方式适合实时行情驱动的定价场景:行情数据持续写入引擎,引擎根据配置自动更新内部市场数据对象;调用 instrumentPricer 时,系统会从引擎中按名称获取最新市场数据。

// 构造首次输入的债券行情。name 对应债券 instrumentId,price 为用于构建收益率曲线的行情价格。
tbdata = table(1:0, `eventTime`type`subType`name`term`price, [NANOTIMESTAMP, STRING, STRING, STRING, STRING, DOUBLE])
insert into tbdata values(now(), "Bond", string(), "0001", "1d", 3.2415)
insert into tbdata values(now(), "Bond", string(), "0002", "1d", 2.1584)

bond1 = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",    
    "instrumentId": "0001",
    "start": 2022.05.15,
    "maturity": 2032.05.15,
    "dayCountConvention": "ActualActualISDA",
    "coupon": 0.0276,
    "issuePrice": 100.0,
    "frequency": "Semiannual"
}

bond2 = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",
    "instrumentId": "0002",
    "start": 2023.05.15,
    "maturity": 2033.05.15,
    "dayCountConvention": "ActualActualISDA",
    "coupon": 0.0276,
    "issuePrice": 100.0,
    "frequency": "Semiannual"
}

// 创建债券收益率曲线配置。name 是曲线名称,instrumentPricer 将按该名称匹配债券所需的折现曲线。
bondcurveConfig = {
    "name": "CNY_TREASURY_BOND",
    "type": "BondYieldCurve",
    "bonds": [parseInstrument(bond1), parseInstrument(bond2)],
    "currency": "CNY",
    "dayCountConvention": "ActualActualISDA",
    "compounding": "Compounded",
    "frequency": "Semiannual",
    "interpMethod": "Linear",
    "extrapMethod": "Flat",
    "method": "Bootstrap"
}

engine = createMktDataEngine("engine", 2022.06.10, bondcurveConfig)
engine.append!(tbdata)

// 引擎异步处理输入行情,示例中通过 sleep 等待引擎完成首次曲线构建。
sleep(1000)

ins = parseInstrument(bond1)
results3 = instrumentPricer([ins], 2022.06.10, engine)
print(results3)
// output: [55.2648]

相关函数createMktDataEngine, createPricingEngine