Portfolio Stress Testing for Energy Traders: Creating Shock Scenarios and Automated P&L Sensitivity Reports with Energy API

Portfolio Stress Testing for Energy Traders: Creating Shock Scenarios and Automated P&L Sensitivity Reports with Energy API

Energy portfolios are complex systems with tight couplings across gas, oil, electricity, coal, and carbon markets. A single adverse print in TTF gas can ripple through power prices and carbon allowances within hours; a refinery outage can skew crack spreads and tilt merchant generator margins; a carbon rally can erase the economics of coal-heavy stacks overnight. If you’re a trader, risk analyst, or platform engineer building for these dynamics, you need a repeatable way to define shock scenarios, revalue exposures, and publish P&L sensitivity reports in minutes—not days of manual data wrangling.

This post shows how to build automated portfolio stress testing for energy markets using a single normalized data surface. We’ll construct cross-commodity shocks (e.g., +15% EUA_CO2, -10 EUR/MWh TTF_GAS, +5 USD/barrel BRENT_CRUDE), revalue positions using the latest or historical prices, and generate sensitivity slices for your desks. We’ll use the unified REST interface from Energy API to pull wholesale market data across electricity (including intraday curves), gas, oil, coal, carbon allowances, and grid carbon intensity—without scraping multiple portals or stitching incompatible formats.

By the end, you’ll have a blueprint to 1) discover symbols across commodities; 2) fetch the most recent marks, time series, and volatility context; 3) assemble deterministic day-ahead electricity forecasts where auctions publish them; 4) generate scenario P&L and shock ladders; and 5) operationalize the whole pipeline with health checks and sensible error handling. The goal is simple: faster stress tests, cleaner data, and fewer moving parts between you and production-grade risk tools.

Why Energy API

If you’ve ever integrated OMIE day-ahead with ENTSO-E intraday while also bringing in EUA allowances and TTF day-ahead, you know the drill: different schedules, time zones, currencies, and symbol naming conventions. The typical alternative is a fragile cube of scrapers, cron jobs, and one-off transformations that takes weeks to stabilize and breaks on holidays. With Energy API, you use one normalized REST surface to query cross-commodity data, all returned in the same JSON schema. That means:

  • Ship faster with one schema: Electricity, gas, oil, coal, carbon allowances, and carbon intensity share a consistent response shape, so you can write one ingestion path and reuse it everywhere. Your stress engine doesn’t care whether it’s BRENT_CRUDE or OMIE_ES_DA—fields and layouts align.
  • One call for many markets: Query multiple commodities at once for the latest marks (e.g., BRENT_CRUDE, TTF_GAS, EUA_CO2) or fetch synchronized historical windows for backtests. This is a killer feature for cross-commodity P&L sensitivity reports.
  • Intraday electricity curves where sources publish them: When a scenario hinges on hourly or 15-minute shapes, leverage an endpoint dedicated to intraday curves for power symbols. Align shocks to load shapes rather than flat averages.
  • Deterministic day-ahead forecasts for auction-published symbols: Pull the next published day-ahead result without predictive modeling. That’s especially helpful for setting scenario anchors around known day-ahead outcomes.

The bottom line for developers: you reduce ETL complexity, harden your risk stack, and iterate on features instead of fighting data drift. Your energy desk gets consistent P&L revaluations across commodities with fewer integration points.

Quick Start

Base URL: https://energy-api.com/api/v1

Let’s pull the latest marks for three commonly stressed instruments—TTF gas, Brent crude, and EU ETS allowances—in a single request. We’ll use the unified “/latest” endpoint and ask for multiple symbols at once. This becomes our baseline for immediate P&L revaluation or as the anchor marks for scenario shocks.

curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=BRENT_CRUDE,TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"date": "2026-06-11",
"base": "MIXED",
"rates": {
"BRENT_CRUDE": 74.82,
"TTF_GAS": 38.15,
"EUA_CO2": 67.40
},
"dates": {
"BRENT_CRUDE": "2026-06-11",
"TTF_GAS": "2026-06-11",
"EUA_CO2": "2026-06-11"
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR",
"EUA_CO2": "EUR"
}
}

Key fields:

  • rates: The latest price per symbol. Use these as your current marks before applying shocks.
  • date and dates: The as-of date for the returned marks. dates is per-symbol; use it to ensure consistent valuation windows when symbols publish at different times.
  • currencies: Map symbols to their native currency. You can convert downstream or filter with the base param when supported.

Core Endpoints for Stress Testing and P&L Sensitivities

1) Discover tradable symbols: GET /symbols

Start every stress pipeline by discovering which instruments are available per category and country. This is essential for assembling cross-commodity baskets and guarding against symbol drift (renames, retirements).

Key params:

  • category: Filter by market type (e.g., gas, electricity, oil, coal, carbon, carbon_intensity).
  • base: Optional currency filter where applicable.
  • provider: Optional filter by source.
curl -G https://energy-api.com/api/v1/symbols \
--data-urlencode "category=gas" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"count": 3,
"symbols": [
{
"symbol": "TTF_GAS",
"name": "TTF Natural Gas Day-Ahead",
"category": "gas",
"country_code": "EU",
"currency_code": "EUR",
"frequency": "daily",
"description": "TTF day-ahead price published by EEX."
},
{
"symbol": "HENRY_HUB",
"name": "Henry Hub Natural Gas",
"category": "gas",
"country_code": "US",
"currency_code": "USD",
"frequency": "daily",
"description": "US Henry Hub natural gas price."
}
]
}

Field notes:

  • symbol: Your canonical identifier for all subsequent endpoints.
  • frequency: Helps align your resampling logic for mixed-frequency stress runs.
  • country_code and currency_code: Useful for region-specific risk reports and FX normalization workflows.

2) Pull latest marks for revaluation: GET /latest

Use this to grab your valuation vector in a single call across commodities. You can pass a comma-separated list of symbols to produce a synchronized mark sheet for immediate P&L revaluation and for applying shocks (e.g., +3 USD/bbl to Brent, -12% to EUA).

Key params:

  • symbols: Comma-separated list (required).
  • base, category: Optional filters depending on your downstream use.
curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=OMIE_ES_DA,EUA_CO2,TTF_GAS,BRENT_CRUDE" \
--data-urlencode "api_key=YOUR_API_KEY"

Interpretation tips:

  • Use dates per symbol to guard against partial trading-day skew. If your risk policy requires a single cut, you can min() or max() align after checking dates alignment.
  • prices are native-currency; stash currencies for FX normalization downstream if needed.

3) Build historical context and backtests: GET /timeseries

Stress testing isn’t just about today’s shock; it needs a historical envelope for basis risk and fat-tail exploration. The timeseries endpoint pulls daily series per symbol between dates, perfect for computing rolling vol, correlations, and historical scenario templates (e.g., 2021 Q4 gas spike).

Key params:

  • start, end: YYYY-MM-DD, inclusive bounds.
  • symbols: Comma-separated list, ideal for multi-asset backtests.
curl -G https://energy-api.com/api/v1/timeseries \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2025-03-31" \
--data-urlencode "symbols=BRENT_CRUDE,TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"base": "MIXED",
"start_date": "2025-01-01",
"end_date": "2025-03-31",
"rates": {
"BRENT_CRUDE": {
"2025-01-02": 76.30,
"2025-01-03": 75.90
},
"TTF_GAS": {
"2025-01-02": 46.80,
"2025-01-03": 47.10
},
"EUA_CO2": {
"2025-01-02": 68.50,
"2025-01-03": 69.10
}
},
"frequencies": {
"BRENT_CRUDE": "daily",
"TTF_GAS": "daily",
"EUA_CO2": "daily"
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR",
"EUA_CO2": "EUR"
}
}

Field notes:

  • rates: Per-symbol map keyed by ISO date. Use it directly for vectorized analytics and charting.
  • frequencies: Useful when mixing electricity intraday with daily commodities—you’ll know which require resampling before covariance calculations.
  • currencies: Track FX for multi-currency risk. Keep base=MIXED explicit in your report headers.

4) Quantify period moves at a glance: GET /fluctuation

Stress scenario definitions often start from recent realized moves. The fluctuation endpoint returns start/end values and absolute/percent changes in one structure—handy for generating shock ladders (e.g., take 1x, 2x, 3x of the weekly move).

Key params:

  • start, end: YYYY-MM-DD window.
  • symbols: Comma-separated list.
curl -G https://energy-api.com/api/v1/fluctuation \
--data-urlencode "start=2026-05-15" \
--data-urlencode "end=2026-06-11" \
--data-urlencode "symbols=EUA_CO2,TTF_GAS,BRENT_CRUDE" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"base": "MIXED",
"results": {
"EUA_CO2": {
"start_value": 62.10,
"end_value": 67.40,
"change": 5.30,
"change_pct": 8.53
},
"TTF_GAS": {
"start_value": 34.90,
"end_value": 38.15,
"change": 3.25,
"change_pct": 9.31
},
"BRENT_CRUDE": {
"start_value": 72.40,
"end_value": 74.82,
"change": 2.42,
"change_pct": 3.34
}
}
}

Usage notes:

  • change_pct provides a quick template for +/-p% shocks (e.g., double the realized monthly move).
  • Use start_value/end_value to calibrate scenario pivots or to tag “shock vs prior month” in a sensitivity table.

5) Capture structural volatility context: GET /ohlc

When you’re stress testing options or spreads, candles matter. The OHLC endpoint returns pre-aggregated weekly/monthly/quarterly candles, making it straightforward to derive implied shock envelopes from highs and lows or to compute drawdowns by period.

Key params:

  • symbols: Comma-separated.
  • period: weekly, monthly, or quarterly (default monthly).
  • start, end: Optional bounds.
curl -G https://energy-api.com/api/v1/ohlc \
--data-urlencode "symbols=BRENT_CRUDE,EUA_CO2" \
--data-urlencode "period=monthly" \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2025-06-30" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"base": "MIXED",
"candles": {
"BRENT_CRUDE": [
{
"period": "2025-01",
"open": 76.10,
"high": 79.80,
"low": 73.50,
"close": 75.40,
"data_points": 22
},
{
"period": "2025-02",
"open": 75.40,
"high": 77.90,
"low": 71.30,
"close": 72.20,
"data_points": 20
}
],
"EUA_CO2": [
{
"period": "2025-01",
"open": 67.20,
"high": 70.10,
"low": 64.30,
"close": 68.00,
"data_points": 22
}
]
}
}

Strategy tips:

  • Derive scenario envelopes from high/low bands (e.g., shock-to-month-high or test “break-below last quarter low”).
  • Use data_points to sanity-check liquidity or skip periods with sparse prints in your backtests.

6) Get intraday power curves for shape-aware shocks: GET /electricity/hourly

Flat shocks miss shape risk. When markets publish intraday or quarter-hourly power curves, you can stress test per-slot exposures. This endpoint returns the full curve for a symbol on a date—ideal for shape-based P&L and hedging effectiveness checks.

Key params:

  • symbol: Electricity symbol with intraday support (e.g., OMIE_ES_DA).
  • date: The target date for the curve.
curl -G https://energy-api.com/api/v1/electricity/hourly \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "date=2026-06-12" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2026-06-12",
"frequency": "hourly",
"currency": "EUR",
"curve": [
{"ts": "2026-06-12T00:00:00+01:00", "price": 63.10},
{"ts": "2026-06-12T01:00:00+01:00", "price": 60.40},
{"ts": "2026-06-12T02:00:00+01:00", "price": 58.90}
// ... remaining hours
]
}

Implementation details:

  • Use ts for time-aware valuation of hourly positions. Align your portfolio positions by local time or convert to UTC consistently.
  • Apply per-slot shock multipliers to reflect shape-sensitive risks (e.g., peak hours +15%, off-peak +5%).

7) Align to known next-day anchors: GET /forecast

For auction-sourced symbols, the forecast endpoint provides the next published day-ahead price without predictive modeling. It’s perfect when you want deterministic anchors for scenario baselines, especially around day-ahead scheduling and hedging checks.

Key params:

  • symbol: An auction-published electricity instrument (e.g., OMIE_ES_DA).
curl -G https://energy-api.com/api/v1/forecast \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"symbol": "OMIE_ES_DA",
"for_date": "2026-06-13",
"currency": "EUR",
"price": 64.20,
"source": "auction"
}

Practical use:

  • Use price as the “base case” curve scalar when a next-day result is known; then layer scenario shocks around it for peak/off-peak differentials.

8) Monitor ingestion health: GET /status

Stress engines are only as reliable as the data behind them. Before running daily revaluations, check provider health via /status and apply sensible fallbacks (e.g., persist prior close) if a provider is delayed.

curl -G https://energy-api.com/api/v1/status \
--data-urlencode "api_key=YOUR_API_KEY"

Example JSON response:

{
"success": true,
"providers": {
"omie": {"last_fetch": "2026-06-11T23:58:00Z", "status": "ok"},
"entso-e": {"last_fetch": "2026-06-11T23:55:00Z", "status": "ok"},
"eia": {"last_fetch": "2026-06-11T21:10:00Z", "status": "ok"},
"fred": {"last_fetch": "2026-06-11T21:10:00Z", "status": "ok"},
"esios": {"last_fetch": "2026-06-11T23:59:00Z", "status": "ok"}
}
}

How to use:

  • Gate your daily stress job on status=ok for required providers. If not ok, skip or apply prior-day marks with an audit tag.

From Data to Stress: Building Shock Scenarios and P&L Sensitivity Reports

With the key endpoints in place, let’s move to the core objective: define and apply shock scenarios across a cross-commodity portfolio, then publish P&L sensitivities. We’ll outline a framework you can adapt to your desk’s conventions.

Step 1: Define portfolio exposures

Represent your portfolio as a set of positions keyed by symbol with quantity, currency, and optional slotting (for hourly power). For example:

{
"positions": [
{"symbol": "TTF_GAS", "qty": 120000, "unit": "MWh", "side": "long", "currency": "EUR"},
{"symbol": "BRENT_CRUDE", "qty": -50000, "unit": "barrel", "side": "short", "currency": "USD"},
{"symbol": "EUA_CO2", "qty": 200000, "unit": "MT", "side": "long", "currency": "EUR"},
{"symbol": "OMIE_ES_DA", "qty_by_hour": {"2026-06-12T18:00:00+01:00": 50, "2026-06-12T19:00:00+01:00": 50}, "unit": "MWh", "side": "long", "currency": "EUR"}
]
}

You can store these in a database or config-managed JSON. If your book includes spreads, capture them as separate legs and compute leg-wise P&L.

Step 2: Fetch baseline marks

Call /latest to pull current marks for all symbols in a single request. For hourly positions, fetch the relevant day curve via /electricity/hourly for precise per-slot valuation.

Step 3: Specify shock scenarios

Define scenarios as deltas or percentages per symbol (or group). For example:

{
"scenarios": [
{"name": "Carbon Spike", "shocks": {"EUA_CO2": {"pct": 0.15}}},
{"name": "Gas Slump", "shocks": {"TTF_GAS": {"abs": -10.0}}},
{"name": "Oil Up, Gas Down", "shocks": {"BRENT_CRUDE": {"pct": 0.05}, "TTF_GAS": {"pct": -0.08}}},
{"name": "Power Peak-Only", "shocks": {"OMIE_ES_DA": {"shape": {"peak_pct": 0.12, "offpeak_pct": 0.03}}}}
]
}

For electricity curves, “shape” shocks can be time-window based (e.g., peak hours H08–H20). You can also connect shocks to realized moves from /fluctuation (e.g., scenario magnitude = 2 × weekly change_pct).

Step 4: Revalue and compute P&L sensitivities

For each scenario, compute shocked_price = base_price × (1 + pct) + abs (apply abs in native units). For hourly curves, apply per-slot multipliers. Then P&L per leg is:

  • delta = (shocked_price - base_price) × signed_qty
  • sum across legs and currencies (normalize to a reporting currency if needed)

Generate a sensitivity ladder by sweeping shock magnitudes (e.g., -20%, -10%, -5%, 0%, +5%, +10%, +20%) per symbol. Combine ladders for cross-commodity scenarios to produce a grid of outcomes.

Python reference implementation

import requests
from datetime import date

BASE = "https://energy-api.com/api/v1"
API_KEY = "YOUR_API_KEY"

symbols = ["TTF_GAS","BRENT_CRUDE","EUA_CO2"]

def get_latest(symbols):
resp = requests.get(f"{BASE}/latest", params={
"symbols": ",".join(symbols),
"api_key": API_KEY
}, timeout=20)
data = resp.json()
if not data.get("success"):
raise RuntimeError(data.get("error","Unknown error"))
return data

def get_hourly_curve(symbol, d):
resp = requests.get(f"{BASE}/electricity/hourly", params={
"symbol": symbol,
"date": d,
"api_key": API_KEY
}, timeout=20)
data = resp.json()
if not data.get("success"):
raise RuntimeError(data.get("error","No curve"))
return data

# Example portfolio
portfolio = [
{"symbol": "TTF_GAS", "qty": 120000, "side": "long", "ccy": "EUR"},
{"symbol": "BRENT_CRUDE", "qty": -50000, "side": "short", "ccy": "USD"},
{"symbol": "EUA_CO2", "qty": 200000, "side": "long", "ccy": "EUR"}
]

# Baseline marks
latest = get_latest(symbols)
marks = latest["rates"]

# Scenario definition
scenarios = [
{"name": "Base + Carbon Spike", "shocks": {"EUA_CO2": {"pct": 0.15}}},
{"name": "Gas -10 EUR/MWh", "shocks": {"TTF_GAS": {"abs": -10.0}}},
{"name": "Oil +5%, Gas -8%", "shocks": {"BRENT_CRUDE": {"pct": 0.05}, "TTF_GAS": {"pct": -0.08}}}
]

def shock_price(symbol, base, shock):
pct = shock.get("pct")
abs_move = shock.get("abs")
p = base
if pct is not None:
p = p * (1.0 + pct)
if abs_move is not None:
p = p + abs_move
return p

def pnl_leg(symbol, qty, base_price, new_price):
# side via sign in qty
return (new_price - base_price) * qty

for s in scenarios:
total = 0.0
for pos in portfolio:
sym = pos["symbol"]
base_p = marks[sym]
shock = s["shocks"].get(sym, {})
new_p = shock_price(sym, base_p, shock)
q = pos["qty"]
pnl = pnl_leg(sym, q, base_p, new_p)
total += pnl
print(s["name"], " => P&L:", round(total, 2))

Adapt this skeleton to incorporate FX normalization and hourly curve shocks. For electricity curves, call get_hourly_curve and apply slot-level pct or abs moves based on peak/off-peak windows, summing P&L per slot.

JavaScript scenario sweep (Node.js)

import fetch from "node-fetch";

const BASE = "https://energy-api.com/api/v1";
const API_KEY = "YOUR_API_KEY";

async function latest(symbols) {
const url = new URL(`${BASE}/latest`);
url.searchParams.set("symbols", symbols.join(","));
url.searchParams.set("api_key", API_KEY);
const r = await fetch(url.toString(), { timeout: 20000 });
const j = await r.json();
if (!j.success) throw new Error(j.error || "Unknown error");
return j;
}

const symbols = ["TTF_GAS", "BRENT_CRUDE", "EUA_CO2"];

const shockLadder = [-0.2, -0.1, -0.05, 0, 0.05, 0.1, 0.2];

const positions = {
"TTF_GAS": 100000,
"BRENT_CRUDE": -30000,
"EUA_CO2": 150000
};

(async () => {
const data = await latest(symbols);
const marks = data.rates;

for (const sym of symbols) {
console.log(`Sensitivity ladder for ${sym}`);
const base = marks[sym];
for (const s of shockLadder) {
const shocked = base * (1 + s);
const pnl = (shocked - base) * positions[sym];
console.log(`${Math.round(s*100)}%: ${pnl.toFixed(2)}`);
}
console.log("");
}
})();

Advanced Patterns for Scenario Design

Beyond simple pct/abs moves, robust stress frameworks leverage the rest of the dataset to design realistic shocks:

  • Realized-move templating: Use /fluctuation to compute recent weekly/monthly change_pct and scale scenarios to 1×, 2×, or 3× those magnitudes. This keeps scenarios anchored to current volatility regimes.
  • High/low bands: From /ohlc candles, shock to the monthly high or below last quarter’s low, then observe break-even spreads or convexity impacts.
  • Historical replay: With /timeseries, extract windows (e.g., 2021-09 to 2021-12 for EU gas/power), compute relative moves vs base marks, and replay those deltas on today’s portfolio.
  • Shape-aware electricity: Use /electricity/hourly curves to shock peak vs off-peak differently (e.g., +15% peak, +5% off-peak) or to apply renewable-driven shapes. If retail indices are relevant, combine with /electricity/pvpc for Spanish PVPC reference context.
  • Anchor to published next-day: For auction-based symbols, /forecast gives the next day’s deterministic anchor; layer stress around that to test day-ahead hedges.

Error Handling, Data Hygiene, and Operational Reliability

Stress reports are high-visibility artifacts; you want them resilient to market holidays, partial updates, and provider delays. Build the following guardrails:

  • Use /status to confirm provider freshness before running the job. If a provider isn’t ok, skip revaluation for that symbol or roll prior close with a clear “stale” tag.
  • Handle 404s gracefully. If /historical or /electricity/hourly can’t find a value on a holiday, fall back to the most recent available prior date for baseline marks. Communicate this in your report header.
  • Watch for 422 (validation errors). Validate inputs before the request—check date formats, symbol strings, and required params locally to avoid noisy failures.
  • Respect 429 backoffs with exponential retry logic. While building shock ladders you might parallelize requests; keep concurrency at sane levels and add jitter.
  • Preserve currencies and dates per symbol from responses. Don’t assume synchronized timing across commodities; align as-of timestamps to your risk policy before aggregating P&L.

Error shape example:

{
"success": false,
"error": "No data for the given symbols or date."
}

In your code, check success first. If false, route the error message to your runbook or alerting system and apply policy-based fallbacks.

Real-World Use Cases

1) Trader P&L shock ladder dashboard

Build a single-page tool that shows each trader’s book sensitivity at -20%, -10%, -5%, +5%, +10%, +20% per symbol, plus cross-commodity composite scenarios (e.g., “Oil up, Gas down”). Use /latest for baseline marks and /fluctuation to anchor ladder magnitudes to recent realized moves. For power desks, augment with /electricity/hourly to show peak/off-peak sensitivities. Export snapshots to a shareable report for morning meetings.

2) Risk team historical replay engine

Construct scenario sets from prior stress windows (e.g., gas spikes, carbon rallies, oil crashes) using /timeseries. Compute relative deltas over those intervals and apply them to today’s marks from /latest. Use /ohlc to highlight whether current prices have breached key period highs/lows during replays. This gives management a clear view of what would happen “if today behaved like Q4 2021.”

3) Utility hedging and schedule validation

For utilities scheduling next-day power, pull /forecast for auction-based symbols to set the base case. Then use /electricity/hourly to stress peak/off-peak differently based on expected renewable output and demand. Publish a sensitivity report for hedge coverage—spotting under-hedged peak slots before gate closure.

End-to-End Example: Carbon-Gas-Oil Composite Shock with Hourly Power Overlay

Let’s combine everything: baseline marks for EUA_CO2, TTF_GAS, BRENT_CRUDE, and an OMIE_ES_DA hourly curve; then apply a composite shock and compute P&L. We’ll demonstrate the data gathering, then outline the math.

1) Fetch baseline marks (multi-commodity)

curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=EUA_CO2,TTF_GAS,BRENT_CRUDE" \
--data-urlencode "api_key=YOUR_API_KEY"

Sample response shorthand:

{
"success": true,
"rates": {"EUA_CO2": 67.40, "TTF_GAS": 38.15, "BRENT_CRUDE": 74.82},
"dates": {"EUA_CO2": "2026-06-11", "TTF_GAS": "2026-06-11", "BRENT_CRUDE": "2026-06-11"},
"currencies": {"EUA_CO2":"EUR", "TTF_GAS":"EUR", "BRENT_CRUDE":"USD"}
}

2) Fetch hourly curve (electricity)

curl -G https://energy-api.com/api/v1/electricity/hourly \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "date=2026-06-12" \
--data-urlencode "api_key=YOUR_API_KEY"

Assume some hours at 60–70 EUR/MWh; we’ll apply time-window shocks (peak +12%, off-peak +4%).

3) Define composite shock

  • EUA_CO2: +15% (carbon spike)
  • TTF_GAS: -8% (gas down)
  • BRENT_CRUDE: +5% (oil up)
  • OMIE_ES_DA (hourly): +12% peak (08:00–20:00), +4% off-peak

Now compute P&L per leg:

  • Commodity legs: delta = (shocked - base) × qty
  • Hourly power: sum over hours: (shocked_hour - base_hour) × hourly_qty

Finally, aggregate by reporting currency. Preserve the native currency values and handle FX normalization in your reporting layer as needed.

Data Modeling and Best Practices

A robust stress platform benefits from a few modeling conventions:

  • Symbol registry: Keep a mapping table for symbols with category, unit, currency, and time zone. Populate it via /symbols and refresh periodically.
  • As-of discipline: Always store the as-of dates from responses. When mixing instruments, re-align to a consistent cut before aggregating.
  • Curve semantics: For electricity, store entire curves with ts and price so you can reconstruct slot-level P&L. Avoid pre-summing into flat averages if shape risk matters.
  • Scenario provenance: Capture how a shock was derived (e.g., “2× weekly /fluctuation(2026-05-15..2026-06-11)”) for auditability.
  • Observability: Log the actual API responses driving each stress run and tag your reports with provider statuses from /status.

FAQ

How often does the TTF gas price update?

TTF_GAS is available via the same unified endpoints used by other commodities. Use /latest for the most recent mark and /timeseries for historical windows. The dates field in the response tells you exactly which as-of date your mark reflects.

Can I get historical energy prices going back multiple years?

Yes. Use /timeseries with start and end to fetch daily historical data for supported symbols like BRENT_CRUDE, TTF_GAS, EUA_CO2, and day-ahead electricity indices. You can combine multiple symbols in a single request for synchronized backtests.

Does the API support multiple commodities in one call?

Absolutely. A major advantage is querying gas, oil, carbon, coal, and electricity symbols together through the same endpoint. For example, /latest and /timeseries let you pass comma-separated symbols to build cross-commodity mark sheets instantly.

Can I get intraday electricity curves for shape-aware stress tests?

Yes, where sources publish them. Use /electricity/hourly for symbols like OMIE_ES_DA to retrieve hourly or 15-minute curves by date. This is ideal for peak/off-peak sensitivities and hedging checks.

How should I handle non-publishing days and provider delays?

Check /status before running your job and respect the success flag in responses. If a symbol has no value for a given date, fall back to the most recent available date and label the stress run accordingly. This keeps your pipeline robust on holidays and partial updates.

Conclusion + CTA

Energy stress testing should be about trading insight, not data plumbing. By unifying electricity, gas, oil, coal, carbon allowances, and grid carbon intensity behind one consistent REST surface, you can go from scenario idea to production-grade P&L sensitivities in hours. Intraday curves let you respect shape risk, deterministic day-ahead anchors align everyone on the same baseline, and multi-commodity calls simplify cross-asset reports.

If your current stack is a patchwork of scrapers and one-off transformations, simplify it. Use a single JSON schema, a handful of versatile endpoints, and practical guardrails—status checks, historical windows, candles, and fluctuation deltas—to deliver fast, reliable stress results day after day.

Build your next stress engine, risk dashboard, or hedging validation tool with the data foundation it deserves. Explore Energy API and start assembling automated P&L sensitivity reports and shock scenarios with clean, consistent market data. Try Energy API for free and put a unified, developer-friendly energy dataset at the core of your platform.

Ready to get started?

Get your API key and start querying energy commodity prices in minutes.

Get API Key

Related posts