portfolioPricer

语法

portfolioPricer(instrument, amount, pricingDate, marketData)

参数

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

amount INT 类型标量或向量,与 instrument 等长,表示对应的合约数量。

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

marketData MKTDATA 类型向量,或者嵌套字典,表示市场数据。

  • MKTDATA 类型向量:

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

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

  • 嵌套字典的结构如下:

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

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

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

详情

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

返回值:DOUBLE 类型标量。

instrument 和 marketData 的匹配规则

目前支持下图分类树中叶节点所示的金融工具类型:

在定价过程中,系统会按照以下优先级确定市场数据:

  1. instrument 中已显式指定市场数据,则直接使用该数据;

  2. 若未指定,则系统根据预定义规则自动匹配合适的市场数据。

以下将对不同类型金融工具的匹配规则进行说明。

债券(Bond)

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

bond = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",
    "version": 0, 
    "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 已指定,定价函数会直接在 marketData 中查找对应曲线。

  • 如果 discountCurve 未指定,指定了 currency,subType 和 creditRating。系统会自动生成名如 currency + "_" + subType + "_" + creditRating 的折现曲线,其中 currency 默认为 "CNY"。

  • 如果以上这些可选字段均未指定,折现曲线默认为 "CNY_TREASURY_BOND"。

国债期货(BondFutures)

由于国债期货的可交割券为国债,在定义 instrument 时,折现曲线的选择规则如下:

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

  • 如果未指定,则使用默认折现曲线 "CNY_TREASURY_BOND" 进行定价。

存款(Deposit)

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

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

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

currency discountCurve
CNY CNY_FR_007
USD USD_SOFR
EUR EUR_EONIA

利率互换(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

例子

// instrument

//外汇远期
fxFwd1 = {
    "productType": "Forward",
    "forwardType": "FxForward",
    "version": 0,
    "expiry": 2025.10.08,
    "delivery": 2025.10.10,
    "currencyPair": "USDCNY",
    "direction": "Buy",
    "notional": ["USD", 1E6],
    "strike": 7.2
}

fxFwdUsdCny = parseInstrument(fxFwd1)

fxFwd2 = {
    "productType": "Forward",
    "forwardType": "FxForward",
    "version": 0,
    "expiry": 2025.10.08,
    "delivery": 2025.10.10,
    "currencyPair": "EURCNY",
    "direction": "Buy",
    "notional": ["EUR", 1E6],
    "strike": 8.2
}

fxFwdEurCny = parseInstrument(fxFwd2)

//外汇掉期
fxSwap1 = {
    "productType": "Swap",
    "swapType": "FxSwap",
    "version": 0,
    "currencyPair": "USDCNY",
    "direction": "Buy",
    "notional": ["USD", 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",
    "version": 0,
    "currencyPair": "EURCNY",
    "direction": "Buy",
    "notional": ["EUR", 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",
    "version": 0,
    "notional": ["USD", 1E6],
    "strike": 7.0,
    "maturity": 2025.12.08,
    "payoffType": "Call",
    "dayCountConvention": "Actual365",
    "underlying": "USDCNY"
}

fxOptionUsdCny = parseInstrument(fxOption1)

fxOption2 = {
    "productType": "Option",
    "optionType": "EuropeanOption",
    "assetType": "FxEuropeanOption",
    "version": 0,
    "notional": ["EUR", 1E6],
    "strike": 8.0,
    "maturity": 2025.12.08,
    "payoffType": "Call",
    "dayCountConvention": "Actual365",
    "underlying": "EURCNY"
}

fxOptionEurCny= parseInstrument(fxOption2)

//债券
bond1 = {
    "productType": "Cash",
    "assetType": "Bond",
    "bondType": "FixedRateBond",
    "version": 0, 
    "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",
    "version": 0,
    "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",
    "version": 0, 
    "start": 2025.06.15,
    "maturity": 2025.12.15,
    "rate": 0.02,
    "dayCountConvention": "Actual360",
    "notional":["CNY", 1E6],
    "payReceive": "Receive"
}

deposit = parseInstrument(deposit1)

//利率互换
irs1 =  {
    "productType": "Swap",
    "swapType": "IrSwap",
    "irSwapType": "IrFixedFloatingSwap",
    "version": 0, 
    "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,
    "notional":["CNY", 1E8]
}

irs = parseInstrument(irs1)


//mktData
aod = 2025.08.18

fxSpot1 = {
    "mktDataType": "Spot",
    "spotType": "FxSpot",
    "version": 0, 
    "spotDate": aod+2 ,
    "referenceDate": aod ,
    "value": 7.1627,
    "unit": "USDCNY"
}

fxSpotUsdCny = parseMktData(fxSpot1)

fxSpot2 = {
    "mktDataType": "Spot",
    "spotType": "FxSpot",
    "version": 0, 
    "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",
	"version": 0,
	"referenceDate": "2025.08.18",
	"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",
	"version": 0,
	"referenceDate": "2025.08.18",
	"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",
    // 0.083 0.25 0.5 1.0 2.0 3.0 5.0 7.0 10.0 15.0 20.0 30.0 40.0 50.0
    "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",
    "version": 0,
    "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 = [fxFwdUsdCny, fxFwdEurCny, fxSwapUsdCny, fxSwapEurCny, 
              fxOptionUsdCny, fxOptionEurCny, bond, bondFut, deposit, irs]
mktData= [fxSpotUsdCny, fxSpotEurCny, curveCnyFr007, 
          curveUsdUsdCnyFx, curveEurEurCnyFx, surfUsdCny, 
          surfEurCny, curveCnyTreasuryBond, priceCurveFr007]

pricingDate = aod

amount = [1, 2, 3, 4, 5, 6, -7, -8, 9, 10]

// case1: mktData is a vector
results1 = portfolioPricer(instrument, amount, pricingDate, mktData)
print(results1)

// case2: mktData is a dict
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

dSpots = dict(DATE, ANY)
dSpots[aod] = spots

dCurves = dict(DATE, ANY)
dCurves[aod] = curves

dSurfs = dict(DATE, ANY)
dSurfs[aod] = surfs

mktData2 = dict(STRING, ANY)
mktData2 = {"Spot": dSpots,
            "Curve": dCurves,
            "Surface": dSurfs}

results2 = portfolioPricer(instrument, amount, pricingDate, mktData2)
print(results2)

相关函数:instrumentPricer