ewmaRiskEngine

First introduced in version: 3.00.6.4

Syntax

ewmaRiskEngine(factorReturns, portfolio, settings)

Details

Calculates portfolio profit and loss (P&L) under simulated risk factor shock scenarios based on EWMA (Exponentially Weighted Moving Average) covariance estimation and conditional multivariate normal simulation, and generates a risk primitive.

The function uses the historical risk factor return object generated by mktRiskFactorReturns, estimates the risk factor covariance matrix based on exponentially decaying weights, and generates a specified number of joint return scenarios from a multivariate normal distribution. It then restores risk factor levels, reconstructs market data, and revalues each asset in the portfolio under each scenario. Finally, it returns the P&L results of each asset under all simulated scenarios.

Parameters

factorReturns is a STRING-ANY dictionary returned by mktRiskFactorReturns. It contains information such as the base date, risk factor definitions, historical return matrix, base factor levels, and base market data.

portfolio is a STRING-ANY dictionary that describes the assets to be revalued and their position sizes. It usually contains the following keys:

  • names: a STRING vector indicating asset names or asset identifiers.

  • instruments: an ANY vector of objects containing the INSTRUMENT instances corresponding to the assets.

  • amounts: a DOUBLE vector vector indicating the position size or notional amount of each asset. Its length must be consistent with names and instruments.

settings is a STRING-ANY dictionary that specifies risk engine settings for controlling the valuation date, currency, output dimensions, and pricing behavior. The following settings are supported:

  • baseCurrency: a required STRING scalar indicating the base currency of the portfolio. This is a reserved parameter for future support of cross-currency conversion; in the current version, it is not involved in calculations and does not affect the calculation results.

  • analysisHorizon: an optional INT scalar indicating the analysis horizon or holding period in trading days. The default value is 1. It must be greater than 0.

  • samplingHorizon: an optional INT scalar indicating the historical return sampling horizon in trading days. The default value is 1. It must be greater than 0.

  • decay: an optional DOUBLE scalar indicating the EWMA decay factor. The default value is 0.94. The value must be in the range (0, 1].

  • nSimulations: an optional INT scalar indicating the number of simulation scenarios. The default value is 1000. It must be greater than 0.

  • randomSeed: an optional INT scalar indicating the seed of the random number generator. The default value is NULL. It must be a non-negative integer if specified.

  • assetDimensions: an optional STRING vector indicating the asset output dimensions. The default value is NULL. The current version supports only NULL or "assetType".

  • riskDimensions: an optional STRING vector indicating risk dimensions. The default value is NULL. It must be NULL in the current version.

Returns

Returns a STRING-ANY dictionary with the following keys:

  • riskPrimitive: A table indicating asset-level P&L under each scenario, where each row corresponds to one asset in the portfolio. It contains the following columns:

    • assetName: a STRING vector indicating asset names or identifiers.

    • assetType: a STRING vector indicating asset types (such as Stock, Bond, etc.).

    • assetPnLs: an array vector of DOUBLE[] recording the full P&L distribution of each asset across all EWMA simulation scenarios. Each row is a DOUBLE vector whose length equals the total number of simulation scenarios (nSimulations).

  • modelResult: a STRING-ANY dictionary containing model results and intermediate artifacts. It contains the following keys:

    • nSimulations: INT scalar. The actual number of EWMA simulation scenarios generated.

    • returns: DOUBLE matrix. The simulated factor return matrix. Each row represents the joint returns of all factors under one simulated scenario.

    • artifacts: a dictionary containing internal artifacts of EWMA model estimation and simulation:

      • factorMatrix: A DOUBLE matrix containing the input historical factor returns.

      • weightedMatrix: AA DOUBLE matrix containing the EWMA-weighted historical returns R.

      • covariance: A A DOUBLE matrix containing the factor covariance matrix estimated using EWMA.

      • variance: A A DOUBLE vector containing the diagonal elements of the covariance matrix, representing the variance of each factor.

      • randomSeed: INT scalar. The actual random seed in effect.

Examples

The following example uses a fixed-rate bond portfolio and multi-period CNY treasury yield curves to demonstrate a complete workflow for full market risk revaluation based on the EWMA simulation method. The example first constructs historical curves in batches based on the trading days in a specified period and extracts historical factor returns through mktRiskFactorReturns. Then it configures the base currency, a 10-day analysis horizon, and EWMA parameters in settings: the decay factor is set to 0.94, 5000 multivariate normal joint shock scenarios are generated, and randomSeed is set to 42 to make the result reproducible. Finally, it calls ewmaRiskEngine to complete full asset revaluation and shows how to extract the estimated factor covariance matrix artifact and the table of asset-level P&L under each scenario (riskPrimitive).

// Define a function to construct a single-period interest rate curve
def makeExampleCurve(d, rates) {
    return parseMktData({
        "mktDataType": "Curve",
        "curveType": "IrYieldCurve",
        "curveName": "CNY_TREASURY_BOND",
        "referenceDate": d,
        "currency": "CNY",
        "dayCountConvention": "Actual365",
        "compounding": "Continuous",
        "frequency": "Annual",
        "interpMethod": "Linear",
        "extrapMethod": "Flat",
        "dates": d + 365 * (1..size(rates)),
        "values": rates
    })
}

// Obtain the trading days in the specified period and construct historical curves in batches
// This example uses multi-period historical data to demonstrate a typical EWMA risk engine workflow
dates = getMarketCalendar("SSE", 2025.10.01, 2025.12.31)
curveHistory = array(ANY, 0)
for (i in 0..(size(dates)-1)) {
   // Simulate a yield curve with small fluctuations
   rates = [0.020, 0.022, 0.025] + rand(0.002, 3) - 0.001
   curveHistory.append!(makeExampleCurve(dates[i], rates))
}
mktDataTable = table(dates as dates, curveHistory as CNY_TREASURY_BOND)

asOf = mktDataTable.dates.last()
mfr = mktRiskFactorReturns(mktDataTable=mktDataTable, asOf=asOf)

// Construct a portfolio containing two fixed-rate bonds
instrumentA = parseInstrument({
    "productType": "Cash", "assetType": "Bond", "bondType": "FixedRateBond",
    "instrumentId": "EXAMPLE_BOND_A", "start": 2025.01.07, "maturity": 2028.01.07,
    "issuePrice": 100.0, "coupon": 0.03, "frequency": "Annual",
    "dayCountConvention": "Actual365", "currency": "CNY",
    "discountCurve": "CNY_TREASURY_BOND"
})
instrumentB = parseInstrument({
    "productType": "Cash", "assetType": "Bond", "bondType": "FixedRateBond",
    "instrumentId": "EXAMPLE_BOND_B", "start": 2025.01.07, "maturity": 2029.01.07,
    "issuePrice": 100.0, "coupon": 0.04, "frequency": "Annual",
    "dayCountConvention": "Actual365", "currency": "CNY",
    "discountCurve": "CNY_TREASURY_BOND"
})
instruments = array(ANY, 0)
instruments.append!(instrumentA)
instruments.append!(instrumentB)

portfolio = dict(STRING, ANY)
portfolio["names"] = ["positionA", "positionB"]
portfolio["instruments"] = instruments
portfolio["amounts"] = [1000.0, -500.0]

// Configure EWMA-specific parameters
riskSettings = dict(STRING, ANY)
riskSettings["baseCurrency"] = "CNY"
riskSettings["analysisHorizon"] = 10
riskSettings["decay"] = 0.94
riskSettings["nSimulations"] = 5000
riskSettings["randomSeed"] = 42
riskSettings["assetDimensions"] = ["assetType"]

// Call the EWMA risk engine
ewmaResult = ewmaRiskEngine(factorReturns=mfr, portfolio=portfolio, settings=riskSettings)

// Extract the asset-level scenario PnL table and the covariance matrix artifact
riskPrimitive = ewmaResult.riskPrimitive
covMatrix = ewmaResult.modelResult.artifacts.covariance

Related Functions: mktRiskFactorReturns, historicalRiskEngine, parseMktData, parseInstrument, instrumentPricer