createPricingEngine
First introduced in version: 3.00.5
Syntax
createPricingEngine(name, instrument, [handler], [engineConfig], [setting],
[model], [method])
Details
Creates a pricing engine that supports both DolphinDB's built-in functions and user-defined functions or expressions for valuation and pricing.
Pricing Engine currently supports the following built-in pricing functions for asset types:
| Asset Type | Function Name | Description |
|---|---|---|
| Fixed Income | bondPricer | Bond pricing (supports discount bonds, zero-coupon bonds, and fixed-rate bonds) |
| bondFuturesPricer | Treasury bond futures pricing | |
| Interest Rate | irDepositPricer | Deposit pricing |
| irFixedFloatingSwapPricer | Standard interest rate swap pricing | |
| FX | fxForwardPricer | FX forward pricing |
| fxSwapPricer | FX swap pricing | |
| bondPricer | FX European option pricing |
Parameters
name is a STRING scalar indicating the name of the engine. It is the only identifier of an engine on a data or compute node. It can contain letters, digits and "_" and must start with a letter.
instrument is an INSTRUMENT scalar/vector, indicating the instrument(s) to be
priced. During pricing, market data is matched according to the rules defined by
instrumentPricer.
handler (optional) is a user-defined function to handle the results of pricing.
- If
outputTime = trueis set in engineConfig, the function signature isdef(eventTime, name, date, npv, [greek...]). - If
outputTime = false(default value) is set in engineConfig, the function signature isdef(name, date, npv, [greek...]).
Parameter descriptions:
- eventTime: NANOTIMESTAMP, the event time. Passed only if
outputTime=trueis set in engineConfig. - name: STRING, the instrument ID of the pricing target.
- date: DATE, the pricing date.
- npv: DOUBLE, the net present value.
- greek: DOUBLE or DOUBLE[], the greeks. The column names of the greeks are
consistent with the return values of the pricing function. For example, for
bondPricer, the column corresponding to key rate duration is discountCurveKeyRateDuration. The output order of the greeks is fixed as follows, and greeks that are not specified are skipped: delta, gamma, vega, theta, rho, rhoDemestic, rhoForeign, rhoIr, rhoDividend, volga, vanna, discountCurveDelta, discountCurveGamma, and discountCurveKeyRateDuration.
engineConfig (optional) is a dictionary specifying engine runtime configuration. Supported key-value pairs include:
- numThreads (optional): is an INT scalar indicating the number of worker threads. Default is 8.
- maxQueueDepth (optional): is an INT scalar indicating the maximum queue depth. Default is 10,000,000.
- useSystemTime (optional): is a Boolean value indicating whether to use system time as the event time. Default is true.
- timeColumn (optional) is a STRING scalar to specify a NANOTIMESTAMP column as the event time. When specified, input data must contain this column. To specify timeColumn, useSystemTime must be set to false.
- outputTime (optional) is a Boolean value indicating whether to output the event time. Default is false.
setting (optional) is a dictionary (<STRING, ANY>) that specifies pricing settings. For the pricing settings supported by each asset, see the setting parameter of the corresponding pricing function.
-
Key: a string that specifies the asset classification path. The path typically consists of two to three levels, with each level separated by a period. For example, specify “Cash.Bond.DiscountBond” for a discount bond.
-
Value: a dictionary (<STRING, ANY>) that specifies whether to calculate a given Greek metric and provides the parameters required to calculate it. Supports both local and global configuration. When local configuration is specified, the global default value must be configured in the default field.
-
Local configuration:
{ "default": { "calcDiscountCurveDelta": true, "calcDiscountCurveKeyRateDuration": true, "discountCurveShift": 0.0001, "discountCurveKeyTerms": [1.0, 3.0, 5.0], "discountCurveKeyShifts": [0.0002, 0.0003, 0.0001] }, "Cash.Bond.FixedRateBond": { "calcDiscountCurveGamma": true, }, "Cash.Bond.OptionBond": { "calcDiscountCurveGamma": false, "useExerciseCashflow": true } } -
Global configuration:
{ "calcDiscountCurveDelta": true, "calcDiscountCurveGamma": true, "calcDiscountCurveKeyRateDuration": true, "discountCurveShift": 0.0001, "discountCurveKeyTerms": [1.0, 3.0, 5.0], "discountCurveKeyShifts": [0.0002, 0.0003, 0.0001] }
-
model (optional) a string or a dictionary (<STRING, ANY>) that specifies the pricing model. For the pricing model supported by each instrument, see the model parameter of the corresponding pricing function.
-
When a string is passed—for example,
model="DCF"—all instruments are priced using that model. -
When a dictionary is passed, its format is similar to that of the setting parameter, as shown in the following example:
{
"Cash.Bond.FixedRateBond": "DCF",
"Cash.Bond.OptionBond": "DCF"
}
method (optional) is a string or a dictionary (<STRING, ANY>) that specifies the pricing method. For the pricing method supported by each instrument, see the method parameter of the corresponding pricing function.
-
When a string is passed—for example,
method= "Analytic"—all instruments are priced using that method. -
When a dictionary is passed, its format is similar to that of the setting parameter, as shown in the following example:
{
"Cash.Bond.FixedRateBond": "Analytic",
"Cash.Bond.OptionBond": "Analytic"
}
Returns
A handle of the created pricing engine.
Examples
Example 1. This example defines 240025.IB as the pricing instrument. Based on the
default matching rules in instrumentPricer, the instrument is
associated with the market data CNY_TREASURY_BOND, which is subsequently added to
the pricing engine using appendMktData.
try{dropStreamEngine("PRICING_ENGINE")}catch(ex){}
bondDict = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"instrumentId": "240025.IB",
"start": 2024.12.25,
"maturity": 2031.12.25,
"issuePrice": 100.0,
"coupon": 0.0149,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
instrument = parseInstrument(bondDict)
pricingDate = 2025.08.18
curveDict = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"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
}
discountCurve = parseMktData(curveDict)
share streamTable(1:0, `name`date`price, [STRING, DATE, DOUBLE]) as st
def myHandler(name, date, price) {
tableInsert(st, name, date, price)
}
engine = createPricingEngine("PRICING_ENGINE", [instrument], myHandler)
appendMktData(engine, discountCurve)
select * from st
| name | date | price |
|---|---|---|
| 240025.IB | 2025.08.18 | 99.60 |
Example 2. This example uses the 10-year treasury bond futures contract T2409. It first clears and creates FuturesEngine, and writes the npv returned by the engine to the result table through a callback function. It then constructs the deliverable treasury bond and the treasury bond futures contract, configures key parameters such as the conversion factor and settlement date, inserts the treasury bond yield curve as the discount curve, and finally checks the valuation result of the futures contract.
// Clean up any historical engine with the same name to avoid errors when creating it again
try{dropStreamEngine("FuturesEngine")}catch(ex){}
// Create a result table to receive and store valuation results returned by the futures pricing engine callback
share streamTable(1000:0, `engineName`instrumentId`npv`updateTime, [STRING, STRING, DOUBLE, TIMESTAMP]) as futuresResult
// Define the callback function: whenever the engine completes a calculation, write the contract name, NPV, and update time to the result table
def futuresHandler(name, date, npv){
tableInsert(futuresResult, "FuturesEngine", name, npv, now())
}
// Construct the deliverable treasury bond as the underlying bond of treasury bond futures T2409
underlyingBond = parseInstrument({
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"instrumentId": "UNDERLYING_BOND",
"start": 2020.09.15,
"maturity": 2030.09.15,
"issuePrice": 100.0,
"coupon": 0.03,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA",
"currency": "CNY",
"subType": "TREASURY_BOND",
"discountCurve": "CNY_TREASURY_BOND"
})
// Construct the treasury bond futures contract, focusing on the underlying bond, notional coupon, conversion factor, and delivery settlement date
futuresIns = parseInstrument({
"productType": "Futures",
"futuresType": "BondFutures",
"instrumentId": "T2409",
"nominal": 100.0,
"maturity": 2024.09.13,
"settlement": 2024.09.17,
"underlying": underlyingBond,
"nominalCouponRate": 0.03,
"conversionFactor": 0.9812
})
// Create the futures pricing engine and bind the instrument to be valued and the callback function
engine = createPricingEngine("FuturesEngine", futuresIns, futuresHandler)
// Construct the treasury bond yield curve; curveName must match the discountCurve in the underlying bond
discountCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2024.09.10,
"currency": "CNY",
"curveName": "CNY_TREASURY_BOND",
"dayCountConvention": "ActualActualISDA",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2024.12.10, 2025.12.10, 2026.12.10],
"values": [0.000180, 0.000190, 0.000200]
})
// Append market data to the engine, trigger valuation, and write the result to the result table through futuresHandler
appendMktData(engine, discountCurve)
// Check the valuation result of T2409
select * from futuresResult
| engineName | instrumentId | npv | updateTime |
|---|---|---|---|
| FuturesEngine | T2409 | 117.84882688404052 | 2026.08.27 11:45:47.979 |
Example 3. This example uses a 3-month CNY time deposit to show how the pricing engine calculates the present value and accrued interest of the deposit based on the principal, contract rate, and discount curve.
// Clean up any historical engine with the same name to avoid errors when creating it again
try{dropStreamEngine("DepositEngine")}catch(ex){}
// Create a result table to receive and store valuation results returned by the deposit pricing engine callback
share streamTable(1000:0, `engineName`instrumentId`npv`updateTime, [STRING, STRING, DOUBLE, TIMESTAMP]) as depositResult
// Define the callback function: whenever the engine completes a calculation, write the contract name, NPV, and update time to the result table
def depositHandler(name, date, npv){
tableInsert(depositResult, "DepositEngine", name, npv, now())
}
// Construct a 3-month CNY time deposit. The principal currency field of Deposit must use notionalCurrency;
// meanwhile, the principal amount uses notionalAmount, consistent with the interest rate swap example.
depositIns = parseInstrument({
"productType": "Cash",
"assetType": "Deposit",
"instrumentId": "DEP_3M",
"start": 2026.08.27,
"maturity": 2026.11.27,
"rate": 0.018,
"dayCountConvention": "Actual360",
"notionalCurrency": "CNY",
"notionalAmount": 1000000.0,
"payReceive": "Receive",
"discountCurve": "CNY_DISC_CURVE"
})
// Create the deposit pricing engine and bind the instrument to be valued and the callback function
engine = createPricingEngine("DepositEngine", depositIns, depositHandler)
// Construct discount curve market data; curveName corresponds to the discountCurve in the deposit contract
discountCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "CNY_DISC_CURVE",
"dayCountConvention": "Actual360",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2026.09.27, 2026.11.27, 2027.02.27, 2027.08.27],
"values": [0.0155, 0.0165, 0.0170, 0.0180]
})
// Append market data to the engine, trigger valuation, and write the result to the result table through depositHandler
appendMktData(engine, discountCurve)
// Check the valuation result of DEP_3M
select * from depositResult
|
engineName |
instrumentId |
npv |
updateTime |
|---|---|---|---|
| DepositEngine | DEP_3M | 1,000,407.2780936392 | 2026.08.27 13:40:39.896 |
Example 4. This example uses a 5-year fixed-for-floating interest rate swap to help users understand how to estimate the swap value with a discount curve and a floating-leg reference curve, and how to view NPV, the PVs of both legs, and DV01.
// Clean up any historical engine with the same name to avoid errors when creating it again
try{dropStreamEngine("SwapEngine")}catch(ex){}
// Create a result table to receive and store valuation results returned by the interest rate swap pricing engine callback
share streamTable(
1000:0,
`engineName`instrumentId`npv`updateTime,
[STRING, STRING, DOUBLE, TIMESTAMP]
) as swapResult
// Define the callback function: whenever the engine completes a calculation, write the contract name, NPV, and update time to the result table
def swapHandler(name, date, npv){
tableInsert(swapResult, "SwapEngine", name, npv, now())
}
// Construct a 5-year fixed-for-floating interest rate swap;
// in addition to discountCurve / forwardCurve, an FR_007 swap also needs
// assetPriceCurve for historical fixings on the floating leg
irsIns = parseInstrument({
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"instrumentId": "IRS_FR007_5Y",
"start": 2026.08.27,
"maturity": 2031.08.27,
"frequency": "Quarterly",
"fixedRate": 0.0385,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual365",
"payReceive": "Pay",
"iborIndex": "FR_007",
"spread": 0.0,
"notionalCurrency": "CNY",
"notionalAmount": 10000000.0,
// The names of the three curves must match the curveName values in the market data below
"discountCurve": "CNY_DISC_CURVE",
"forwardCurve": "FR007_FWD_CURVE",
"assetPriceCurve": "PRICE_FR_007"
})
// Create the interest rate swap pricing engine and bind the instrument to be valued and the callback function
engine = createPricingEngine(
"SwapEngine",
irsIns,
swapHandler
)
// Construct the CNY discount curve; curveName corresponds to the discountCurve in the swap contract
discountCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "CNY_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [
2026.11.27,
2027.08.27,
2028.08.27,
2029.08.27,
2031.08.27
],
"values": [
0.0180,
0.0185,
0.0190,
0.0200,
0.0220
]
})
// Construct the FR007 forward curve; curveName corresponds to the forwardCurve in the swap contract
forwardCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "FR007_FWD_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [
2026.11.27,
2027.02.27,
2027.08.27,
2028.08.27,
2031.08.27
],
"values": [
0.0195,
0.0200,
0.0210,
0.0220,
0.0240
]
})
// Construct the FR007 historical fixing data curve. This is a very important piece of market data for IRS pricing
// curveType must be AssetPriceCurve
// curveName must correspond to assetPriceCurve in the instrument
fixingDates = 2026.05.19..2026.08.26
fixingRates = take(0.0190, size(fixingDates))
assetPriceCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "AssetPriceCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "PRICE_FR_007",
// Historical FR007 fixing rates
"dates": fixingDates,
"values": fixingRates
})
// Append all three pieces of market data at once to trigger valuation
appendMktData(engine, [discountCurve, forwardCurve, assetPriceCurve])
// Check the valuation result
select * from swapResult
| engineName | instrumentId | npv | updateTime |
|---|---|---|---|
| SwapEngine | IRS_FR007_5Y | -701,240.0307065442 | 2026.08.27 14:35:55.568 |
Example 5. This example uses a 6-month USD/CNY FX forward to explain how the forward exchange rate is affected by the spot exchange rate and the interest rate curves of the two currencies, and outputs the theoretical forward rate and contract NPV.
// Clean up any historical engine with the same name
try{dropStreamEngine("FxFwdEngine")}catch(ex){}
// Result table
share streamTable(1000:0, `engineName`instrumentId`npv`updateTime, [STRING, STRING, DOUBLE, TIMESTAMP]) as fxFwdResult
// Callback function
def fxFwdHandler(name, date, npv){
tableInsert(fxFwdResult, "FxFwdEngine", name, npv, now())
}
// Construct the FX forward contract: use domesticCurve / foreignCurve
fxFwdIns = parseInstrument({
"productType": "Forward",
"forwardType": "FxForward",
"instrumentId": "USDCNY_6M_FWD",
"expiry": 2027.02.27,
"delivery": 2027.03.01,
"currencyPair": "USDCNY",
"direction": "Buy",
"notionalCurrency": "USD",
"notionalAmount": 1000000.0,
"strike": 7.10,
"domesticCurve": "CNY_DISC_CURVE",
"foreignCurve": "USD_DISC_CURVE"
})
// Create the engine
engine = createPricingEngine("FxFwdEngine", fxFwdIns, fxFwdHandler)
// FX spot exchange rate market data
spot = parseMktData({
"mktDataType": "Price",
"priceType": "FxSpotRate",
"referenceDate": 2026.08.27,
"spotDate": 2026.08.29,
"value": 7.1200,
"unit": "USDCNY"
})
// CNY discount curve
cnyCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "CNY_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2026.09.27, 2026.11.27, 2027.02.27],
"values": [0.0155, 0.0165, 0.0170]
})
// USD discount curve
usdCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "USD",
"curveName": "USD_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2026.09.27, 2026.11.27, 2027.02.27],
"values": [0.0440, 0.0430, 0.0415]
})
// Trigger pricing
appendMktData(engine, spot)
appendMktData(engine, cnyCurve)
appendMktData(engine, usdCurve)
// Check the result
select * from fxFwdResult
| engineName | instrumentId | npv | updateTime |
|---|---|---|---|
| FxFwdEngine | USDCNY_6M_FWD | -65,285.58303391563 | 2026.08.27 14:16:54.106 |
Example 6. This example uses a USD/CNY FX swap to show how to evaluate the value of the near-leg and far-leg FX cash flows, and obtain swap points, segment PVs, and overall NPV.
// Clean up any historical engine with the same name
try{dropStreamEngine("FxSwapEngine")}catch(ex){}
// Result table
share streamTable(1000:0, `engineName`instrumentId`npv`updateTime, [STRING, STRING, DOUBLE, TIMESTAMP]) as fxSwapResult
// Callback function
def fxSwapHandler(name, date, npv){
tableInsert(fxSwapResult, "FxSwapEngine", name, npv, now())
}
// Construct the USD/CNY FX swap; also use domesticCurve / foreignCurve to specify curve names
fxSwapIns = parseInstrument({
"productType": "Swap",
"swapType": "FxSwap",
"instrumentId": "USDCNY_SWAP",
"currencyPair": "USDCNY",
"direction": "Buy",
"notionalCurrency": "USD",
"notionalAmount": 1000000.0,
"nearStrike": 7.12,
"nearExpiry": 2026.09.27,
"nearDelivery": 2026.09.29,
"farStrike": 7.15,
"farExpiry": 2027.03.27,
"farDelivery": 2027.03.29,
"domesticCurve": "CNY_DISC_CURVE",
"foreignCurve": "USD_DISC_CURVE"
})
// Create the engine
engine = createPricingEngine("FxSwapEngine", fxSwapIns, fxSwapHandler)
// Spot exchange rate
spot = parseMktData({
"mktDataType": "Price",
"priceType": "FxSpotRate",
"referenceDate": 2026.08.27,
"spotDate": 2026.08.29,
"value": 7.1200,
"unit": "USDCNY"
})
// CNY discount curve
cnyCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "CNY_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2026.09.27, 2027.03.27],
"values": [0.0155, 0.0170]
})
// USD discount curve
usdCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "USD",
"curveName": "USD_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2026.09.27, 2027.03.27],
"values": [0.0440, 0.0415]
})
// Trigger pricing
appendMktData(engine, spot)
appendMktData(engine, cnyCurve)
appendMktData(engine, usdCurve)
// Check the result
select * from fxSwapResult
| engineName | instrumentId | npv | updateTime |
|---|---|---|---|
| FxSwapEngine | USDCNY_SWAP | 109,673.96002695739 | 2026.08.27 14:20:02.733 |
Example 7. This example uses a 3-month USD/CNY European call option to help users understand the roles of the spot exchange rate, interest rate curves, and implied volatility in option pricing, and to view the theoretical value and Greeks such as Delta, Gamma, and Vega.
// Clean up any historical engine with the same name to avoid errors when creating it again
try{dropStreamEngine("FxOptEngine")}catch(ex){}
// Create the result table
share streamTable(
1000:0,
`engineName`instrumentId`npv`updateTime,
[STRING, STRING, DOUBLE, TIMESTAMP]
) as fxOptResult
// Define the callback function
// The default handler signature of createPricingEngine is def(name, date, npv)
def fxOptHandler(name, date, npv){
tableInsert(fxOptResult, "FxOptEngine", name, npv, now())
}
// Construct a 3-month USD/CNY European call option;
// 1) underlying uses the currency pair
// 2) domesticCurve / foreignCurve specify curve names
fxOptIns = parseInstrument({
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"instrumentId": "USDCNY_CALL_7.2",
"notionalCurrency": "USD",
"notionalAmount": 1000000.0,
"strike": 7.20,
"maturity": 2026.11.27,
"delivery": 2026.11.29,
"payoffType": "Call",
"direction": "Buy",
"dayCountConvention": "Actual365",
"underlying": "USDCNY",
// Custom names for the two curves
// The curveName of subsequent IrYieldCurve data must match these values
"domesticCurve": "CNY_DISC_CURVE",
"foreignCurve": "USD_DISC_CURVE"
})
// Create the pricing engine
engine = createPricingEngine("FxOptEngine", fxOptIns, fxOptHandler)
// Construct the USD/CNY spot exchange rate.
// For the pricing engine, FX spot should use Price / FxSpotRate
// unit uses the currency pair name and corresponds to underlying
spot = parseMktData({
"mktDataType": "Price",
"priceType": "FxSpotRate",
"referenceDate": 2026.08.27,
"spotDate": 2026.08.29,
"value": 7.1200,
"unit": "USDCNY"
})
// Construct the CNY discount curve
// curveName corresponds to domesticCurve in the instrument
cnyCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "CNY",
"curveName": "CNY_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [
2026.09.27,
2026.11.27,
2027.02.27
],
"values": [
0.0155,
0.0165,
0.0170
]
})
// Construct the USD discount curve
// curveName corresponds to foreignCurve in the instrument
usdCurve = parseMktData({
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2026.08.27,
"currency": "USD",
"curveName": "USD_DISC_CURVE",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [
2026.09.27,
2026.11.27,
2027.02.27
],
"values": [
0.0440,
0.0430,
0.0415
]
})
// Construct the USD/CNY FX volatility surface
volSurf = parseMktData({
"mktDataType": "Surface",
"surfaceType": "FxVolatilitySurface",
"referenceDate": 2026.08.27,
"surfaceName": "USDCNY",
"currencyPair": "USDCNY",
"smileMethod": "Linear",
// termDates and volSmiles correspond one-to-one
"termDates": [
2026.11.27,
2027.02.27
],
"volSmiles": [
{
"strikes": [6.8, 7.2, 7.6],
"vols": [0.0550, 0.0550, 0.0550]
},
{
"strikes": [6.8, 7.2, 7.6],
"vols": [0.0560, 0.0560, 0.0560]
}
]
})
// Append all market data at once to trigger valuation
appendMktData(engine, [spot, cnyCurve, usdCurve, volSurf])
// Check the valuation result
select * from fxOptResult
| engineName | instrumentId | npv | updateTime |
|---|---|---|---|
| FxOptEngine | USDCNY_CALL_7.2 | 4,306.487653692539 | 2026.08.27 14:40:36.151 |
Example 8: The following example prices a fixed-rate bond (FixedRateBond). Besides calculating net present value (NPV), the example uses the model and method parameters to specify the pricing model and pricing method, and the setting parameter to calculate greeks.
Step 1: Define the contract to be priced
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"instrumentId": "240025.IB",
"start": 2024.12.25,
"maturity": 2031.12.25,
"issuePrice": 100.0,
"coupon": 0.0149,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
fixedRateBond = parseInstrument(bond)
Step 2: Define the market data required for pricing
pricingDate = 2025.08.18
curve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"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
}
discountCurve = parseMktData(curve)
Step 3: Specify the pricing settings, pricing model, and pricing method
// Pricing settings
setting = dict(STRING, ANY)
setting["Cash.Bond.FixedRateBond"] = {
"calcDiscountCurveDelta": true,
"calcDiscountCurveGamma": true,
"calcDiscountCurveKeyRateDuration": true,
"discountCurveShift": 0.0001,
"discountCurveKeyTerms": [1.0, 3.0, 5.0],
"discountCurveKeyShifts": [0.0002, 0.0003, 0.0001]
}
// Pricing model
model = {
"Cash.Bond.FixedRateBond": "DCF"
}
// Pricing method
method = {
"Cash.Bond.FixedRateBond": "Analytic"
}
Step 4: Define a callback function to write the contract name, NPV, greeks, and pricing date to the result table each time the engine completes a calculation.
share streamTable(1000:0, `engineName`instrumentId`npv`discountCurveDelta`discountCurveGamma`discountCurveKeyRateDuration`pricingDate, [STRING, STRING, DOUBLE, DOUBLE, DOUBLE, DOUBLE[], TIMESTAMP]) as result
def resultHandler(name, date, npv, discountCurveDelta, discountCurveGamma, discountCurveKeyRateDuration){
tableInsert(result, "fixedRateBondPricer", name, npv, discountCurveDelta, discountCurveGamma, [discountCurveKeyRateDuration], date)
}
Step 5: Create a pricing engine and insert market data.
engine = createPricingEngine("fixedRateBondPricer", fixedRateBond, resultHandler, , setting, model, method)
appendMktData(engine, discountCurve)
Step 6: View the pricing result.
select * from result
| engineName | instrumentId | npv | discountCurveDelta | discountCurveGamma | discountCurveKeyRateDuration | pricingDate |
|---|---|---|---|---|---|---|
| fixedRateBondPricer | 240025.IB | 99.60084681135089 | -592.2599412782859 | 4,223.064257757869 | [0.012669167121743475, 0.06998233298563586, 1.9557862057092341] | 2025.08.18 00:00:00.000 |
Related functions: appendMktData
