Stress testing

Use stress testing when you want to apply scenario-specific shocks at the sector, sub-sector, underlying, or expiry level.

This is different from stress_sensitivities on POST /portfolios. stress_sensitivities defines a uniform shock grid for sensitivity analysis. It does not support per-sector or per-underlying targeting.

Overview

Scenario-based stress testing uses two parts of the API together:

  • GET /stress-test/scenarios to list available scenarios
  • POST /stress-test/scenarios to upload client-defined scenarios
  • DELETE /stress-test/scenarios to remove client-defined scenarios
  • POST /portfolios with stress_test_enabled: true to run those scenarios on a portfolio

This workflow lets you define reusable scenarios and then apply them to submitted portfolios.

How It Works

The typical flow is:

  1. List existing scenarios.
  2. Optionally delete client-defined scenarios to start from a clean slate.
  3. Upload one or more new scenario definitions.
  4. Submit a portfolio with stress_test_enabled: true.
  5. Optionally set stress_test_details_enabled: true to receive per-position stress details.

The public Python walkthrough demonstrates this full flow end to end:

Scenario precedence

Each scenario_definition can declare shocks at four levels of granularity. For each position, the most specific matching rule wins:

expiry > underlying > sub_sector > sector

That means:

  • sector applies broadly, for example Energy
  • sub_sector is narrower, for example Crude Oil
  • underlying targets a single underlying name
  • expiry targets a single underlying and a single expiry month

Scenario definition

Each matching block carries:

  • underlying for the price shock
  • volatility for the implied volatility shock

At the underlying and expiry levels, you can also use:

  • type: "Relative" for fractional moves such as -0.02 for -2%
  • type: "Absolute" for native-unit moves
  • override: true to force that rule to take precedence over broader matches

For example, to shock Energy by -1% but Crude Oil by -2%:

{
  "scenario_name": "Energy stress, Crude deeper",
  "scenario_definition": {
    "sector": {
      "Energy": { "underlying": -0.01, "volatility": 0.10 }
    },
    "sub_sector": {
      "Crude Oil": {
        "override": true,
        "underlying": -0.02,
        "volatility": 0.15
      }
    }
  }
}

Example flow

The Python reference script shows four example scenario types:

  • sector-level shocks
  • sub-sector shocks with override: true
  • underlying-level shocks
  • expiry-level shocks

An example upload payload looks like:

[
  {
    "scenario_name": "Broad risk-off (sector)",
    "scenario_definition": {
      "sector": {
        "Equity": { "underlying": -0.10, "volatility": 0.20 },
        "Energy": { "underlying": -0.05, "volatility": 0.10 }
      }
    }
  },
  {
    "scenario_name": "Equity index crash (sub_sector)",
    "scenario_definition": {
      "sector": {
        "Equity": { "underlying": -0.05, "volatility": 0.10 }
      },
      "sub_sector": {
        "Index": {
          "override": true,
          "underlying": -0.20,
          "volatility": 0.40
        }
      }
    }
  }
]

Running the portfolio

Once your scenarios are available, submit your portfolio through POST /portfolios and enable stress testing:

{
  "calculation_type": "all",
  "portfolio": [
    {
      "account_code": "Account 1",
      "exchange_code": "NYMEX",
      "contract_code": "ES",
      "contract_type": "CALL",
      "contract_expiry": "203012",
      "contract_strike": "7000",
      "net_position": 1000
    }
  ],
  "stress_test_enabled": true,
  "stress_test_details_enabled": true,
  "use_closest_active": true,
  "free_risk_rate": 0.05
}

Use:

  • stress_test_enabled: true to run available scenarios against the portfolio
  • stress_test_details_enabled: true to include per-position stress detail rows in the response

Understanding the response

The example script flattens the stress test response into a tidy DataFrame with one row per:

account x position x scenario

The response is especially useful in these two areas:

  • stress_tests.scenarios provides the scenario_id to scenario_name mapping
  • stress_tests.details provides per-position outputs such as underlying_shock, volatility_shock, price_stressed, and stress_loss

This allows you to build:

  • a summary view aggregated by scenario and account
  • a detailed per-position drill-down for downstream analysis

Was this page helpful?