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.
If you want to express rules such as "shock all Energy positions by -1%, but
shock Crude Oil by -2%" you should use stress test scenarios, not
stress_sensitivities.
Overview
Scenario-based stress testing uses two parts of the API together:
GET /stress-test/scenariosto list available scenariosPOST /stress-test/scenariosto upload client-defined scenariosDELETE /stress-test/scenariosto remove client-defined scenariosPOST /portfolioswithstress_test_enabled: trueto 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:
- List existing scenarios.
- Optionally delete client-defined scenarios to start from a clean slate.
- Upload one or more new scenario definitions.
- Submit a portfolio with
stress_test_enabled: true. - Optionally set
stress_test_details_enabled: trueto 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:
sectorapplies broadly, for exampleEnergysub_sectoris narrower, for exampleCrude Oilunderlyingtargets a single underlying nameexpirytargets a single underlying and a single expiry month
Scenario definition
Each matching block carries:
underlyingfor the price shockvolatilityfor the implied volatility shock
At the underlying and expiry levels, you can also use:
type: "Relative"for fractional moves such as-0.02for-2%type: "Absolute"for native-unit movesoverride: trueto 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: trueto run available scenarios against the portfoliostress_test_details_enabled: trueto 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.scenariosprovides thescenario_idtoscenario_namemappingstress_tests.detailsprovides per-position outputs such asunderlying_shock,volatility_shock,price_stressed, andstress_loss
This allows you to build:
- a summary view aggregated by scenario and account
- a detailed per-position drill-down for downstream analysis