Cascade · Weather → Grid → Price

When a cold snap becomes a price shock, three countries away.

A learned propagation operator over a 357-node graph of the European energy system. The ML operator encodes two weeks of history at every node and forecasts where stress surfaces next, from six hours to fourteen days ahead.

Live above: a subset of the actual graph. Hover any node.

01 · THE SYSTEMOne graph for the coupled energy system.

A cold, near-windless week over Germany is not one localised independent event. Gas burn increases to cover the wind deficit, interconnector flows tighten across the continent, and days later the strain surfaces as a price spike in Italy and a curtailment notice at an aluminium smelter. The shock propagates through physical infrastructure, market coupling and fuel logistics, with delays of hours to weeks.

Cascade models such event propagation explicitly. Weather regions, generation fleets, interconnectors, gas hubs, river gauges, ports, prices, industries and companies become nodes, and the couplings between them are the edges. The novel part is what sits on the edges. The interactions representing each of the 675 edges receive more nuance via a natural language description of the physical mechanism/relationship (an LLM-enriched description of how the coupling works, embedded to 1024 dimensions). The ML operator then conditions its message passing on this embedded text. Click any node in the case study below to read the mechanisms it is wired into.

357
graph nodes
675
edges, each with a written mechanism
59
curated shock episodes 2015–2024
18.8M
hourly observations
Ingest
Open-Meteo reanalysis · GloFAS rivers · ENTSO-E market data
2015–2024, hourly
Features
z-scored anomalies against hour-of-year climatology
18.8M rows
Graph
357 typed nodes · 675 edges · LLM-written mechanism per edge
BGE-1024 embeddings
Operator
GRU over 336 h per node, then 5 rounds of edge-conditioned message passing
Forecast
P10 / P50 / P90 quantiles × 5 horizons (6 h → 14 d) × 143 targets

02 · CASE STUDYDecember 2022, replayed on the graph.

For eighteen days a cold anomaly sat over north-west Europe while wind output collapsed (a 13-day wind drought at the peak of the gas crisis). Britain warmed its coal reserve, day-ahead power cleared above £600/MWh, and the depleted Nordic hydro system set December price records. Cascade holds this episode out of training entirely.

The replay below is the test data itself rather than a simulation. It shows each node's daily peak stress measured in standard deviations (|z|) against its own climatology. Press play to watch the shock enter through the weather nodes and surface in prices, gas hubs and industry.

Dec 01
|z| 0 6σ+ · node colour = daily peak stress
weather & riversgeneration · grid · demandpricesgas & logisticsindustry & companies

03 · RESULTSThe ML operator ranks stress across the whole system.

Hand the operator any moment in a held-out year and ask which parts of the network will be under strain over the next one to fourteen days. It ranks "stressed" against "quiet" nodes at a median AUC of 0.74 across 21 test episodes spanning the 2022 energy crisis and the storm winter of 2024. Persistence, the strongest simple baseline, scores 0.65, and a per-node GRU with the graph removed scores 0.67. The graph structure therefore closes a quarter of the distance between persistence and a perfect ranking, and the operator beats persistence's median on 18 of the 21 episodes it never trained on.

Whole-system stress ranking · AUC · held-out test years 2022 + 2024

Dots: the operator's 21 individual test episodes (hover for names). Diamonds: per-model median. The axis begins at 0.45 so differences are readable, and 0.50 is random. Source: the operator and baseline evaluation harness, with identical episodes and no-peek slices for every model.
episode table

The graph structure is clearly beneficial. Removing it (per-node GRU) forfeits half the margin over persistence, and removing history as well (climatology) collapses the ranking to chance.

04 · THE FRONTIERWhich quiet node lights up next?

Ranking visible stress is the utility a grid operator needs. A reinsurer prices something harder: onset. Among the nodes that look healthy today, which will be disrupted by the end of the week? These are the newly-disrupted nodes, quiet for a week (|z| < 1.5) and then they cross the disruption threshold within the episode.

On this slice, persistence is structurally blind (AUC 0.34, below random), because a quiet node gives nothing to extrapolate. This leaves open headroom for a model that reads the graph. However, the measurements below show otherwise, and explain why.

Three independent methods, one shared failure mode: every history-conditioned score ranks tomorrow's spikers below the nodes that stay calm.

Newly-disrupted ranking · pooled AUC, 95% bootstrap CI · val + test

24,376 within-episode pairs, 206 positives, 26 episodes. Quantile-median ranking, upper-tail excess (P90 − |P50|) and a purpose-built exceedance classifier, trained with class-weighted loss against the rare positives, all perform at or below random. Persistence sits at 0.34 on the same slice.

The mechanism is a covariate shift, and it is structural rather than a tuning gap. The slice is defined as the quiet-before nodes, and a node's own quietness is the single strongest predictor that it stays quiet, so any score built on recent history sorts the eventual spikers to the bottom. Evidence for a quiet-then-spiking node has to arrive entirely through its graph neighbours, and on this graph that signal is too faint to overcome the node's own autocorrelation. This is the current boundary of predictability, measured three independent ways and explained by one mechanism.

05 · THE ABLATIONDoes language on the edges help?

Every edge is annotated with an LLM-written description of its relationship/coupling, embedded to 1024 dimensions. The natural hypothesis is that semantic edge conditioning should beat a bare 13-dimensional edge-type one-hot. The matched-capacity ablation (the two arms differ in a single input projection) says otherwise, as text and one-hot tie at every cell of the evaluation.

A perturbation probe rules out the trivial explanation. Shuffling embeddings within each edge type moves the operator's outputs by 0.47× their own scale, so the model demonstrably reads the per-edge text. A zero-shot test then shows that it depends on what it reads. Hold two edge types out of training and the text arm's error on the affected nodes degrades thirty times more than one-hot's (+0.042 versus +0.001 pinball), while control nodes stay flat for both. The specificity of the per-edge semantics is what makes the text arm brittle on an edge type it never saw.

Zero-shot edge-type holdout · Δ pinball loss when two edge types are withheld

Positive Δ = worse without the held-out types. Affected = 8 nodes downstream of a held-out edge. Control = 135 other targets. Text degrades +0.042 on affected nodes against +0.001 for one-hot, while controls move < 0.006 for both arms.
reads per-edge text · 0.47× output sensitivity ties one-hot in-distribution, every cell −30× more brittle zero-shot

In distribution, structure beats semantics on this graph. Because the operator provably uses the text, the null is a modelling result about language conditioning, not an artefact of a weak enrichment pipeline.

06 · MEASUREMENTHow the numbers were produced.

Every claim above rests on the evaluation harness, so the harness was built first and the models were judged against it unchanged.

2015
2016
2017
2018
2019
2020
2021
2022
2023
2024

train · validation · test, separated by a 336-hour guard band so no training window's forecast horizon reaches a held-out year.

The same scrutiny applies to the operator's own uncertainty. A pinball-trained forecaster ought to be calibrated, so the P10–P90 band should cover 80% of outcomes. On test years it covers 66%. The median is nearly calibrated, and both tails are too tight. Under-dispersion is the signature of a variance-shrinking objective, and it appears to be the same mechanism behind the onset blindness of §04, since the model thins exactly the tail where onset lives.

Quantile calibration · edge-text arm · 12,234 test positions

Hollow marks: nominal targets. Filled: empirical coverage. P10 lands at 0.14, P50 at 0.46, P90 at 0.80, and the central band covers 66% against a nominal 80%. A secondary result runs the other way, in that adding the exceedance objective as a multi-task term regularised the shared forecaster (validation ranking AUC 0.688 → 0.743).

This page shows one episode in motion. The full pipeline, the 59-episode catalogue and the complete quantitative results are in the repository at github.com/wienkers/cascade.