German–Luxembourg electricity market

Day-ahead electricity forecasts, with uncertainty.

Explore hourly price forecasts with prediction intervals, and see how research models improved, what failed and how it was checked.

Demo
v1 · released LightGBM
Research
v5 · DDNN-2 added
Met the adoption rule set before the experiment: both error scores improved on v4's (v5 − v4 at 97.5%: −0.0133 [−0.0166, −0.0091] on the point-error score, −0.0119 [−0.0147, −0.0084] on the interval score; 1 policy tested against the rule). Development · post-selection
  • Error scores: error relative to a simple naive forecast, averaged over the test periods; lower is better.
  • Adoption rule: set on 2026-10-05; its five conditions are in the v5 chapter. Read them
  • Paired difference: v5's score minus v4's, with the rule's 97.5% interval; below zero favours v5.
  • Policies: the models and variants tested.
  • Development · post-selection: development evidence, not a test on new data.
  • DDNN-2: a distributional neural network (DDNN).

The demo runs the released model, v1. Research generations are not released one by one; only the final model, after its one-shot test and live run, replaces the released one.

Runs in your browser: about 57 MB on a first visit. A forecast appeared after 18.3 s in Chrome 153 on a Mac, public demo, 2026-09-29; last verified 2026-09-29.

Historical forecast · v1 Forecast and observed price for a held-out day. This is a historical replay, not a live forecast.
v1 historical replay: the default delivery dayStatic rendering of v1's saved historical replay for one holdout delivery day at the unperturbed load scenario: the median forecast, the 80 percent interval as a shaded band, and the price that actually cleared as a dashed line. Not a live forecast.−1000100200036912151821EUR/MWh · local hour · 2026-09-06v1 historical replay: the default delivery dayStatic rendering of v1's saved historical replay for one holdout delivery day at the unperturbed load scenario: the median forecast, the 80 percent interval as a shaded band, and the price that actually cleared as a dashed line. Not a live forecast.−1000100200061218EUR/MWh · local hour · 2026-09-06

Median forecast 80% prediction interval Observed price

How the product works

The released model, v1 · released LightGBM, topic by topic: the artifact its one-shot test evaluated and the demo computes.

All topics in full

Data and the information cutoff

What it forecasts. The German–Luxembourg day-ahead price of each hour of the next delivery day, in EUR/MWh: 24 values on most days and 23 or 25 on daylight-saving transition days, issued together as one curve before the 12:00 CET auction gate.

Where the data comes from. One committed hourly snapshot, from 2019-01-01 to 2026-09-06, of the day-ahead price and the day-ahead load forecast, pinned by its SHA-256 hash. It was pulled from SMARD.de, which republishes the ENTSO-E series, and a sample spanning every regime agreed with the ENTSO-E Transparency Platform to the cent. Data: ENTSO-E Transparency Platform; Bundesnetzagentur | SMARD.de — CC BY 4.0.

The information cutoff. Every price-derived input uses only prices of delivery days before the forecast day, and rolling price statistics are frozen at the day before. The day-ahead wind and solar forecast is published after the gate, so the model never uses it. That the load forecast exists before the gate is an assumption, not a measurement.

Fitting, calibration and test data. The model was fitted on data up to 2026-04-07, calibrated once on 2026-04-09..2026-06-07 and tested once on 2026-06-09..2026-09-06. The demo and this page replay the committed snapshot; no live data feed is read.

Preprocessing. A quarter-hour series becomes an hour only from four complete quarter-hours; from 2025-10-01 the hourly price is the mean of four quarter-hour prices. The price is not log-transformed, because it is often negative.

Price regimes and negative prices

Three regimes shape the development period: before 2021-09-01, the energy crisis from 2021-09-01 to 2022-12-31, and from 2023-01-01 a market with frequent negative prices. The development hours split into 4,319, 2,112 and 4,316 hours across them; 465 hours, on 85 days, had a negative price.

Why it matters: the model learns from calm, crisis and negative-price periods together, so its errors and interval coverage are reported per regime, and the calibration's assumption that recent errors resemble future ones breaks when the regime shifts. The day-ahead price floor moved to −600 EUR/MWh from 2026-05-28, an environment shift the frozen model predates.

Yearly price levels and negative-hour counts, in the archived report

The inputs it uses, and why

v1 uses 25 inputs, a catalog frozen before fitting: calendar, holiday and seasonal features; two date-based regime flags; the day-ahead load forecast for the hour and for the day; the price of the same hour one, two and seven days earlier; rolling price statistics over the previous week and month; and a weekly count of negative-price hours.

The inputs, by group, as the model card names them
GroupInputs
Calendar, holidays and seasonlocal_hour, day_of_week, month, is_federal_holiday, is_day_after_holiday, is_bridge_day, day_type, dst_transition_day, summer_peak, winter_peak
Day-ahead load forecastload_forecast_mw, load_forecast_day_mean_mw
Price of the same hour on earlier daysprice_lag_24h, price_lag_48h, price_lag_168h
Rolling price statistics, frozen at the day beforeprice_roll_mean_168h, price_roll_std_168h, price_roll_mean_720h, price_roll_std_720h, price_roll_q05_168h, price_roll_q50_168h, price_roll_q95_168h
Negative prices and regime flagsnegative_price_count_168h, crisis_period, post_crisis

What was left out, and why. The one candidate domain input, a residual-load proxy built from actual wind and solar generation, had to lower the pooled pinball loss in a comparison fixed before fitting; it did not (+0.371516%). The day-ahead wind and solar forecast is excluded because it is published after the gate; a separate benchmark measured what it would have been worth (-19.4926%).

Why hour-of-day and day-of-week inputs. The price spectrum shows pronounced cycles at 24 and 168 hours, with a 12-hour harmonic, and their amplitude changed in the crisis; the calendar inputs follow that structure rather than assuming it.

The spectral figures behind the calendar inputs, in the archived report

How it was tested before release

Before release. Five development folds of 90 days each, spanning all three regimes, were scored walk-forward: each fold's model was fitted on earlier data only, with a gap of one delivery day before its test block. The similar-day naive, a 168-hour seasonal naive and ridge regression were scored on the same rows. The folds hold 10,747 hours on 448 days, the same hours the research comparison uses.

The one-shot test. After every choice was frozen, the model was fitted once, calibrated once on 2026-04-09..2026-06-07 and frozen; only then was the 90-day holdout, 2026-06-09..2026-09-06, opened and scored, once. Pre-specified one-shot holdout DM test on a fixed 90-day window — confirmatory-style, not power-qualified.

Evidence classes. The development folds also chose the input catalog, so their results are post-selection evidence; the holdout is the only test specified in advance; prospective live evidence is a third class, reserved for a future final model.

Leakage checks, on the browser path. Setting the delivery day's 24 prices to missing changes the forecast by exactly 0.0; raising all 24 D−1 prices by 250 EUR/MWh moves it by 220.9433 EUR/MWh. The model's input schema also refuses the post-gate forecast.

Measured results

The one-shot holdout Confirmatory-style, not power-qualified

On its pre-specified 90-day holdout, v1 beat the similar-day naive: MAE 25.9 against 27.8 EUR/MWh, and mean pinball loss 6.7 against 13.9 EUR/MWh. A one-sided Diebold–Mariano test on the daily pinball-loss vectors gave p < 10⁻⁶; it tests the probabilistic forecast, not the MAE difference.

Its prediction intervals covered 0.4407, 0.7593 and 0.9398 of the holdout's hours at the 50, 80 and 95% levels.

Where it falls short. On the development folds its point error is 28.58% worse than the naive's, pooled over all days (a one-sided test for an improvement gives p = 0.948: no evidence of an advantage). Over the August 2022 peak weeks its 95% interval covered 0.194 of outcomes.

In the shared development comparison, whose error scores divide by the naive's error in each period, v1's development replay scores 1.052 on the point-error score and 0.986 on the interval score, where the naive scores 1.000; lower is better.

Why these scores differ from its own report

What drives its forecasts

The price of the same hour one day earlier dominates the median forecast.

Mean absolute SHAP value, EUR/MWh · median head · the released artifact on fold 5's test block · in-sample diagnostic

The ten inputs with the largest mean absolute SHAP value for the released model's median forecastHorizontal bars from zero, one per input, in EUR/MWh; the same-hour price one day earlier is by far the largest. The released artifact explained on fold five's test block, rows it was fitted on: an in-sample diagnostic.price_lag_24h14.6price_lag_168h5.7price_roll_q50_168h4.4price_lag_48h4.4day_of_week4.4price_roll_q95_168h4.4load_forecast_mw3.4local_hour3.4price_roll_mean_720h3.3day_type3.00246810121416mean absolute SHAP value, EUR/MWh · median head · in sampleThe ten inputs with the largest mean absolute SHAP value for the released model's median forecastHorizontal bars from zero, one per input, in EUR/MWh; the same-hour price one day earlier is by far the largest. The released artifact explained on fold five's test block, rows it was fitted on: an in-sample diagnostic.price_lag_24h14.6price_lag_168h5.7price_roll_q50_168h4.4price_lag_48h4.4day_of_week4.4price_roll_q95_168h4.4load_forecast_mw3.4local_hour3.4price_roll_mean_720h3.3day_type3.00481216mean absolute SHAP value, EUR/MWh ·median head · in sample

The weekly lag, the rolling weekly price quantiles, the two-day lag and the day of the week follow, close to one another.

Which model and rows. These are the released artifact's own SHAP values for its median head on fold 5's test block, 2026-01-08 to 2026-04-07: rows it was fitted on, so an in-sample diagnostic. Fold 5's development model, explained out of sample on the same rows, ranks the inputs almost identically (Spearman rank correlation 0.98; 10 of the top 10 shared), but agreement does not make them the same evidence.

View values, beside the development model's ranking
Mean absolute SHAP value of the median head, EUR/MWh, on fold 5's test block
RankReleased artifact, in sampleValueFold 5 development model, out of sampleValue
1price_lag_24h14.638026612371469price_lag_24h15.401310383360386
2price_lag_168h5.657623951395043price_lag_168h5.412601170582895
3price_roll_q50_168h4.448508921689905price_roll_q50_168h5.1258021429891265
4price_lag_48h4.439940498351033day_of_week4.510413707759048
5day_of_week4.396023958232133price_lag_48h4.206478858888543
6price_roll_q95_168h4.386255175377148load_forecast_mw3.2302870958504752
7load_forecast_mw3.418967676456138day_type3.1644473239108297
8local_hour3.395383482828897local_hour3.064186071616306
9price_roll_mean_720h3.281260605520439price_roll_mean_720h2.9835918587747425
10day_type2.982999170265987price_roll_q95_168h2.71908082228481

SHAP on the median explains its central tendency, not the interval width, and it is not a test of incremental value: that was the comparison fixed before fitting, in the inputs topic.

The out-of-sample SHAP figures of fold 5’s development model, in the archived report

Which inputs matter, and what that does not show

Permutation importance shuffles one input at a time and measures how much the median forecast's MAE rises: here for fold 5's development model on its own test block, out of sample. price_lag_24h adds 8.3 EUR/MWh, price_lag_48h 1.8 and day_of_week 1.4. Its ranking agrees with SHAP's at the top and differs in the middle (Spearman rank correlation 0.69).

Permutation importance: rise in the median forecast's MAE when one input is shuffled, EUR/MWh, fold 5's development model on its own test block
RankInputMAE increaseStandard deviation
1price_lag_24h8.2608025389812920.30247307929369166
2price_lag_48h1.8025100351414630.14628203865002448
3day_of_week1.4435931977728150.15776352757618647
4local_hour1.12850287135033440.09176676071425387
5price_lag_168h1.09668406589529740.08430715494917224
6load_forecast_day_mean_mw0.41051486757333320.07627746551533812
7load_forecast_mw0.38556516723968280.07415806585874446
8day_type0.336494158974846140.06551227273566475
9price_roll_std_720h0.18862706254185040.04192072992783573
10price_roll_q50_168h0.151147049443960320.05026603320434395

Neither ranking measures incremental value or causation; the only incremental-value test was the comparison fixed before fitting.

Scenario sensitivity. The load-forecast control in the replay and the demo multiplies the day's load forecast and holds every other input fixed. Scenario perturbations are ceteris-paribus sensitivity probes and may be out of distribution.

Where it fails: errors by regime

Errors and coverage are worst in the crisis: MAE 141.0 EUR/MWh [123.1, 160.4], with the 95% interval covering 0.555 of 2,112 hours, against 13.3 EUR/MWh and 0.889 before it and 21.6 EUR/MWh and 0.943 after. Over the August 2022 peak weeks the 95% interval covered 0.194 of 408 hours; on negative-price hours, 0.710.

The released recipe on its five development folds, by stratum: MAE in EUR/MWh with a day-block bootstrap 95% confidence interval for thin subsets, and interval coverage as a fraction of hours
StratumHoursDaysMAE, EUR/MWh50% coverage80% coverage95% coverageReading
All development hours10,74744841.7434815568312350.364473806643714540.62808225551316640.8451660928631246quantitative
Before the crisis4,31918013.3244605696675650.31373003009956010.59134058809909710.8888631627691596quantitative
The crisis2,11288140.9928521771404 [123.10192189737595, 160.35247258127796]0.208806818181818180.35274621212121210.5553977272727273qualitative (thin subset)
After the crisis4,31618021.6153724033249330.491427247451343860.79958294717330860.9432344763670065quantitative
Negative-price hours4658539.03261154910987 [33.01702504612175, 44.88987296822982]0.20215053763440860.4322580645161290.7096774193548387qualitative (thin subset)
Low wind and solar days6482738.63067566038576 [19.902467254572812, 61.37871816414696]0.257716049382716030.493827160493827130.7716049382716049qualitative (thin subset)
Other days10,09942141.943214027461650.37132389345479750.63669670264382620.8498861273393405quantitative
Weekdays7,63031843.3735123905244750.35412844036697250.60707732634338140.8330275229357799quantitative
Weekends3,11713037.7533836225741060.38979788257940330.67949951876804620.8748796920115496quantitative
August 2022 peak weeks40817275.25954291591773 [236.7974823998587, 316.73649476759823]0.01960784313725490.06617647058823530.19362745098039216qualitative (thin subset)

Which model. These strata come from the five development folds, each scored by the model fitted for that fold and calibrated on its own window, not by the frozen artifact, whose holdout covers only the most recent regime. Thin subsets carry day-block bootstrap 95% confidence intervals and are read qualitatively. The crisis failure's mechanism is in the limitations: shrinkage toward the training price level, with calibration thresholds estimated at a lower level.

How reliable its intervals are

Calibration raised coverage, which stayed below nominal at every level, on the holdout and on the development folds.

Share of hours inside the interval · nominal level as reference · the frozen artifact on its one-shot holdout, and the development folds

  • raw heads
  • after CQR
  • final
  • nominal level
How often the released model's intervals contained the price, by calibration stageTwo panels, the frozen artifact on its one-shot holdout and the development folds. For each nominal level, three short lines: the coverage of the raw heads (open circle), after CQR (open diamond) and final (filled triangle), with the nominal level as a black vertical line across them.One-shot holdout, the frozen artifact50% intervalraw0.3546CQR0.4389final0.440780% intervalraw0.5991CQR0.7597final0.759395% intervalraw0.8394CQR0.9398final0.93980.20.40.60.81.0Development folds, one model per fold50% intervalraw0.2257CQR0.3642final0.364580% intervalraw0.4322CQR0.6280final0.628195% intervalraw0.6705CQR0.8416final0.84520.20.40.60.81.0x: share of hours inside the interval · the black line is the nominal level, a reference, not a targetHow often the released model's intervals contained the price, by calibration stageTwo panels, the frozen artifact on its one-shot holdout and the development folds. For each nominal level, three short lines: the coverage of the raw heads (open circle), after CQR (open diamond) and final (filled triangle), with the nominal level as a black vertical line across them.One-shot holdout, the frozen artifact50% intervalraw0.3546CQR0.4389final0.440780% intervalraw0.5991CQR0.7597final0.759395% intervalraw0.8394CQR0.9398final0.93980.20.40.60.81.0Development folds, one model per fold50% intervalraw0.2257CQR0.3642final0.364580% intervalraw0.4322CQR0.6280final0.628195% intervalraw0.6705CQR0.8416final0.84520.20.40.60.81.0x: share of hours inside the interval ·the black line is the nominal level, areference, not a target

The intervals come from nine quantile heads, then conformalized quantile regression (CQR), which shifts them by thresholds calibrated on a recent window, then an isotonic step that keeps the quantiles in order. On the one-shot holdout the 95% interval covered 0.8394 of hours from the raw heads, 0.9398 after CQR and 0.9398 after the isotonic step; on the development folds, 0.6705, 0.8416 and 0.8452.

Coverage is read with width: over the development hours the final intervals averaged 41.5, 75.5 and 130.9 EUR/MWh at the 50, 80 and 95% levels. The holdout report records coverage but not width.

The one hard gate was correctness, not a favourable number: adjacent quantiles crossed 10,158 times from the raw heads and 4,412 times after CQR on the development folds, and 0 times after the isotonic step; 0 on the holdout.

CQR's finite-sample marginal guarantee applies to its output before the isotonic step, and only when past and future errors are exchangeable; regime shifts break that, so every coverage figure here is empirical.

Read a forecast

Forecast for 2026-09-06, a day of the one-shot holdout

Historical replay · EUR/MWh by local hour (Europe/Berlin) · the frozen released model

Prediction-interval level
The released model's forecast for one held-out delivery dayMedian forecast as a line, the chosen prediction interval as a band, and the price that cleared as a dashed line, for each local hour. A historical replay, not a live forecast.

Median forecast Prediction interval Observed price

At the selected level, the frozen model's empirical coverage over the holdout was 0.7593.

How to read it. The line is the median forecast for each local hour; the band is the prediction interval at the level you choose; the dashed line is the price that cleared, an outcome that was never an input. Historical out-of-sample replay — the frozen champion forecasting a 90-day period it never trained on. This is not a live forecast.

The controls. The level selector reads other quantiles of the same forecast, and the frozen model's empirical coverage at that level over the holdout is shown beside the chart. The load-forecast scenario multiplies the day's load forecast with every other input held fixed, and hides the cleared price, which belongs to the unperturbed day.

Computed in your browser. The demo forecasts historical delivery days with the released model's own boosters, so a Python runtime and the model download first, about 57 MB on a first visit; on a committed fixture of 54 delivery days its output equals the frozen artifact's bitwise. Change the interval level or the load scenario there as here.

Try the v1 demo

Limitations

The main limits, each in full below: the development results are post-selection evidence; the intervals under-cover when the regime shifts, severely in the 2022 crisis; the model is frozen, fitted 152 delivery days before its snapshot ends; the load forecast's availability before the gate is an assumption, not a measurement; and it is a portfolio artifact, not an operations system.

  • Exchangeability under regime shift. CQR provides finite-sample marginal coverage guarantees under exchangeability. The walk-forward CV mildly violates exchangeability — the crisis regime is not exchangeable with the pre-crisis regime, and the solar-driven negative-price era is not exchangeable with either — so empirical coverage may diverge from nominal on regime-shift folds. This is documented in the reliability diagram (Section 8.4).
  • Development versus one-shot evidence. The five-fold development results are descriptive post-selection evidence, never confirmatory: those folds also chose the catalog. Only the 90-day holdout was pre-specified and opened once, and on the development folds the point-accuracy DM shows a deficit, not merely the absence of an advantage.
  • Disclosed assumption — the load forecast. A65/A01 is pre-gate by explicit assumption, not by measurement: both the existence of the delivery-day load forecast before the 12:00 CET gate and its equality to the archived vector used here are assumed, and the regulatory update provision permits later revisions.
  • Disclosed assumption — the generation archive. A75 aggregate actual generation is used at its current archived values, which may differ from the values visible in real time despite the D-2 boundary.
  • The measured cost of the strict gate. The strict-gate design has a measured cost rather than an assumed one: the post-gate A69 forecast is worth 19.4926% of pooled raw-head pinball loss, and the project declines to use it.
  • A two-sided bounded target, live at the floor. The target is two-sided and bounded: the price is routinely negative and has hit the −500 EUR/MWh floor, which truncates the lower conformity residuals, so the lowest intervals under-cover conditionally near the floor.
  • Coverage divergence. Empirical coverage diverges from nominal: 0.4407 / 0.7593 / 0.9398 against 50 / 80 / 95 %, so the 50 % interval under-covers by roughly six points on the holdout window. On the crisis stratum it does not merely diverge, it collapses: over the August-2022 peak weeks the 95 % interval covered 0.194 of outcomes. The mechanism is measured — that fold's CQR thresholds were estimated on a May-June 2022 calibration window at a ~198 EUR/MWh level and applied to an evaluation block averaging 376 EUR/MWh, and the conformal correction is additive, not multiplicative. This is what a split-conformal guarantee does when exchangeability breaks; it is the defect later generations address (see the v2 and v3 chapters), and it is not fixed in the released v1.
  • Model staleness, with all four cutoffs. The deployed demo applies a frozen model whose raw-model fit cutoff (2026-04-07) precedes the snapshot cutoff (2026-09-06) by 152 delivery days, with the final calibration window 2026-04-09..2026-06-07 and the holdout window 2026-06-09..2026-09-06 — all four cutoffs published separately because they are four different dates.
  • The 15-minute MTU averaging choice. From 2025-10-01 an hourly price is the mean of four quarter-hour prices, so every hour-level statistic here — the negative-hour tally included — depends on that averaging choice, and a quarter-hour tally differs.
  • Scope. This is a portfolio artifact, not an operations system: no retraining schedule, no drift gate, no rollback machinery, no monitoring surface, and no multi-day-ahead forecast.

The day-ahead price floor moved to −600 EUR/MWh from 2026-05-28, an environment shift the frozen model predates.

Run this product

Run the released model on your machine. Install the pinned dependencies with uv sync, then uv run python predict_next_day.py --level 80 --self-check forecasts a delivery day offline from the bundled snapshot and re-proves the gate boundary.

Check its identity. The artifact fingerprint is 57e3ad40a7f48bb7896628ce2e5dec61314dea567da9867aede4bf1b0a10e0fb, the same value in the model card, the one-shot holdout report and the registered model's alias; the snapshot's SHA-256 hash is 7dd2dc73407706ca6bd3c1ad51d201ac0de35eec5ca129ce320cca639f697f00.

Check the browser computation. make wasm rebuilds the browser payload from the committed model, proves its output equal to the frozen artifact's on the fixture and exports the demo; uv run pytest tests/test_22_wasm_equivalence.py -q reruns that proof alone.

v1's runs in MLflow: training, the holdout and the diagnostics, readable without signing in. Rebuild this report from saved evidence. Deployment notes.

The archived report's container instructions are historical: the demo is a static Hugging Face Space that computes in the browser, and publishing it is the Owner's action.

How the models compare

v5 against v4, as a share of v4's error scores: −2% [−3%, −2%] on the point-error score and −2% [−3%, −2%] on the interval score, with 95% confidence intervals.

Development evidence, not a test on new data. Meeting the targets is a development diagnostic, not a product qualification.

  • Accuracy targets: each error score at least 10% below the strongest benchmark's, set on 2026-09-15; a policy's distance from them is a point comparison.
  • Daily LEAR: the strongest benchmark, a linear model refitted daily.
  • Not adopted: the candidates of the two experiments tested against v4 and not adopted, drawn as open circles. Pooled member, averaged: one LightGBM for all 24 hours, averaged over four sizes, in place of v4's three blocks. Pooled pair: v4's normalized and raw-price LightGBM pair, each pooled over all 24 hours. DDNN member on v4: a distributional neural network with one third of the blend's weight. Their cards are under the experiments not adopted between v4 and v5.

12 policies · the same 10,747 historical hours over 448 days · error scores averaged with equal weight over five test periods · lower is better

  • v5
  • v4
  • v3
  • v2
  • study arm, or a candidate not adopted
  • reference
  • v1
Error scores of the twelve policies, relative to the similar-day naive, against the targetsTwo dot plots with one row per policy in the same order; lower is better. The solid line marks the naive at one, a reference and not a target; the dashed line marks the target set before the experiments. Candidates of experiments that were tested and not adopted are open circles, as study points. Whether a policy met both targets is in the value table below the chart.v5v4v3v2Pooled member, averaged (not adopted)Pooled pair (not adopted)DDNN member on v4 (not adopted)Daily LEAR (benchmark)Normalized LEAR (study)Daily LightGBM (benchmark)v1Similar-day naive (normalizer)Point-error scoreratio to the naive · lower is better0.50.60.70.80.91.01.1naivetarget0.5220.5360.5660.6440.5370.5340.5420.6580.6720.7841.0521.000Interval scoreratio to the naive · lower is better0.50.60.70.80.91.01.1naivetarget0.4940.5060.5320.6160.5070.5050.5130.6390.6460.7400.9861.000Error scores of the twelve policies, relative to the similar-day naive, against the targetsTwo dot plots with one row per policy in the same order; lower is better. The solid line marks the naive at one, a reference and not a target; the dashed line marks the target set before the experiments. Candidates of experiments that were tested and not adopted are open circles, as study points. Whether a policy met both targets is in the value table below the chart.Point-error scoreratio to the naive · lower is better0.60.81.0naivetargetv50.522v40.536v30.566v20.644Pooled member, averaged (not adopted)0.537Pooled pair (not adopted)0.534DDNN member on v4 (not adopted)0.542Daily LEAR (benchmark)0.658Normalized LEAR (study)0.672Daily LightGBM (benchmark)0.784v11.052Similar-day naive (normalizer)1.000Interval scoreratio to the naive · lower is better0.60.81.0naivetargetv50.494v40.506v30.532v20.616Pooled member, averaged (not adopted)0.507Pooled pair (not adopted)0.505DDNN member on v4 (not adopted)0.513Daily LEAR (benchmark)0.639Normalized LEAR (study)0.646Daily LightGBM (benchmark)0.740v10.986Similar-day naive (normalizer)1.000

The dashed lines mark the targets: each error score at least 10% below the strongest benchmark, daily LEAR (set 2026-09-15). 25 policies were tested against them; v3 was the first to meet both; 16 later policies met them too, among them v4 and v5. The chart's 12 rows are not that census: 8 of them were tested against the targets, and the others are references that never were: daily LEAR, daily LightGBM, v1's development replay and the similar-day naive.

Each score divides a model's error by that of a simple similar-day forecast in the same period, which therefore scores 1.000. The interval score accounts for both interval width and missed outcomes.

For scale, as mean absolute error per test period: v5 4.8–14.4 EUR/MWh in the four ordinary periods and 45.5 EUR/MWh in the 2022 crisis period; the similar-day naive 8.6–30.5 and 86.9 EUR/MWh. Context only: the error scores rank the policies.

v1 appears here as its development replay; its one-shot holdout results are in the v1 chapter.

EvidenceCompare the runs in MLflowReview verdict, frozen 2026-10-10Engineering report, frozen 2026-10-10Raw CSV rows, frozen 2026-10-10

View values
Equal-fold error scores (ratio to the naive), the targets, and pooled errors (EUR/MWh), identical hours
PolicyPoint-error score (S_MAE)Interval score (S_WIS)Both targetsDistance from daily LEAR, point / interval, percentPooled MAE, EUR/MWhPooled WIS, EUR/MWh
v5 · DDNN-2 added v50.52232127604314320.4936627890811673met−20.60% / −22.74%17.050332863648959.977221704544798
v4 · three-block LightGBM added HGL0.53565865411537960.5055748401472236met−18.57% / −20.88%17.54969359332055510.23606326165729
v3 · weather features HG0.56576063763336410.532218690181866met−13.99% / −16.71%18.25888550047536210.665905821725305
v2 · blended LEAR, hour-aware intervals H00.64407213862868780.6160299894915677not met−2.09% / −3.59%20.2310354215464512.046459955387254
Pooled member, averaged (not adopted) R0.53680113993107090.5065780356195718met−18.40% / −20.72%17.52042966463680810.248430843718442
Pooled pair (not adopted) M0.53433167295014120.5048157261017694met−18.77% / −21.00%17.42342419640798210.205525194847981
DDNN member on v4 (not adopted) v5, CP-230.54210446846549830.5126648907263633met−17.59% / −19.77%17.96036116483292510.413018697663293
Daily LEAR (benchmark) B20.65781091237479210.6389910407326591——20.98425254516231312.662319073520665
Normalized LEAR (study) A10.67229081213700330.646015091607363not met2.20% / 1.10%20.7074919631863312.449676327150861
Daily LightGBM (benchmark) B30.78413639776829920.7399052224715813——26.32393319706729815.167693659401653
v1 · released LightGBM (development replay) B11.0518451348391990.9856366964174134——41.74348155683123525.24792934918561
Similar-day naive (normalizer) B01.01.0——32.8101016562761720.020603986162254

A fair comparison

The five test periods are called folds below; the third covers the 2022 price crisis. These are development results, not a test on new data.

Bootstrap settings and the five historical test periods

Paired intervals come from a moving-block bootstrap with seed 15042, 2,000 replicates and 7-day blocks, resampled identically for every policy. They are confidence intervals of an estimated difference, not forecast intervals. A change's interval as a share of the comparator's score is, from v4 on, the percentile interval of the ratio of the two scores over the same draws; for v2 and v3, it is the difference's interval divided by the comparator's score.

FoldDelivery daysDaysHours
Fold 12020-07-01 to 2020-09-28902,160
Fold 22021-04-01 to 2021-06-29902,159
Fold 3 (the 2022 crisis)2022-07-01 to 2022-09-28882,112
Fold 42025-05-01 to 2025-07-29902,160
Fold 52026-01-08 to 2026-04-07902,156
Definitions, the policies tested, and why v1 scores differently in its own report

The point-error score (S_MAE) is the mean over the five historical test periods (folds) of a policy's MAE divided by the similar-day naive's MAE in the same period; the interval score (S_WIS) does the same for the weighted interval score, which rewards narrow intervals and penalizes missed outcomes. MAE uses the emitted median.

The 25 policies tested against the targets, each identity counted once, by decision date. Decided 2026-09-16: Normalized LEAR; Normalized LightGBM; Normalized component mean; 84-day normalized LEAR; Normalized component mean, variant. Decided 2026-09-23: v2 · blended LEAR, hour-aware intervals; Pooled-interval control. Decided 2026-09-24: v3 · weather features. Decided 2026-09-30: v4 · three-block LightGBM added; Pooled LightGBM with weather; Three-block LightGBM; Normalized three-block LightGBM. Decided 2026-10-04: DDNN member on v4; v3 plus a capacity-averaged pooled LightGBM; v3 plus pooled normalized and raw LightGBM; v3 plus a pooled normalized LightGBM; v3 plus a pooled raw LightGBM; v3 plus normalized block LightGBM; v4 with dynamic intervals; v3 with dynamic intervals; DDNN alone; v3 plus a DDNN member. Decided 2026-10-11: v5 · DDNN-2 added; DDNN-2 alone; v3 plus a DDNN-2 member.

Why v1 scores 1.052 in the shared development comparison but 28.58% worse in its own report. Both figures describe the same 448 development days. v1's report compared its daily absolute error with the raw similar-day naive (MAE 32.45 EUR/MWh) and pooled all days, so the 2022 crisis dominates. This comparison gives each of the five folds equal weight, and its naive reference is the forecast's emitted median after the common residual layer (MAE 32.81 EUR/MWh). v1's own error is 41.74 EUR/MWh in both. v1's original nine-quantile pinball is a different score from the seven-quantile interval score used here.

How it evolved

  1. v1 · released LightGBMReleased · September 2026Nine-quantile LightGBM with calibrated intervals
  2. v2 · blended LEAR, hour-aware intervalsAdopted in research · September 2026Two LEAR forecasts blended, hour-aware intervals
  3. v3 · weather featuresAdopted in research · September 2026v2 plus three weather forecast inputs
  4. v4 · three-block LightGBM addedAdopted in research · September 2026v3 plus a three-block LightGBM member
  5. v5 · DDNN-2 addedAdopted in research · October 2026v4 plus a DDNN-2 member

Adopted changes, newest first

From v4 to v5: adding a distributional neural network

Development · post-selection

Predecessor
v4 · three-block LightGBM added. In September 2026, v4 was adopted in research.
What changed
v5 kept v4's inputs, its two LEAR forecasts and its LightGBM, and added DDNN-2, a distributional neural network that forecasts the whole next day at once, with one sixth of the blend's weight, taken from the LightGBM's third; the hour-aware intervals were re-estimated on the new forecast's own errors.
Comparator
Set in advance: v4 itself, on identical hours, so the protocol's comparator is also the predecessor and the comparison is direct.
Result
Point-error score −2% [−3%, −2%] and interval score −2% [−3%, −2%], as a share of v4's score, with 95% confidence intervals of that ratio from the experiment's own bootstrap draws; at the rule's 97.5% decision level, [−3%, −2%] and [−3%, −2%]. Development evidence after selection, not a test on new data.
Not established
The comparison scores 448 of the 2,654 days of data up to the end of the development period, 2019-01-01 to 2026-04-07; 0 of them fall in October to December, and only 1 winter (December to February) contains any of them. It is the second decision on a distributional neural network over the same five test periods; only a one-shot test on days never used for development or selection protects against that reuse.
Decision
In October 2026, v5 was adopted in research. It met the adoption rule set before the experiment against v4; the released model, v1, did not change. The two study arms, DDNN-2 alone and v3 plus a DDNN-2 member, were built only to show where the change came from, and were never candidates for adoption.

The comparison chart and its evidence, in the v5 chapter

From v3 to v4: adding a LightGBM forecaster

Development · post-selection

Predecessor
v3 · weather features. In September 2026, v3 was adopted in research.
What changed
v4 kept v3's inputs and its two LEAR forecasts, added a LightGBM forecaster with one third of the blend's weight, and re-estimated the hour-aware intervals on the new forecast's own errors. The gain comes from the combination: on its own, no LightGBM arm showed an improvement over v3, but the blend improves both error scores, because a nonlinear model built from decision trees makes different errors from the two linear forecasts. The LightGBM's split into hour blocks is not shown to contribute.
Comparator
Set in advance: v3 itself, on identical hours, so the protocol's comparator is also the predecessor and the comparison is direct.
Result
Point-error score −5% [−6%, −4%] and interval score −5% [−6%, −4%], as a share of v3's score, with 95% confidence intervals of that ratio from the experiment's own bootstrap draws; development evidence, not a test on new data.
Not established
Separate hour-block models are not shown to help: the three-block against the pooled LightGBM shows no demonstrated joint preference. A gain over the August 2022 peak is not shown either: over those 17 days, v4's point error is higher than v3's.
Decision
In September 2026, v4 was adopted in research. It met the adoption rule set before the experiment against v3; the released model, v1, did not change. The three study arms were built only to separate the change into steps, and were never candidates for adoption.

The comparison chart and its evidence, in the v4 chapter

From v2 to v3: adding weather forecasts

Development · post-selection

Predecessor
v2 · blended LEAR, hour-aware intervals. In September 2026, v2 was adopted in research.
What changed
v3 kept v2's blend of two LEAR forecasts and its hour-aware intervals, and added three weather forecasts available before the auction: wind speed at 10 m and 100 m and solar radiation, each with a missing-data indicator.
Comparator
Set in advance: v2 itself, on identical hours, so the protocol's comparator is also the predecessor and the comparison is direct.
Result
Point-error score −12% [−16%, −9%] and interval score −14% [−17%, −11%], as a share of v2's score, with 95% confidence intervals; development evidence, not a test on new data.
Not established
The three weather inputs were tested together, so no single input's contribution is isolated; within the 2022 crisis period the point-error gain is not demonstrated on its own.
Decision
In September 2026, v3 was adopted in research. It met the joint improvement rule against v2 and both accuracy targets.

The comparison chart and its evidence, in the v3 chapter

From v1 to v2: a blended linear model with hour-aware intervals

Development · post-selection

Predecessor
v1 · released LightGBM. In September 2026, v1 was released.
What changed
After v1 failed in the 2022 crisis, v2 replaced its LightGBM quantile model and fixed-window calibration with an equal blend of two LEAR forecasts refitted every day, and intervals built from recent errors by hour of the day.
Comparator
Set in advance: daily LEAR, the strongest benchmark, not the predecessor v1; a pooled-interval control isolated the interval method.
Result
Against daily LEAR: point-error score −2% [−4%, −1%] and interval score −4% [−5%, −2%], as a share of daily LEAR's score, with 95% confidence intervals; development evidence, not a test on new data.
Against the predecessor
No paired interval for v2 against v1 exists: the protocol did not test that pair. As descriptive context on the same development hours, without an interval, the point-error scores are 1.052 for v1 and 0.644 for v2, and the interval scores 0.986 and 0.616. v1's one-shot holdout covers a different window and evidence class and is not compared.
Not established
The gain over daily LEAR is not attributed to hour-aware intervals alone, the blend and the interval layer are not separated, and against its pooled-interval control there is no demonstrated joint preference.
Decision
In September 2026, v2 was adopted in research. v3 was built on it.

The comparison chart and its evidence, in the v2 chapter

Experiments not adopted between v1 and v2

  • Calibration experiment Not adopted September 2026

    Recalibration alone was not enough: the model itself had to adapt.

    Question, result and evidence

    Could recalibrating v1, without refitting it, repair its coverage in the 2022 crisis?

    Against v1, on the matched crisis window: the hours inside the 95% interval rose from 79 to 131 of 408.

    EvidenceCompare the runs in MLflowEngineering report, frozen 2026-09-16Review verdict, frozen 2026-09-16

  • Model comparison study Not adopted September 2026

    No policy met the criteria; the study informed v2's blend of two LEAR forecasts.

    Question, result and evidence

    Which forecasting approach copes best with the 2022 crisis?

    Nine policies on the same hours, none meeting the product criteria. Normalized LEAR cut crisis-window MAE to 49.9 EUR/MWh, but daily LEAR kept the better error scores: 0.658 and 0.639 against 0.672 and 0.646.

    EvidenceCompare the runs in MLflowEngineering report, frozen 2026-09-16Review verdict, frozen 2026-09-16

Experiments not adopted between v4 and v5

  • Pooled LightGBM member for v4 Not adopted October 2026

    Both candidates were decisively worse than v4 in one test period, with a 95% interval wholly above zero; the rule allowed none, so v4 was kept as it was.

    Question, result and evidence

    Can one pooled LightGBM, for all 24 hours, replace v4's three-block LightGBM member without losing accuracy against v4 itself?

    Against v4, over the five test periods together, neither candidate's 95% interval lay wholly above zero: the averaged member's paired difference is +0.0011 [−0.0031, +0.0054] in the point-error score and +0.0010 [−0.0028, +0.0049] in the interval score; the pair's −0.0013 [−0.0036, +0.0016] and −0.0008 [−0.0030, +0.0022]. In fold 4, both were decisively worse: point error +0.3 [+0.1, +0.4] and +0.2 [+0.1, +0.3] EUR/MWh, interval score +0.2 [+0.1, +0.2] and +0.1 [+0.024, +0.2] EUR/MWh. Development evidence after selection, not a test on new data.

    EvidenceCompare the runs in MLflowEngineering report, frozen 2026-10-04Review verdict, frozen 2026-10-04

  • DDNN member on v4 Not adopted October 2026

    The improvement over v4 that the rule required was not shown, on either score.

    Question, result and evidence

    Does a distributional neural network, added to v4 as a one-third member, improve on v4 in point and interval accuracy together?

    Against v4, the paired difference is +0.0064 [−0.0016, +0.0149] in the point-error score and +0.0071 [−0.0009, +0.0138] in the interval score, with 95% intervals; in fold 3, the 2022 crisis, its point error was decisively worse, +1.9 [+0.3, +4.4] EUR/MWh. Development evidence after selection, not a test on new data.

    EvidenceCompare the runs in MLflowEngineering report, frozen 2026-10-04Review verdict, frozen 2026-10-04

How the research improved, newest first

Adopted in researchOctober 2026

v5 · DDNN-2 added

v4 plus a DDNN-2 member

Development · post-selection

Does a distributional neural network that forecasts the whole next day at once, added to v4 with a fixed one-sixth weight, improve both of its error scores?

v5 adds DDNN-2, a distributional neural network: it forecasts the 24 hours of the next day together, each as a full probability distribution, from the same information as v4. It takes half of the third that v4's LightGBM held; the two LEAR forecasts keep two thirds, and the hour-aware intervals are re-estimated on the new forecast's own errors.

v4

  • two LEAR forecasts, two thirds of the weight
  • a LightGBM forecaster, one third
  • hour-aware intervals from recent errors

added in v5

  • DDNN-2: a distributional neural network that forecasts the whole next day at once
  • half of the LightGBM's third: one sixth of the weight

same information; intervals re-estimated on the new errors

Against v4, the point-error score changed by −2% [−3%, −2%] and the interval score by −2% [−3%, −2%], each as a share of the comparator's score, with 95% confidence intervals; at the rule's 97.5% decision level the intervals are [−3%, −2%] and [−3%, −2%].

Difference in error score, v5 − v4 · paired intervals at 95% and at the rule's 97.5% decision level · identical hours · development, post-selection

v5 minus v4: equal-fold error-score differences with 95 percent intervals and with the intervals at the rule's decision levelFour rows: the point-error score and the interval score, each with its 95 percent interval and with its wider interval at the rule's decision level, named in the row labels. Each shows the estimated difference as a pentagon and its interval as a line; every interval lies wholly left of zero, which favours v5.Difference, v5 − v4error-score difference · below zero favours v5−0.020−0.015−0.010−0.0050.0000.005no differencePoint-error score, 95% interval−0.0133 [−0.0161, −0.0096]Point-error score, 97.5% interval,the decision level−0.0133 [−0.0166, −0.0091]Interval score, 95% interval−0.0119 [−0.0143, −0.0087]Interval score, 97.5% interval,the decision level−0.0119 [−0.0147, −0.0084]v5 minus v4: equal-fold error-score differences with 95 percent intervals and with the intervals at the rule's decision levelFour rows: the point-error score and the interval score, each with its 95 percent interval and with its wider interval at the rule's decision level, named in the row labels. Each shows the estimated difference as a pentagon and its interval as a line; every interval lies wholly left of zero, which favours v5.Difference, v5 − v4error-score difference · below zerofavours v5−0.020−0.015−0.010−0.0050.0000.005no differencePoint-error score, 95% interval−0.0133 [−0.0161, −0.0096]Point-error score, 97.5% interval, thedecision level−0.0133 [−0.0166, −0.0091]Interval score, 95% interval−0.0119 [−0.0143, −0.0087]Interval score, 97.5% interval, thedecision level−0.0119 [−0.0147, −0.0084]

All five conditions of the rule set in advance held: at the rule's 97.5% level both paired differences' intervals lie below zero; v5 passed the six screening criteria set before the experiments (the two accuracy targets, interval coverage in each test period, the August 2022 peak against the benchmarks, each test period against the daily benchmarks, and complete forecasts); the evaluation was complete and valid; no test period's paired interval lies wholly above zero; and both scores improved on v4's by more than the practical size set in advance, half a percent.

View values
RowDifference, v5 − v4
normalized score difference
Point-error score, 95% interval−0.01333737807223645 [−0.016121484421607043, −0.009595925721551714]
Point-error score, 97.5% interval, the decision level−0.01333737807223645 [−0.016593515917557655, −0.009139871117277598]
Interval score, 95% interval−0.011912051066056362 [−0.01434812523649127, −0.008704317096786424]
Interval score, 97.5% interval, the decision level−0.011912051066056362 [−0.014686660762561797, −0.00838381402215626]
View the change as a share of v4's score
Change as a share of v4's score
ScoreChange, percent95% interval97.5% interval, the decision level
Point-error score−2.49%[−2.96%, −1.79%][−3.04%, −1.68%]
Interval score−2.36%[−2.78%, −1.71%][−2.86%, −1.62%]

In October 2026, v5 was adopted in research. It met the adoption rule set before the experiment against v4; the released model, v1, did not change. The two study arms, DDNN-2 alone and v3 plus a DDNN-2 member, were built only to show where the change came from, and were never candidates for adoption.

Method

The blend. v5's central forecast gives v4's two LEAR forecasts, bit for bit, two thirds of the weight, v4's LightGBM one sixth and DDNN-2 one sixth. The weights were fixed before any fit and never tuned. The hour-aware intervals keep v4's recipe, re-estimated on v5's own errors.

DDNN-2. A feed-forward network written in NumPy, on one row per delivery day, with a Johnson SU distribution for each of the 24 hours, and exactly v4's information. Each member trains on up to two years before the forecast day, from 2019-01-01 at the earliest, minus a random fifth of whole weeks held out to stop its training; four configurations, chosen per test period by a search on training data only, times two seeds, are combined by the median of their forecasts.

The study arms: DDNN-2 alone, and DDNN-2 in the LightGBM's place

The study arms. DDNN-2 alone, against v4: −11% [−14%, −7%] on the point-error score and −16% [−19%, −12%] on the interval score, as shares of v4's score: descriptive, never eligible.

v3 plus a DDNN-2 member, DDNN-2 in the LightGBM's place, scored better than v5 itself: v5 minus it is +0.0067 [+0.0033, +0.0097] on the point-error score and +0.0062 [+0.0031, +0.0089] on the interval score, both intervals wholly above zero: with DDNN-2 present, adding the LightGBM member made both scores worse. It too was a study arm, never eligible, so the rule's candidate was v5.

Per-period consistency, including absolute errors

Did v5 help in every test period?

Every test period favours v5: in each, the paired 95% intervals of both errors lie below zero. The largest change is in fold 3, the 2022 crisis: point error −1.5 [−2.3, −0.7] EUR/MWh.

RowPoint error, v5 − v4
EUR/MWh, paired mean daily loss difference
Interval score, v5 − v4
EUR/MWh, paired mean daily loss difference
Fold 1−0.10876490668787397 [−0.15663215817633505, −0.04421789306202459]−0.06835227177153058 [−0.09755633072365016, −0.03564519265431773]
Fold 2−0.19256961026946673 [−0.34059887455329213, −0.04333364194639319]−0.14796142322496664 [−0.2372618917234631, −0.07229258216697157]
Fold 3 (crisis)−1.5290001479454176 [−2.3424333977644825, −0.6608124920680131]−0.766031483921644 [−1.1408621219016533, −0.2633714453431077]
Fold 4−0.1863791897791387 [−0.32426378499738184, −0.048799840996407925]−0.0898975815374854 [−0.1527542467215385, −0.009112545231936373]
Fold 5−0.5067149415746428 [−0.7532426698565389, −0.21945882194836108]−0.23494216061499174 [−0.362733768402562, −0.09657068000428516]

Absolute errors per test period

Mean absolute error per test period: v5 4.8–14.4 EUR/MWh in the four ordinary periods and 45.5 EUR/MWh in the 2022 crisis period, where v4 had 47.0.

The stress period: the 2022 crisis

The August 2022 peak

The August 2022 peak, 17 days inside the crisis period: v5's point error is 46.9 EUR/MWh against v4's 50.1. Descriptive, on a small sample: no inference is drawn.

Coverage and interval width

Did the intervals get more reliable, or only wider?

v5's pooled intervals are narrower than v4's at every level: mean widths 25.3, 54.7 and 100.2 EUR/MWh at the 50%, 80% and 95% levels, against 26.3, 56.1 and 101.9. Its pooled coverage is 0.4916, 0.7923 and 0.9395, against v4's 0.4961, 0.7905 and 0.9392.

Protocol and review

The rule, set on 2026-10-05 and frozen in the protocol before any of its fits: v5 would be adopted only if, against v4, the paired differences' intervals at 97.5% lay below zero for the interval score and at or below zero for the point-error score; it met the six original screening criteria; the evaluation was complete and valid; no test period was decisively worse, that is, none had a 95% paired interval wholly above zero; and both point estimates improved on v4's score by at least half a percent. The 97.5% level splits a 5% error rate across the two attempts the plan allowed; one ran. All five conditions held.

As a diagnostic, v5 meets all six original screening criteria, as v4, DDNN-2 alone and v3 plus a DDNN-2 member do. This is a development diagnostic, not a product qualification.

All 80 frozen causal and integrity controls passed, each negative check paired with a positive one: masking the delivery day and future inputs changed the forecast by exactly zero, and a day-before price change, weather permutations and held-out weeks moved DDNN-2.

No delivery-day outcome is used: the leakage test at every origin

No outcome from the delivery day on is used, at any origin. With every such outcome destroyed, the frozen network refitted at all 636 warm-up and evaluation origins reproduced the committed forecasts bit for bit at 636 of them, over 10,747 hours; a change to the previous day's prices moved them, and a planted one-day leak was caught in every test period. The input vintages are inherited from the earlier experiments, not re-tested here.

Adopted in researchSeptember 2026

v4 · three-block LightGBM added

v3 plus a three-block LightGBM member

Development · post-selection

Does adding a nonlinear forecaster, LightGBM, to v3 improve both of its error scores?

v4 adds a LightGBM forecaster, a nonlinear model built from decision trees, with the same information as v3, to its blend of two linear forecasts, and re-estimates the hour-aware intervals on the new forecast's own errors.

v3

  • two LEAR forecasts, blended equally
  • hour-aware intervals from recent errors

added in v4

  • a LightGBM forecaster: nonlinear, built from decision trees
  • one third of the blend's weight, the LEAR pair two thirds

same information; intervals re-estimated on the new errors

Against v3, the point-error score changed by −5% [−6%, −4%] and the interval score by −5% [−6%, −4%], each as a share of the comparator's score, with 95% confidence intervals.

Difference in error score, v4 − v3 · paired 95% confidence interval · identical hours · development, post-selection

v4 minus v3: equal-fold error-score differences with 95 percent confidence intervalsTwo rows, the point-error score and the interval score. Each shows the estimated difference as a diamond and its 95 percent confidence interval as a line; both lie wholly left of zero, which favours v4.Difference, v4 − v3error-score difference · below zero favours v4−0.05−0.04−0.03−0.02−0.010.000.01no differencePoint-error score−0.0301 [−0.0368, −0.0228]Interval score−0.0266 [−0.0327, −0.0204]v4 minus v3: equal-fold error-score differences with 95 percent confidence intervalsTwo rows, the point-error score and the interval score. Each shows the estimated difference as a diamond and its 95 percent confidence interval as a line; both lie wholly left of zero, which favours v4.Difference, v4 − v3error-score difference · below zerofavours v4−0.05−0.04−0.03−0.02−0.010.000.01no differencePoint-error score−0.0301 [−0.0368, −0.0228]Interval score−0.0266 [−0.0327, −0.0204]

All four conditions of the rule set in advance held: both paired differences' 95% confidence intervals lie below zero; v4 passed the six screening criteria set before the experiments (the two accuracy targets, interval coverage in each test period, the August 2022 peak against the benchmarks, each test period against the daily benchmarks, and complete forecasts); the evaluation was complete and valid; and no test period's paired interval lies wholly above zero.

View values
RowDifference, v4 − v3
normalized score difference
Point-error score−0.030101983517984543 [−0.03681584729111768, −0.02278213336960615]
Interval score−0.02664385003464209 [−0.032698827022918084, −0.020441588003386926]

In September 2026, v4 was adopted in research. It met the adoption rule set before the experiment against v3; the released model, v1, did not change. The three study arms were built only to separate the change into steps, and were never candidates for adoption.

Method

The blend. v4's central forecast gives v3's two LEAR forecasts, bit for bit, two thirds of the weight, and the mean of the raw and normalized three-block LightGBM forecasts one third. The weights were fixed before any result and never tuned. The hour-aware intervals keep v3's recipe, re-estimated on v4's own errors.

The same information as v3. Every LightGBM arm uses the model comparison study's LightGBM inputs plus the three weather forecasts and their missing-data indicators. The blocks are the night, the solar hours and the shoulder and peak hours, in local time. At every forecast origin each block picks one of 4 model sizes on the training window's last 28 days, by MAE, then refits.

The ladder. Three study arms separate the change into steps, one at a time. Daily LightGBM to the pooled LightGBM adds weather, bundled with the training-only choice of model size and the missing-input rule, so that step is not a weather effect on its own. The pooled to the three-block LightGBM adds the block split alone: the same rows, target, inputs, size grid, selection rule and interval recipe. v4 then blends the block models into v3.

The ladder: what each step added

The ladder: each step's equal-fold error-score difference, with 95 percent confidence intervalsThree steps in two panels. Adding weather, bundled with size selection and the missing-input rule, lowered both scores; the block split and the normalized target show no demonstrated joint preference: their intervals span zero.Point-error scoreerror-score difference · below zero favours the first named−0.2−0.10.0no differencePooled − daily LightGBM: weather, bundled withsize selection and the missing-input rule−0.2056 [−0.2377, −0.1766]Three-block − pooled LightGBM: the block splitalone+0.0050 [−0.0084, +0.0142]Normalized − raw three-block LightGBM: thetarget−0.0066 [−0.0304, +0.0144]Interval scoreerror-score difference · below zero favours the first named−0.2−0.10.0no differencePooled − daily LightGBM: weather, bundled withsize selection and the missing-input rule−0.1922 [−0.2278, −0.1659]Three-block − pooled LightGBM: the block splitalone+0.0063 [−0.0050, +0.0135]Normalized − raw three-block LightGBM: thetarget−0.0138 [−0.0348, +0.0065]The ladder: each step's equal-fold error-score difference, with 95 percent confidence intervalsThree steps in two panels. Adding weather, bundled with size selection and the missing-input rule, lowered both scores; the block split and the normalized target show no demonstrated joint preference: their intervals span zero.Point-error scoreerror-score difference · below zerofavours the first named−0.2−0.10.0no differencePooled − daily LightGBM: weather,bundled with size selection and themissing-input rule−0.2056 [−0.2377, −0.1766]Three-block − pooled LightGBM: theblock split alone+0.0050 [−0.0084, +0.0142]Normalized − raw three-block LightGBM:the target−0.0066 [−0.0304, +0.0144]Interval scoreerror-score difference · below zerofavours the first named−0.2−0.10.0no differencePooled − daily LightGBM: weather,bundled with size selection and themissing-input rule−0.1922 [−0.2278, −0.1659]Three-block − pooled LightGBM: theblock split alone+0.0063 [−0.0050, +0.0135]Normalized − raw three-block LightGBM:the target−0.0138 [−0.0348, +0.0065]
View values
RowPoint-error score
normalized score difference
Interval score
normalized score difference
Pooled − daily LightGBM: weather, bundled with size selection and the missing-input rule−0.20562784434169123 [−0.23768439456736903, −0.1765800776271131]−0.19216237218095578 [−0.22784175191813563, −0.16586110543866844]
Three-block − pooled LightGBM: the block split alone+0.0049994372049132485 [−0.008373621208457324, +0.014244960827487128]+0.0062996016332945715 [−0.004965340004477995, +0.013458515844260681]
Normalized − raw three-block LightGBM: the target−0.006595619965337529 [−0.0303682659462218, +0.014365304445946402]−0.013845499873477163 [−0.034816051195493254, +0.006521376305368999]

The block split (three-block minus pooled LightGBM): point-error score +0.0050 [−0.0084, +0.0142], interval score +0.0063 [−0.0050, +0.0135]: no demonstrated joint preference. It was tested on the raw price only, with one seed.

Each study arm against v3

No study arm on its own shows a demonstrated joint preference over v3: each arm's intervals against v3 span zero, except the three-block LightGBM's interval score, whose interval lies wholly above zero, worse: +0.0218 [+0.0004, +0.0450].

Each study arm, and v4, against v3: equal-fold error-score differences with 95 percent confidence intervalsFour rows in two panels. Each study arm's intervals span zero, except the three-block LightGBM's interval score, which lies wholly above zero, worse than v3; v4's lie wholly below zero.Point-error scoreerror-score difference · below zero favours the first named−0.04−0.020.000.020.04no differencePooled LightGBM − v3+0.0127 [−0.0088, +0.0427]Three-block LightGBM − v3+0.0177 [−0.0065, +0.0458]Normalized three-block LightGBM − v3+0.0112 [−0.0080, +0.0324]v4 − v3−0.0301 [−0.0368, −0.0228]Interval scoreerror-score difference · below zero favours the first named−0.04−0.020.000.020.04no differencePooled LightGBM − v3+0.0155 [−0.0039, +0.0412]Three-block LightGBM − v3+0.0218 [+0.0004, +0.0450]Normalized three-block LightGBM − v3+0.0080 [−0.0086, +0.0270]v4 − v3−0.0266 [−0.0327, −0.0204]Each study arm, and v4, against v3: equal-fold error-score differences with 95 percent confidence intervalsFour rows in two panels. Each study arm's intervals span zero, except the three-block LightGBM's interval score, which lies wholly above zero, worse than v3; v4's lie wholly below zero.Point-error scoreerror-score difference · below zerofavours the first named−0.04−0.020.000.020.04no differencePooled LightGBM − v3+0.0127 [−0.0088, +0.0427]Three-block LightGBM − v3+0.0177 [−0.0065, +0.0458]Normalized three-block LightGBM − v3+0.0112 [−0.0080, +0.0324]v4 − v3−0.0301 [−0.0368, −0.0228]Interval scoreerror-score difference · below zerofavours the first named−0.04−0.020.000.020.04no differencePooled LightGBM − v3+0.0155 [−0.0039, +0.0412]Three-block LightGBM − v3+0.0218 [+0.0004, +0.0450]Normalized three-block LightGBM − v3+0.0080 [−0.0086, +0.0270]v4 − v3−0.0266 [−0.0327, −0.0204]
View values
RowPoint-error score
normalized score difference
Interval score
normalized score difference
Pooled LightGBM − v3+0.012747915793243858 [−0.008794172015535534, +0.042714599211186276]+0.015524160108759788 [−0.0038990983353396178, +0.04116649379444595]
Three-block LightGBM − v3+0.017747352998157107 [−0.006504132602501644, +0.04581685361048941]+0.02182376174205436 [+0.0003812602641126484, +0.044965122644490506]
Normalized three-block LightGBM − v3+0.011151733032819577 [−0.007968476014353413, +0.03235233945818378]+0.007978261868577197 [−0.008616068429282007, +0.026979556122014123]
v4 − v3−0.030101983517984543 [−0.03681584729111768, −0.02278213336960615]−0.02664385003464209 [−0.032698827022918084, −0.020441588003386926]
Per-period consistency, including absolute errors

Did v4 help in every test period?

Every test period's point estimate favours v4, and no period's paired interval lies wholly above zero. In fold 3, the 2022 crisis, both intervals cross zero: point error −1.0 [−2.6, +0.6] EUR/MWh.

v4 minus v3 per fold, in EUR/MWh, with 95 percent confidence intervalsFive folds in two panels. Every point estimate is below zero. In fold 3, the 2022 crisis, both intervals cross zero.Point error, v4 − v3EUR/MWh, paired mean daily loss · below zero favours v4−3.0−2.5−2.0−1.5−1.0−0.50.00.51.0no differenceFold 1−0.3 [−0.5, −0.2]Fold 2−0.7 [−1.0, −0.4]Fold 3 (crisis)−1.0 [−2.6, +0.6]Fold 4−0.9 [−1.1, −0.6]Fold 5−0.7 [−1.0, −0.2]Interval score, v4 − v3EUR/MWh, paired mean daily loss · below zero favours v4−3.0−2.5−2.0−1.5−1.0−0.50.00.51.0no differenceFold 1−0.2 [−0.3, −0.1]Fold 2−0.3 [−0.5, −0.2]Fold 3 (crisis)−0.8 [−1.7, +0.1]Fold 4−0.5 [−0.6, −0.3]Fold 5−0.4 [−0.5, −0.1]v4 minus v3 per fold, in EUR/MWh, with 95 percent confidence intervalsFive folds in two panels. Every point estimate is below zero. In fold 3, the 2022 crisis, both intervals cross zero.Point error, v4 − v3EUR/MWh, paired mean daily loss · belowzero favours v4−3−2−101no differenceFold 1−0.3 [−0.5, −0.2]Fold 2−0.7 [−1.0, −0.4]Fold 3 (crisis)−1.0 [−2.6, +0.6]Fold 4−0.9 [−1.1, −0.6]Fold 5−0.7 [−1.0, −0.2]Interval score, v4 − v3EUR/MWh, paired mean daily loss · belowzero favours v4−3−2−101no differenceFold 1−0.2 [−0.3, −0.1]Fold 2−0.3 [−0.5, −0.2]Fold 3 (crisis)−0.8 [−1.7, +0.1]Fold 4−0.5 [−0.6, −0.3]Fold 5−0.4 [−0.5, −0.1]
View values
RowPoint error, v4 − v3
EUR/MWh, paired mean daily loss difference
Interval score, v4 − v3
EUR/MWh, paired mean daily loss difference
Fold 1−0.3229640928953561 [−0.490918874934352, −0.1792666182626842]−0.19035518052131994 [−0.2803454918532368, −0.09996558306048241]
Fold 2−0.66809437246072 [−1.028642381776143, −0.3595380911248335]−0.3480706987890354 [−0.525538656645842, −0.19405558493603636]
Fold 3 (crisis)−1.007646942926975 [−2.556157657177591, +0.5855596781267095]−0.7808591699897036 [−1.6984668320956737, +0.08755002730629288]
Fold 4−0.863745136499448 [−1.110747218367528, −0.6293465475668373]−0.47114701178041507 [−0.6288219246857399, −0.3215126400059036]
Fold 5−0.6878264409242298 [−0.9703964888404143, −0.22010451577675244]−0.36537969059780195 [−0.5047710892283478, −0.13683274559545425]

Absolute errors per test period, for v3 and v4

Mean absolute error per test period: v4 4.9–15.0 EUR/MWh in the four ordinary periods and 47.0 EUR/MWh in the 2022 crisis period, where v3 had 48.0.

MAE and WIS per fold for v3 and v4For each fold, two markers on that fold's own scale: v3 circle, v4 diamond, with the values printed underneath.MAE by fold, EUR/MWhlower is betterFold 106v3 5.3v4 4.9Fold 209.5v3 8.4v4 7.7Fold 3055v3 48.0v4 47.0Fold 4020v3 14.6v4 13.8Fold 5020v3 15.6v4 15.0WIS by fold, EUR/MWhlower is betterFold 103.5v3 3.2v4 3.0Fold 206v3 5.1v4 4.8Fold 3035v3 27.8v4 27.0Fold 409.5v3 8.5v4 8.0Fold 5010v3 9.1v4 8.7Each fold has its own scale, shared by the two generations inside it.MAE and WIS per fold for v3 and v4For each fold, two markers on that fold's own scale: v3 circle, v4 diamond, with the values printed underneath.MAE by fold, EUR/MWhlower is betterFold 106v3 5.3v4 4.9Fold 209.5v3 8.4v4 7.7Fold 3055v3 48.0v4 47.0Fold 4020v3 14.6v4 13.8Fold 5020v3 15.6v4 15.0WIS by fold, EUR/MWhlower is betterFold 103.5v3 3.2v4 3.0Fold 206v3 5.1v4 4.8Fold 3035v3 27.8v4 27.0Fold 409.5v3 8.5v4 8.0Fold 5010v3 9.1v4 8.7Each fold has its own scale, shared bythe two generations inside it.
View values
MAE by fold, EUR/MWh
Rowv3v4
Fold 15.2539246025380044.930960509642647
Fold 28.3809651936560287.713016585113509
Fold 348.03538569121360547.02773874828664
Fold 414.63611969446632313.772374557966877
Fold 515.64030999959778414.950077113978647
WIS by fold, EUR/MWh
Rowv3v4
Fold 13.2082354202758733.017880239754553
Fold 25.134481667236574.786404255399961
Fold 327.79182226572893627.01096309573922
Fold 48.5177815501074568.046634538327039
Fold 59.0522350024446188.685815912228607
The stress period: the 2022 crisis

The August 2022 peak: where v4's point error is higher

The protocol's stress period is fold 3, the 2022 crisis. Its peak, delivery 2022-08-15 to 2022-08-31, is the 17 days charted here; their figures are for those days only, not the whole period.

The August 2022 peak, 17 days inside the crisis period: v4's point error is higher than v3's, MAE 50.1 against 47.5 EUR/MWh, and so is its interval score, 28.0 against 27.3 EUR/MWh; 382 against 383 of its 408 hours fell inside the 95% interval. Descriptive, on a small sample: no inference is drawn.

The August 2022 peak: point error and interval score for v2, v3 and v4Three generations on the 17-day peak window, delivery 15 to 31 August 2022. v4's point error and interval score are higher than v3's there. Descriptive only.v2v3v4MAE, EUR/MWhlower is better010203040506052.547.550.1WIS, EUR/MWhlower is better01020304030.127.328.0The August 2022 peak: point error and interval score for v2, v3 and v4Three generations on the 17-day peak window, delivery 15 to 31 August 2022. v4's point error and interval score are higher than v3's there. Descriptive only.MAE, EUR/MWhlower is better0102030405060v252.5v347.5v450.1WIS, EUR/MWhlower is better010203040v230.1v327.3v428.0
View values
RowMAE, EUR/MWh
EUR/MWh
WIS, EUR/MWh
EUR/MWh
v252.509801535653530.102050231473346
v347.5214373203569127.308312686097484
v450.08510692500822628.02151976713374
Coverage and interval width

Did the intervals get more reliable, or only wider?

v4's pooled intervals are narrower than v3's at every level. Its pooled coverage is 0.4961, 0.7905 and 0.9392 at the 50%, 80% and 95% levels, against v3's 0.4937, 0.7914 and 0.9377. No hour or block effect is claimed.

Coverage and mean interval width at 50, 80 and 95 percent, pooled, for v3 and v4For each nominal level, coverage and mean width for v3 and v4. A black tick marks the nominal coverage. Higher coverage is not better on its own if the intervals widen.Coverage (fraction)closer to nominal is better50% intervalv3 0.4937v4 0.4961nominal 50%80% intervalv3 0.7914v4 0.7905nominal 80%95% intervalv3 0.9377v4 0.9392nominal 95%0.30.40.50.60.70.80.91.0Mean interval width, EUR/MWhnarrower at equal coverage is better50% intervalv3 27.1v4 26.380% intervalv3 58.8v4 56.195% intervalv3 106.2v4 101.9020406080100120140Coverage and mean interval width at 50, 80 and 95 percent, pooled, for v3 and v4For each nominal level, coverage and mean width for v3 and v4. A black tick marks the nominal coverage. Higher coverage is not better on its own if the intervals widen.Coverage (fraction)closer to nominal is better50% intervalv3 0.4937v4 0.4961nominal 50%80% intervalv3 0.7914v4 0.7905nominal 80%95% intervalv3 0.9377v4 0.9392nominal 95%0.30.40.50.60.70.80.91.0Mean interval width, EUR/MWhnarrower at equal coverage is better50% intervalv3 27.1v4 26.380% intervalv3 58.8v4 56.195% intervalv3 106.2v4 101.9020406080100120140
View values
Coverage (fraction)
Rowv3v4
50% interval0.49371917744486830.496138457243882
80% interval0.79138364194658970.7904531497161998
95% interval0.93765702056387830.9392388573555411
Mean interval width, EUR/MWh
Rowv3v4
50% interval27.14276013862921426.328242357115077
80% interval58.8067687357026956.139984005350115
95% interval106.24360374406864101.91577182718189
Protocol and review

The rule, set on 2026-09-29 and frozen in the protocol before any fit: v4 would be adopted only if, against v3, the interval score's paired difference had its upper 95% confidence limit below zero and the point-error score's at or below zero; it met the six original screening criteria; the evaluation was complete and valid; and no test period was decisively worse, that is, none had a paired interval wholly above zero. All four held.

As a diagnostic, v4 meets all six original screening criteria, as v3 does. Among the study arms, the normalized three-block LightGBM meets them; the pooled LightGBM misses criterion 4 (the August 2022 peak against the benchmarks), and the three-block LightGBM misses criteria 4 and 5 (each test period against the daily benchmarks). This is a development diagnostic, not a product qualification.

Run through this experiment's code, v3 reproduced its accepted forecasts bit for bit on all 10,747 hours, so the comparison is with v3 itself.

All 49 frozen causal and integrity controls passed: masking the delivery day or future weather changed the forecast by exactly zero, a day-before price change moved every arm, and the pooled and block arms saw the same rows.

22,260 LightGBM fits in the main run. The time of one daily cycle was measured as a diagnostic, not as a qualification for daily operation.

Adopted in researchSeptember 2026

v3 · weather features

v2 plus three weather forecast inputs

Development · post-selection

Do weather forecasts available before the auction improve v2?

v3 adds weather forecasts available before the auction to v2's inputs; the modelling setup is otherwise unchanged.

v2 inputs

  • price history
  • load forecast
  • calendar

added in v3

  • wind speed at 10 m
  • wind speed at 100 m
  • solar radiation

each with a missing-data indicator

Weather inputs lowered both error scores against v2.

Difference in error score, v3 − v2 · paired 95% confidence interval · identical hours · development, post-selection

v3 minus v2: equal-fold error-score differences with 95 percent confidence intervalsTwo rows, the point-error score and the interval score. Each shows the estimated difference as a dot and its 95 percent confidence interval as a line; both lie wholly left of zero, which favours v3.Difference, v3 − v2error-score difference · below zero favours v3−0.12−0.10−0.08−0.06−0.04−0.020.000.02no differencePoint-error score−0.0783 [−0.1006, −0.0570]Interval score−0.0838 [−0.1044, −0.0655]v3 minus v2: equal-fold error-score differences with 95 percent confidence intervalsTwo rows, the point-error score and the interval score. Each shows the estimated difference as a dot and its 95 percent confidence interval as a line; both lie wholly left of zero, which favours v3.Difference, v3 − v2error-score difference · below zerofavours v3−0.12−0.08−0.040.00no differencePoint-error score−0.0783 [−0.1006, −0.0570]Interval score−0.0838 [−0.1044, −0.0655]

Both confidence intervals lie below zero and every test period favours v3; its prediction intervals are narrower in every period, with pooled 95% coverage slightly lower, 0.9377 against 0.9389.

View values
RowDifference, v3 − v2
normalized score difference
Point-error score−0.07831150099532369 [−0.10059575155295458, −0.05703087928591252]
Interval score−0.08381129930970188 [−0.10438268112867141, −0.0655398413208593]

In September 2026, v3 was adopted in research. It met the joint improvement rule against v2 and both accuracy targets.

Method

Operational NCEP GFS 0.25°, the 00 UTC run of the day before delivery. Wind components are interpolated to each delivery hour; wind speed is computed per grid cell before a cos(latitude)-weighted average over the fixed box 47–55.25°N, 5.5–15.5°E; radiation is de-averaged from the forecast's running means. Each feature has a missing indicator. A regional weather proxy: not the DE-LU zone's exact outline and not a generation forecast.

Only delivery 2019-01-01 has no weather, structurally: its run would be 2018-12-31, before the input floor. Nothing was imputed from a failed retrieval.

Availability of each run before the D−1 11:00 UTC forecast origin is reconstructed from dated NCEP production records with an assumed dissemination lag. It is not a per-day delivery guarantee.

Per-period consistency, including absolute errors

Did weather help in every test period?

v3 minus v2 per fold, in EUR/MWh, with 95 percent confidence intervalsFive folds in two panels. Every point estimate is below zero. In fold 3, the 2022 crisis, the point-error interval crosses zero.Point error, v3 − v2EUR/MWh, paired mean daily loss · below zero favours v3−7−6−5−4−3−2−101no differenceFold 1−1.1 [−1.7, −0.5]Fold 2−1.1 [−2.0, −0.3]Fold 3 (crisis)−3.2 [−6.1, +0.037]Fold 4−1.5 [−2.7, −0.2]Fold 5−3.1 [−4.2, −1.7]Interval score, v3 − v2EUR/MWh, paired mean daily loss · below zero favours v3−7−6−5−4−3−2−101no differenceFold 1−0.6 [−1.0, −0.4]Fold 2−0.8 [−1.4, −0.4]Fold 3 (crisis)−2.4 [−4.0, −0.8]Fold 4−1.0 [−1.8, −0.3]Fold 5−2.0 [−2.4, −1.3]v3 minus v2 per fold, in EUR/MWh, with 95 percent confidence intervalsFive folds in two panels. Every point estimate is below zero. In fold 3, the 2022 crisis, the point-error interval crosses zero.Point error, v3 − v2EUR/MWh, paired mean daily loss · belowzero favours v3−6−4−20no differenceFold 1−1.1 [−1.7, −0.5]Fold 2−1.1 [−2.0, −0.3]Fold 3 (crisis)−3.2 [−6.1, +0.037]Fold 4−1.5 [−2.7, −0.2]Fold 5−3.1 [−4.2, −1.7]Interval score, v3 − v2EUR/MWh, paired mean daily loss · belowzero favours v3−6−4−20no differenceFold 1−0.6 [−1.0, −0.4]Fold 2−0.8 [−1.4, −0.4]Fold 3 (crisis)−2.4 [−4.0, −0.8]Fold 4−1.0 [−1.8, −0.3]Fold 5−2.0 [−2.4, −1.3]
View values
RowPoint error, v3 − v2
EUR/MWh, paired mean daily loss difference
Interval score, v3 − v2
EUR/MWh, paired mean daily loss difference
Fold 1−1.0568775077080046 [−1.6765662626114164, −0.5212095504165768]−0.6477003323495039 [−1.01275232920474, −0.35598004229867525]
Fold 2−1.076266161201147 [−1.996859263806638, −0.2643651654693269]−0.8471394585486971 [−1.4318023314496544, −0.393523717892896]
Fold 3 (crisis)−3.1782372305718454 [−6.089829306144048, +0.03687700160989306]−2.4294440795608274 [−4.023143370614526, −0.7751608725395348]
Fold 4−1.4881315027950706 [−2.7231726574338713, −0.20103752114857618]−1.0290126050119017 [−1.793812676567589, −0.30339521559099114]
Fold 5−3.1011517190158138 [−4.186992920206246, −1.6990429942376863]−1.9804085956025421 [−2.43524429772757, −1.2767746793683077]

Absolute errors per test period, for v1, v2 and v3

MAE and WIS per fold for v1, v2 and v3For each fold, three markers on that fold's own scale: v1 triangle, v2 square, v3 circle, with the values printed underneath.MAE by fold, EUR/MWhlower is betterFold 107.5v1 6.6v2 6.3v3 5.3Fold 2025v1 20.0v2 9.5v3 8.4Fold 30200v1 141.0v2 51.2v3 48.0Fold 4025v1 20.1v2 16.1v3 14.6Fold 5030v1 23.2v2 18.7v3 15.6WIS by fold, EUR/MWhlower is betterFold 104.5v1 4.0v2 3.9v3 3.2Fold 2015v1 10.8v2 6.0v3 5.1Fold 3095v1 87.9v2 30.2v3 27.8Fold 4015v1 11.4v2 9.5v3 8.5Fold 5015v1 13.5v2 11.0v3 9.1Each fold has its own scale, shared by the three generations inside it.MAE and WIS per fold for v1, v2 and v3For each fold, three markers on that fold's own scale: v1 triangle, v2 square, v3 circle, with the values printed underneath.MAE by fold, EUR/MWhlower is betterFold 107.5v1 6.6v2 6.3v3 5.3Fold 2025v1 20.0v2 9.5v3 8.4Fold 30200v1 141.0v2 51.2v3 48.0Fold 4025v1 20.1v2 16.1v3 14.6Fold 5030v1 23.2v2 18.7v3 15.6WIS by fold, EUR/MWhlower is betterFold 104.5v1 4.0v2 3.9v3 3.2Fold 2015v1 10.8v2 6.0v3 5.1Fold 3095v1 87.9v2 30.2v3 27.8Fold 4015v1 11.4v2 9.5v3 8.5Fold 5015v1 13.5v2 11.0v3 9.1Each fold has its own scale, shared bythe three generations inside it.
View values
MAE by fold, EUR/MWh
Rowv1v2v3
Fold 16.61288869541780066.3108021102460065.253924602538004
Fold 220.039141092307449.4570897432621618.380965193656028
Fold 3140.992852177140451.21362292178543648.035385691213605
Fold 420.0652715880581116.124251197261414.636119694466323
Fold 523.16834910136591218.73014571643314615.640309999597784
WIS by fold, EUR/MWh
Rowv1v2v3
Fold 14.00262940869221053.8559357526253753.208235420275873
Fold 210.8249255468300025.9814329386673555.13448166723657
Fold 387.9353494232605230.2212663452897627.791822265728936
Fold 411.3709509210939069.546794155119368.517781550107456
Fold 513.47035759082911211.0260576549088089.052235002444618

Errors by hour of the day, v2 against v3

Descriptive only: no hour or block effect is claimed.

MAE by local hour, v2 against v3, per foldFive panels, one per fold, each on its own scale: v2 dashed with squares, v3 solid with circles. Descriptive only.Fold 1 · 2020-07-01 to 2020-09-28071406121823v2v3Fold 2 · 2021-04-01 to 2021-06-290510152006121823v2v3Fold 3 · 2022-07-01 to 2022-09-2802040608006121823v2v3Fold 4 · 2025-05-01 to 2025-07-2901020304006121823v2v3Fold 5 · 2026-01-08 to 2026-04-0701020304006121823v2v3x: local delivery hour (Europe/Berlin) · y: MAE, EUR/MWh, lower is better · each fold on its own scaleMAE by local hour, v2 against v3, per foldFive panels, one per fold, each on its own scale: v2 dashed with squares, v3 solid with circles. Descriptive only.Fold 1 · 2020-07-01 to 2020-09-28071406121823v2v3Fold 2 · 2021-04-01 to 2021-06-290510152006121823v2v3Fold 3 · 2022-07-01 to 2022-09-2802040608006121823v2v3Fold 4 · 2025-05-01 to 2025-07-2901020304006121823v2v3Fold 5 · 2026-01-08 to 2026-04-0701020304006121823v2v3x: local delivery hour · y: MAE,EUR/MWh, lower is better · each fold onits own scale
View values
MAE by local hour, EUR/MWh
HourFold 1 v2Fold 1 v3Fold 2 v2Fold 2 v3Fold 3 v2Fold 3 v3Fold 4 v2Fold 4 v3Fold 5 v2Fold 5 v3
02.66868014948079242.57676889869377454.7364173504785684.61805548770184823.6895496048911623.9237196951004846.6031103137489537.0798853754863717.1851499040534386.842553634286969
12.9020942381179032.7986434552252125.7082192947086015.60473379404952426.49626749437405626.5742401685994846.9341893589120067.3172606177986227.2645862510419686.881701046426991
23.07649779065663242.98269073551975966.37235262630104956.31933963660299630.91937263335917430.734036219838477.7513030440934238.0644533898393777.3215664765077156.846153447508501
33.07393272678632.9896596007019746.7851131456184876.80462707780538235.2357629504150234.1366855080598068.6017926900767998.6310167479843888.4905985134067368.016810354851694
43.35638631162019243.07824430825411537.1017811942650577.15081690944162433.8662199321346735.0071147309234268.8875726280348658.9101086406804329.1926285110004948.703148712752807
53.67445990905570063.30785456171079467.0835108825364346.74293872220010835.64650614727849435.560979066798128.96876659678068.86338965466051610.0117744847484779.34928640134387
64.2817338545966943.76053297424963257.6681693837963637.55408778631203340.8621733077649540.32038427494287411.19250681133451811.10039607475118814.26523578932706613.71752932524898
74.9494362072367114.6189632369250019.6648685242965469.5373709711329542.3169126196925139.9019764031925213.70585199663943713.86148008799548518.7043435390243918.28556128431616
86.2012600350070145.617860300630443511.7506534423272411.16691713397050444.6192151332629443.977973263082714.004529194608515.52482157235919621.17107365227640519.429740524305636
96.5774806680725715.70321148783578910.181995231055758.78214581127789548.6266503554460845.999596010564214.5628253579501115.43782386336233321.08962580653377518.868546883911172
107.1984012048314315.78553165564609210.3435326407622598.65741574146978958.905315552026954.6751531428053617.5955432245257516.95242385287448522.8901474018451120.254698996139428
117.8642626096943916.49408208710162910.7292186655849349.2374239990965962.56619907575089557.92348070708024519.89948101470644617.87952495752079324.4010554645757519.56871033094505
128.6054670276364936.72622634894277611.87684917399179210.37919355324972267.3080374524974661.0270581605280620.97054962532065819.17865344800587524.874683251695618.68461655147161
139.4359058662701567.58824027146318614.07361917041618112.29001060889990568.2545458017020463.1749414830059222.99581693937121721.60468249809840225.8415346377431819.1520548721402
1410.4713566164952827.920327549029992516.1299504046541813.87604535819854864.9707484908952861.5344118232557422.89498446662761221.5704635040521324.3623730289079719.292915239570004
159.654198357108717.13271584508578515.32367249368690113.37066010481075369.1532029235043162.94651795538024421.1623649307936617.80191357755982325.10635633823561419.096971769737237
168.5597837813720946.28482211022948413.26017008832979411.5039194655339670.0484438276897862.8942115532739819.32976648918124617.63164763318624424.46341790334583518.496417649102433
177.5238539189608895.5347174937775510.1443478076411758.38714669228447565.3189073152269159.55613484476598520.7874446637831617.1650186713769926.42628138300995720.934182056833567
187.7676270581982266.2327019541865298.4611373855193867.20467002077882455.4066539484114652.3330734389234817.9212206948565413.44216910411252528.37023986966845322.43198404765202
1911.4343023754988210.0352195881307748.5030950688241437.5066711847351261.2458700528496956.6450435661668519.57858457805292616.90350414584304825.12341209893414321.365935817806477
208.3407744553471467.18556743536116658.6130918583800937.18360880819994657.0495365226161552.8311751128318832.0992418672704324.80125469430780420.13606105998695716.771334919236967
215.1055924759907394.4608796960697.4766843565769935.51732244024913254.5346109676975250.1420381023702425.9276604288914521.57617191128132517.08012378163907413.793541694964514
224.4609639466416863.70903143375631936.791323595643314.96667016253784655.0133773969419350.38383276650177614.24992689010971611.72702053190027416.519171209191713.222942357264024
234.2747990612275753.56969743238530958.1561051960415336.75846622657128257.07287061642113550.64547859113475410.356994928603628.24178811215414918.72500887147680614.969250670215398
The stress period: the 2022 crisis

What happened in the 2022 crisis window

The protocol's stress period is fold 3, the 2022 crisis. Its peak, delivery 2022-08-15 to 2022-08-31, is the 17 days charted here; their figures are for those days only, not the whole period. The dashed line marks 95% of the window's hours, the nominal target: a computed reference, not an observed count; there is no coverage guarantee.

During the 2022 price peak, a 17-day window inside the crisis period, MAE went from 52.5 to 47.5 EUR/MWh. Descriptive only; the hours inside the interval are in the chart.

The 2022 crisis window: point error and hours inside the 95 percent intervalFour policies on the matched crisis window, delivery 15 to 31 August 2022. Descriptive only.v1Normalized LEAR (study)v2v3MAE, EUR/MWhlower is better050100150200250300275.349.952.547.5Hours inside the 95% intervalcount of hours in the window · closer tothe nominal line is better0100200300400nominal 95%79378377383The 2022 crisis window: point error and hours inside the 95 percent intervalFour policies on the matched crisis window, delivery 15 to 31 August 2022. Descriptive only.MAE, EUR/MWhlower is better050100150200250300v1275.3Normalized LEAR (study)49.9v252.5v347.5Hours inside the 95% intervalcount of hours in the window · closerto the nominal line is better0100200300400nominal 95%v179Normalized LEAR (study)378v2377v3383
View values
RowMAE, EUR/MWh
EUR/MWh
Hours inside the 95% interval
count
v1275.2595429159177379
Normalized LEAR (study)49.876699068332044378
v252.5098015356535377.0
v347.52143732035691383.0
Coverage and interval width

Did the intervals get more reliable, or only wider?

The prediction intervals are narrower in every period, while pooled 95% coverage is slightly lower, 0.9377 against 0.9389 for v2.

Coverage and mean interval width at 50, 80 and 95 percent, pooledFor each nominal level, coverage and mean width for v1, v2 and v3. A black tick marks the nominal coverage. Higher coverage is not better on its own if the intervals widen.Coverage (fraction)closer to nominal is better50% intervalv1 0.3645v2 0.4993v3 0.4937nominal 50%80% intervalv1 0.6281v2 0.7906v3 0.7914nominal 80%95% intervalv1 0.8452v2 0.9389v3 0.9377nominal 95%0.30.40.50.60.70.80.91.0Mean interval width, EUR/MWhnarrower at equal coverage is better50% intervalv1 41.5v2 29.5v3 27.180% intervalv1 75.5v2 65.8v3 58.895% intervalv1 130.9v2 124.6v3 106.2020406080100120140Coverage and mean interval width at 50, 80 and 95 percent, pooledFor each nominal level, coverage and mean width for v1, v2 and v3. A black tick marks the nominal coverage. Higher coverage is not better on its own if the intervals widen.Coverage (fraction)closer to nominal is better50% intervalv1 0.3645v2 0.4993v3 0.4937nominal 50%80% intervalv1 0.6281v2 0.7906v3 0.7914nominal 80%95% intervalv1 0.8452v2 0.9389v3 0.9377nominal 95%0.30.40.50.60.70.80.91.0Mean interval width, EUR/MWhnarrower at equal coverage is better50% intervalv1 41.5v2 29.5v3 27.180% intervalv1 75.5v2 65.8v3 58.895% intervalv1 130.9v2 124.6v3 106.2020406080100120140
View values
Coverage (fraction)
Rowv1v2v3
50% interval0.364473806643714540.49930213082720760.4937191774448683
80% interval0.62808225551316640.79063924816227780.7913836419465897
95% interval0.84516609286312460.93886666046338520.9376570205638783
Mean interval width, EUR/MWh
Rowv1v2v3
50% interval41.5316422429836129.45917771910010427.142760138629214
80% interval75.4690283694348265.7756222081252758.80676873570269
95% interval130.86485779642376124.63573426269241106.24360374406864
Protocol and review

As a diagnostic, v3 is the first policy evaluated against the original criteria to meet all six; v2 misses criteria 1 and 2. This is a development diagnostic, not a product qualification.

Frozen causal controls ran on 2020-07-01 and 2025-05-01: masking the delivery day or the future changed the forecast by exactly zero, an available day-before price change moved it, and future weather changed nothing.

One frozen check could not fail: multiplying all weather by a constant is undone by the training-only scaler. It was kept as an invariance check, and two controls that can fail were added, a shift of the target day's weather and a permutation of the training weather. Both passed (repair r13).

The first independent Integration review within this project's process failed: one frozen input's recorded hash described its bytes with Windows line endings, so the reproduction commands refused to run in a clean checkout. The bytes were restored to the recorded identity (repair r14) and a fresh Integration review passed.

2,476 GFS runs and 123,800 decoded messages; 136.0 GiB transferred; 40.09 machine-hours; external cost $0.

v3 needs one GFS retrieval per delivery day.

The v3 research model's weather data is derived from NCEP GFS 0.25° (NOAA/NWS/NCEP) via NCAR GDEX d084001 (doi:10.5065/D65D8PWK) and NOAA Open Data Dissemination on AWS, modified and aggregated by this project; it is not an official NOAA product.

Adopted in researchSeptember 2026

v2 · blended LEAR, hour-aware intervals

Two LEAR forecasts blended, hour-aware intervals

Development · post-selection

Could a different forecasting model repair v1's failure in the 2022 crisis?

v1 substantially underestimated prices during the 2022 crisis. Recalibrating its intervals improved coverage, but the improvement was insufficient.

v2 combines two LEAR forecasts (LEAR: a regularized linear model fitted for each hour) with intervals that account for the hour of the day. A control uses the same blend with pooled intervals, so the interval methods can be compared.

v1

  • one LightGBM quantile model
  • conformal intervals from a fixed calibration window

v2

  • daily LEAR and normalized LEAR, blended equally
  • intervals from recent errors, by hour of the day

control: the same blend with pooled intervals

v2 lowered both error scores against daily LEAR.

Difference in error score · paired 95% confidence intervals · identical hours · development, post-selection

v2's paired equal-fold error-score differences with 95 percent confidence intervalsThree contrasts in two panels. Against daily LEAR both intervals lie below zero. Against the pooled-interval control the interval-score interval is below zero but the point-error interval ends just above zero.Point-error scoreerror-score difference · below zero favours v2 in the first two rows, the control in the third−0.04−0.03−0.02−0.010.000.01no differencev2 − daily LEAR−0.0137 [−0.0236, −0.0053]v2 − pooled-interval control−0.0017 [−0.0036, +0.0000039]control − daily LEAR−0.0120 [−0.0213, −0.0036]Interval scoreerror-score difference · below zero favours v2 in the first two rows, the control in the third−0.04−0.03−0.02−0.010.000.01no differencev2 − daily LEAR−0.0230 [−0.0337, −0.0118]v2 − pooled-interval control−0.0127 [−0.0156, −0.0109]control − daily LEAR−0.0103 [−0.0201, +0.0007]v2's paired equal-fold error-score differences with 95 percent confidence intervalsThree contrasts in two panels. Against daily LEAR both intervals lie below zero. Against the pooled-interval control the interval-score interval is below zero but the point-error interval ends just above zero.Point-error scoreerror-score difference · below zerofavours v2 in the first two rows, thecontrol in the third−0.04−0.03−0.02−0.010.000.01no differencev2 − daily LEAR−0.0137 [−0.0236, −0.0053]v2 − pooled-interval control−0.0017 [−0.0036, +0.0000039]control − daily LEAR−0.0120 [−0.0213, −0.0036]Interval scoreerror-score difference · below zerofavours v2 in the first two rows, thecontrol in the third−0.04−0.03−0.02−0.010.000.01no differencev2 − daily LEAR−0.0230 [−0.0337, −0.0118]v2 − pooled-interval control−0.0127 [−0.0156, −0.0109]control − daily LEAR−0.0103 [−0.0201, +0.0007]

Against daily LEAR both confidence intervals lie below zero; against its pooled-interval control only the interval score improved, and the point-error interval ends just above zero, at +0.0000039: not equivalence.

View values
RowPoint-error score
normalized score difference
Interval score
normalized score difference
v2 − daily LEAR−0.013738773746104216 [−0.02357190366002046, −0.005344156036269626]−0.022961051241091157 [−0.03369653727283832, −0.011809928240258985]
v2 − pooled-interval control−0.0016954464559965077 [−0.003623724975937509, +0.000003857628092332211]−0.012691783229441422 [−0.015571242603026905, −0.010911902067713655]
control − daily LEAR−0.012043327290107708 [−0.021286980583395003, −0.003556325861059117]−0.010269268011649735 [−0.020060192236757847, +0.000670395231647897]

In September 2026, v2 was adopted in research. v3 was built on it.

Protocol and review

What the pooled-interval control established, and the scores against the targets

Equal-fold error scores at the time of v2, against the targetsSix policies from the v2 study; both v2 arms have the lowest ratios but stay above the targets.v2 · blended LEAR, hour-aware intervalsnot metPooled-interval controlnot metDaily LEAR (benchmark)Normalized LEAR (study)not metDaily LightGBM (benchmark)v1 · released LightGBM (development replay)Targetsboth met?Point-error scoreratio to the naive · lower isbetter0.60.70.80.91.01.1naivetarget0.6440.6460.6580.6720.7841.052Interval scoreratio to the naive · lower isbetter0.60.70.80.91.01.1naivetarget0.6160.6290.6390.6460.7400.986Equal-fold error scores at the time of v2, against the targetsSix policies from the v2 study; both v2 arms have the lowest ratios but stay above the targets.Point-error scoreratio to the naive · lower is better0.60.70.80.91.01.1naivetargetv2 · blended LEAR, hour-aware intervalstargets:not met0.644Pooled-interval controltargets:not met0.646Daily LEAR (benchmark)targets:0.658Normalized LEAR (study)targets:not met0.672Daily LightGBM (benchmark)targets:0.784v1 · released LightGBM (developmentreplay)targets:1.052Interval scoreratio to the naive · lower is better0.60.70.80.91.01.1naivetargetv2 · blended LEAR, hour-aware intervals0.616Pooled-interval control0.629Daily LEAR (benchmark)0.639Normalized LEAR (study)0.646Daily LightGBM (benchmark)0.740v1 · released LightGBM (developmentreplay)0.986

The pooled-interval control against daily LEAR does not meet the rule: its interval-score interval, [−0.0201, +0.0007], spans zero.

Both v2 arms miss criteria 1–2, the point-error and interval-score thresholds, and meet criteria 3–6.

View values
RowPoint-error score
ratio to the similar-day naive (B0)
Interval score
ratio to the similar-day naive (B0)
v2 · blended LEAR, hour-aware intervals0.64407213862868780.6160299894915677
Pooled-interval control0.64576758508468450.6287217727210093
Daily LEAR (benchmark)0.65781091237479210.6389910407326591
Normalized LEAR (study)0.67229081213700330.646015091607363
Daily LightGBM (benchmark)0.78413639776829920.7399052224715813
v1 · released LightGBM (development replay)1.0518451348391990.9856366964174134

ReleasedSeptember 2026

v1 · released LightGBM

Nine-quantile LightGBM with calibrated intervals

A LightGBM ensemble forecasting nine quantiles for every hour, calibrated into 50 / 80 / 95% prediction intervals, and shipped exactly as it was evaluated.

The one-shot holdout Confirmatory-style, not power-qualified

On its pre-specified 90-day holdout, v1 beat the similar-day naive: MAE 25.9 against 27.8 EUR/MWh, and mean pinball loss 6.7 against 13.9 EUR/MWh. A one-sided Diebold–Mariano test on the daily pinball-loss vectors gave p < 10⁻⁶; it tests the probabilistic forecast, not the MAE difference.

Pre-specified one-shot holdout DM test on a fixed 90-day window — confirmatory-style, not power-qualified.

View values
The one-shot holdout, exact values
Measurev1Similar-day naive
MAE, EUR/MWh25.907827.7578
Mean pinball loss, EUR/MWh6.708313.8789
Diebold–Mariano statistic-8.6798
Diebold–Mariano p-value1.98e-18
Coverage at 50 / 80 / 95%0.4407 / 0.7593 / 0.9398

Where it falls short. On the development folds its point error is 28.58% worse than the naive's, pooled over all days (a one-sided test for an improvement gives p = 0.948: no evidence of an advantage). Over the August 2022 peak weeks its 95% interval covered 0.194 of outcomes.

Why: its crisis errors were about price level, not shape. On the crisis window the bias was −269.4 EUR/MWh, and the daily mean-level error was 269.4 EUR/MWh against a within-day shape error of 66.9 EUR/MWh.

The original v1 report (published 2026-09-15), preserved

Archived v1 report, preserved as published. Its container deployment instructions are historical: the current demo runs in your browser, and this report needs no additional requests after loading. Current instructions · Back to the model comparison

DE-LU day-ahead price forecasting

A probabilistic forecast of the next delivery day's hourly German–Luxembourg day-ahead electricity price, with calibrated 50 / 80 / 95 % prediction intervals. Strict-gate by construction: the shipped model uses no input published after the 12:00 CET day-ahead auction gate. Evaluated exactly once, on a holdout pinned before development.

The shipped model is exactly the model the holdout evaluated: there is no retrain and no re-tune after the result was opened.

This page is static. It renders from files committed in the repository and makes no runtime call to any external service — no analytics, no fonts, no CDN, no call to the interactive Space. Everything below, including the chart, works with the network off.

1 · The data2 · Three regimes 3 · Feature catalog3b · Spectral view 4 · Validation design5 · Results 6–7 · Explainability8 · Regime-stratified error 9 · Reliability10 · Next-day forecast 11 · Honest limitations12 · Reproducibility

The four cutoffs, stated separately because they are four different dates
CutoffValue
snapshot_cutoff2026-09-06
raw_model_fit_cutoff2026-04-07
final_calibration_window2026-04-09..2026-06-07
holdout_window2026-06-09..2026-09-06

The raw-model fit cutoff precedes the snapshot cutoff by 152 delivery days (1 + 60 + 1 + 90). That is what shipping the evaluated model costs, stated plainly rather than apologised for; the deployed demo applies a frozen model and there is no scheduled refresh.

1 · The data

One committed Parquet snapshot: 67,343 continuous UTC-indexed hourly rows, delivery 2019-01-01 through 2026-09-06, carrying the day-ahead price (A44), the day-ahead load forecast (A65/A01), the benchmark-only day-ahead VRE forecast (A69) and aggregate actual generation (A75). Quarter-hourly feeds aggregate to hours from exactly four complete bins, never a partial one; the 2025-10-01 switch to a 15-minute price product is handled as the mean of four quarter-hour prices. The snapshot is pinned by SHA-256 7dd2dc73407706ca6bd3c1ad51d201ac0de35eec5ca129ce320cca639f697f00 and ships inside the container, so the demo never pulls a feed while you use it.

Data: ENTSO-E Transparency Platform; Bundesnetzagentur | SMARD.de — CC BY 4.0.

2 · Three regimes in one series

The annual mean price swept from about €30/MWh in 2020 to about €235/MWh in 2022 and back to about €89/MWh in 2025 — a crisis and a normalization inside one training set. Underneath it, the solar build-out pushed negative-price hours from 139 (2021) → 69 (2022) → 301 (2023) → 457 (2024) → 576 (2025).

The 2025 count is measured on this snapshot's hourly series. From 2025-10-01 an hour is the mean of four quarter-hour prices, so any hour-level tally depends on that averaging choice and a quarter-hour tally differs. The price is routinely negative and has touched the −500 €/MWh floor, which is why no log or Box-Cox transform is applied to the target: pinball loss, the CQR score and monotone rearrangement are all location-equivariant and behave correctly through zero.

Two consequences the whole design follows from. Evaluation is stratified across all three regimes rather than collapsed into a recent tail. And exchangeability — the assumption CQR's coverage guarantee rests on — is mildly violated by construction, which is disclosed rather than assumed away.

3 · Feature catalog — frozen before fitting

Two catalogs were frozen before any model ran. base: calendar and regime features, the A65 load forecast, calendar-day-matched price lags at D−1 / D−2 / D−7, and D-1-frozen rolling price statistics. base + residual_load_proxy adds exactly one domain feature — a residual-load proxy built from a 42-complete-delivery-day trailing mean of actual wind and solar generation ending at D−2, which clears the 12:00 gate with a wide margin.

Pooled observation-weighted raw-head mean pinball loss over the five pinned development folds, matched on rows, seed, hyperparameters and (zero) tuning budget, unrounded as stored:

ArmPooled raw-head mean pinball loss
base13.015841509664993
base + residual_load_proxy13.064197422052183

Percentage difference (augmented vs base): +0.371516%. Selected catalog: base. The rule was fixed before fitting — the augmented catalog ships only if its unrounded stored pooled loss is lower. It is not, so the domain feature did not earn its place and the champion ships strict-gate. That is a reportable result, not a failure, and the comparison was designed so that "no improvement" was a publishable answer.

3b · Why these seasonal features? (spectral view)

Welch periodogram of the detrended DE-LU day-ahead price, with 24h, 168h and 12h labels
Welch periodogram — Hann window, 50 % overlap.
Per-regime Welch periodogram overlay for pre-crisis, crisis and normalization
Per-regime overlay.
Autocorrelation of the detrended price with 24h and 168h reference lines
ACF cross-check, time domain.

The Welch periodogram shows pronounced price energy at the 24-hour and 168-hour cycles with a visible 12-hour harmonic, which is what justifies the catalog's hour-of-day and day-of-week structure rather than an assumption that electricity "should" be daily-seasonal. The per-regime overlay shows an elevated broadband floor and altered seasonal amplitude during the crisis: the spectrum itself is not stationary across regimes, which supports reporting performance across all three rather than collapsing them into one recent-tail summary. The ACF cross-check confirms the same daily and weekly recurrence in the time domain, so the conclusion does not rest on a single estimator. These are price diagnostics only — they neither validate nor justify retaining residual_load_proxy, which the frozen two-arm comparison alone decides.

4 · Validation design

Expanding-window walk-forward CV with five development folds, each carrying a one-complete-delivery-day embargo — 23, 24 or 25 rows as DST requires, never hard-coded to 24 — and a 90-day evaluation block, anchored so the blocks span pre-crisis, the crisis peak and the post-crisis negative-price era. Five tail partitions were pinned before any EDA: fold 5, Embargo A, a 60-day final-calibration slice, Embargo B, and the final 90-day holdout.

The target is D+1, anchored at the 12:00 CET gate, because that is what the day-ahead auction clears. That makes the availability rule stricter than it first looks: the model emits the whole next-day curve at once, so a row-wise t−1 boundary would admit the target curve into its own features. The binding rule is per delivery day — for a forecast of day D, every price-derived feature may consume only prices whose delivery date is earlier than D, rolling statistics are frozen at the D−1 boundary for the whole curve, and an unavailable or ambiguous calendar-day match fails closed to null rather than reaching for a same-day price.

Strict gate. The day-ahead wind and solar forecast (A69) is not published until after the 12:00 gate, so rather than use it as-archived and disclose that, this project excludes it from the shipped model entirely. Delivery-day A69 is rejected by the champion's runtime schema. What the exclusion costs is then measured, in section 5, instead of being waved at.

Two disclosed assumptions, stated as assumptions rather than as measurements:

  • A65/A01 is pre-gate by explicit assumption, not by measurement: both the existence of the delivery-day load forecast before the 12:00 CET gate and its equality to the archived vector used here are assumed, and the regulatory update provision permits later revisions.
  • A75 aggregate actual generation is used at its current archived values, which may differ from the values visible in real time despite the D-2 boundary.

5 · Results

Development folds — descriptive post-selection evidence

evidence_class = development_post_selection. These folds were also used for catalog selection and model development, so their p-values are descriptive, never confirmatory, and no result gates anything.

AnalysisComparatorStatisticp-valueN days
Probabilistic daily-vector pinballsimilar-day naive-2.55170.00536448
Point median absolute errorsimilar-day naive1.62280.948448

The point-accuracy test does not merely fail to show an advantage — it shows a deficit. The test is one-sided (reject if DM < −1.645) and the statistic is +1.6228, p = 0.948: the champion's median is 28.58% worse against the naive over the development folds. Reported here rather than omitted or reframed. The probabilistic win is broad and the point-accuracy win is not: the pooled MAE gap comes almost entirely from the crisis-peak fold. The mechanism is measured, not assumed: the model did see the crisis (that fold's training included 5,784 crisis hours at a €173 mean and a €700 maximum), but 61.3% of the evaluation block sits above the 99th percentile of everything it ever saw while only 2.45% exceeds its maximum — shrinkage toward the training level, not an extrapolation wall. Persistence has no training distribution and carries the level for free. Note also that a point forecast scored on pinball is structurally disadvantaged against a nine-quantile model, so the pinball margin is largely the value of having a predictive distribution.

modelstagen_obsmae_p50mean_pinballcrossing_violationscoverage_50coverage_80coverage_95
baseraw1074741.7613.02101580.22570.43220.6705
basepost_cqr1074741.7611.4644120.36420.6280.8416
basefinal1074741.7411.4400.36450.62810.8452
base_plus_residual_load_proxyraw1074741.1713.06105630.20040.40560.6568
base_plus_residual_load_proxypost_cqr1074741.1711.5738990.31510.59490.8377
base_plus_residual_load_proxyfinal1074740.9411.5500.3180.59410.8401
similar_day_naivepoint1074732.4516.230
seasonal_naive_168hpoint1074737.6318.810
ridgepoint1074728.1114.050
The one-shot holdout — opened exactly once

After the catalog, hyperparameters and every implementation choice were frozen, the nine raw heads were fit on every eligible row strictly before Embargo A, the four CQR thresholds were estimated once on the 60-day calibration slice, isotonic-last was attached, and that complete artifact was frozen. Only then was the holdout opened.

MetricChampionSimilar-day naiveDifference
MAE (EUR/MWh)25.907827.7578-6.66%
Mean pinball loss6.708313.8789-51.67%

Final empirical coverage over 2,160 rows on 90 delivery days: 0.4407 / 0.7593 / 0.9398 at the 50 / 80 / 95 % nominal levels. Probabilistic daily-vector Diebold–Mariano against the similar-day naive: statistic -8.6798, p-value 1.98e-18, standardized effect size -1.0478.

Pre-specified one-shot holdout DM test on a fixed 90-day window — confirmatory-style, not power-qualified.

The result supports a probabilistic-skill claim against the similar-day naive on this window and nothing wider. It is not a gate, and no superiority claim beyond what it supports is made anywhere on this page.

What the post-gate forecast would have been worth

A controlled ablation on raw quantile heads, neither arm calibrated, identical in every respect except the added delivery-day A69 forecast and its named derivatives: pooled mean pinball loss moves from 13.015841509664993 to 10.478714632475889 — -19.4926%. So the project ships an honest model and puts a number on the value of the information it chose not to use.

This uncalibrated raw-head comparison isolates the information content of post-gate A69. It makes no claim about calibrated interval quality and does not make A69 available at the forecast gate.

6–7 · Explainability

SHAP summary plot for the p50 head of the champion catalog
SHAP summary, p50 head, scored out of sample on fold 5's evaluation block.
SHAP dependence plot for price_lag_24h
price_lag_24h
SHAP dependence plot for price_lag_168h
price_lag_168h
Top 10 by mean |SHAP|
featuremean_abs_shaprank
price_lag_24h15.41
price_lag_168h5.4132
price_roll_q50_168h5.1263
day_of_week4.514
price_lag_48h4.2065
load_forecast_mw3.236
day_type3.1647
local_hour3.0648
price_roll_mean_720h2.9849
price_roll_q95_168h2.71910
Top 10 by permutation importance
featureimportance_mean_mae_increaseimportance_stdrank
price_lag_24h8.2610.30251
price_lag_48h1.8030.14632
day_of_week1.4440.15783
local_hour1.1290.091774
price_lag_168h1.0970.084315
load_forecast_day_mean_mw0.41050.076286
load_forecast_mw0.38560.074167
day_type0.33650.065518
price_roll_std_720h0.18860.041929
price_roll_q50_168h0.15110.0502710

SHAP on the p50 head explains central tendency, not interval width — width is driven by the inter-quantile spread and the CQR shift. Neither ranking is the incremental-value test; that is the frozen two-arm comparison in section 3, which selected base. The two rankings agree at the top and disagree in the middle, which is the ordinary difference between attribution in expectation and degradation under shuffling.

8 · Regime-stratified error

n_obs on every row. Thin subsets carry day-block bootstrap 95 % confidence intervals — days, not hours, because the rows of one delivery day share a day effect — and are read qualitatively.

stratumn_obsn_daysmaemean_pinballcoverage_50coverage_80coverage_95readmae_ci95_lowmae_ci95_highpinball_ci95_lowpinball_ci95_high
all validation folds1074744841.7411.440.36450.62810.8452quantitative
Dunkelflaute days (A69 stratum)6482738.6310.490.25770.49380.7716qualitative (thin subset)19.961.385.03617.11
non-flag days1009942141.9411.510.37130.63670.8499quantitative
pre-crisis (< 2021-09-01)431918013.323.3480.31370.59130.8889quantitative
crisis (2021-09-01 .. 2022-12-31)21128814139.980.20880.35270.5554qualitative (thin subset)123.1160.433.6246.78
post-crisis (>= 2023-01-01)431618021.625.5860.49140.79960.9432quantitative
negative-price hours4658539.0311.210.20220.43230.7097qualitative (thin subset)33.0244.899.00813.44
weekday763031843.3711.880.35410.60710.833quantitative
weekend311713037.7510.390.38980.67950.8749quantitative
August-2022 peak weeks40817275.387.950.019610.066180.1936qualitative (thin subset)236.8316.771.04106
Dec-2024 Dunkelflaute week (backtest, fold-3 model, raw heads, 2.5y stale)168775.2425.790.27380.51790.6667qualitative (backtest outside every eval block; raw heads, uncalibrated)43.511010.3445.67

Coverage collapses on the crisis stratum and on negative-price hours. The bounded target truncates the lower conformity residuals near the floor, so the lowest intervals under-cover conditionally. This is disclosed rather than engineered around: a floor-aware tail would reopen scope this project deliberately closed.

9 · Reliability — three stages

Three-stage reliability diagram: raw LightGBM, post-CQR, and final post-isotonic
Raw heads → CQR → isotonic last, at all three nominal levels.
stagenominalempirical
raw LightGBM0.50.2257
raw LightGBM0.80.4322
raw LightGBM0.950.6705
post-CQR / pre-isotonic0.50.3642
post-CQR / pre-isotonic0.80.628
post-CQR / pre-isotonic0.950.8416
final post-isotonic0.50.3645
final post-isotonic0.80.6281
final post-isotonic0.950.8452

The finite-sample, distribution-free per-interval marginal guarantee attaches to the post-CQR / pre-isotonic output only. Isotonic is a monotone rearrangement applied last; whenever it moves an endpoint it perturbs the interval, so the final output's coverage is reported as empirical. No joint or simultaneous coverage across the four intervals is claimed.

The one retained hard gate is a correctness property, not a favourable number: zero quantile-crossing violations after the full pipeline. On the selected base catalog's development evaluation rows, the raw heads cross on 10,158 adjacent pairs and still cross on 4,412 after CQR; after isotonic the count is 0, and 0 on the holdout. That CQR alone leaves thousands of crossings is exactly why isotonic is unconditionally last.

CQR provides finite-sample marginal coverage guarantees under exchangeability. The walk-forward CV mildly violates exchangeability — the crisis regime is not exchangeable with the pre-crisis regime, and the solar-driven negative-price era is not exchangeable with either — so empirical coverage may diverge from nominal on regime-shift folds. This is documented in the reliability diagram (Section 8.4).

10 · Next-day forecast

Archived v1 report. The replay below runs in this page; the current interactive demo runs in your browser, and the container instructions later in this report are historical.

Historical out-of-sample replay — the frozen champion forecasting a 90-day period it never trained on. This is not a live forecast. The delivery day below, 2026-09-06, falls inside the pinned holdout window 2026-06-09..2026-09-06. The dashed line is the price that actually cleared — an outcome, never a model input.

Prediction-interval level
Load-forecast scenario × 1.00

—— median forecast   ▇ selected interval   – – cleared price (outcome)

Nominal level selected above; the frozen champion's own empirical coverage at that level over the 90-day holdout was 0.7593.

Want to drive the model yourself? The interactive demo — runs in your browser; the first visit downloads about 57 MB runs the champion's own boosters in your browser, proved bitwise equal to the frozen artifact over 54 delivery days. This page stays the first touch because it downloads nothing and cannot fail when a CDN does.

11 · Honest limitations

  • Exchangeability under regime shift. CQR provides finite-sample marginal coverage guarantees under exchangeability. The walk-forward CV mildly violates exchangeability — the crisis regime is not exchangeable with the pre-crisis regime, and the solar-driven negative-price era is not exchangeable with either — so empirical coverage may diverge from nominal on regime-shift folds. This is documented in the reliability diagram (Section 8.4).
  • Development versus one-shot evidence. The five-fold development results are descriptive post-selection evidence, never confirmatory: those folds also chose the catalog. Only the 90-day holdout was pre-specified and opened once, and on the development folds the point-accuracy DM shows a deficit, not merely the absence of an advantage.
  • Disclosed assumption — the load forecast. A65/A01 is pre-gate by explicit assumption, not by measurement: both the existence of the delivery-day load forecast before the 12:00 CET gate and its equality to the archived vector used here are assumed, and the regulatory update provision permits later revisions.
  • Disclosed assumption — the generation archive. A75 aggregate actual generation is used at its current archived values, which may differ from the values visible in real time despite the D-2 boundary.
  • The measured cost of the strict gate. The strict-gate design has a measured cost rather than an assumed one: the post-gate A69 forecast is worth 19.4926% of pooled raw-head pinball loss, and the project declines to use it.
  • A two-sided bounded target, live at the floor. The target is two-sided and bounded: the price is routinely negative and has hit the −500 EUR/MWh floor, which truncates the lower conformity residuals, so the lowest intervals under-cover conditionally near the floor.
  • Coverage divergence. Empirical coverage diverges from nominal: 0.4407 / 0.7593 / 0.9398 against 50 / 80 / 95 %, so the 50 % interval under-covers by roughly six points on the holdout window. On the crisis stratum it does not merely diverge, it collapses: over the August-2022 peak weeks the 95 % interval covered 0.194 of outcomes. The mechanism is measured — that fold's CQR thresholds were estimated on a May-June 2022 calibration window at a ~198 EUR/MWh level and applied to an evaluation block averaging 376 EUR/MWh, and the conformal correction is additive, not multiplicative. This is what a split-conformal guarantee does when exchangeability breaks; it is the defect later generations address (see the v2 and v3 chapters), and it is not fixed in the released v1.
  • Model staleness, with all four cutoffs. The deployed demo applies a frozen model whose raw-model fit cutoff (2026-04-07) precedes the snapshot cutoff (2026-09-06) by 152 delivery days, with the final calibration window 2026-04-09..2026-06-07 and the holdout window 2026-06-09..2026-09-06 — all four cutoffs published separately because they are four different dates.
  • The 15-minute MTU averaging choice. From 2025-10-01 an hourly price is the mean of four quarter-hour prices, so every hour-level statistic here — the negative-hour tally included — depends on that averaging choice, and a quarter-hour tally differs.
  • Scope. This is a portfolio artifact, not an operations system: no retraining schedule, no drift gate, no rollback machinery, no monitoring surface, and no multi-day-ahead forecast.

The day-ahead price floor moved to −600 EUR/MWh from 2026-05-28, an environment shift the frozen model predates.

The holdout is a single contiguous recent period, so it tests generalization to the most recent regime rather than repeated out-of-sample skill. Its partitions were pinned before development and it was evaluated once, after the complete model and calibration pipeline were frozen, with no subsequent tuning. The 90-day length was fixed by partition design, not by a power calculation, so the Diebold–Mariano result is confirmatory-style but not power-qualified. The model shown is exactly the model evaluated — no refit followed the holdout — so its raw-model fit cutoff precedes the snapshot cutoff by 152 delivery days. Sequential lag features may use earlier holdout observations exactly as they would in live forecasting; no holdout outcome entered fitting or a development decision. Enforcement is procedural: this is a solo build and the discipline is disclosed, not cryptographically guaranteed.

12 · Reproducibility

Three public surfaces, all live. Each answers a different question and each stands on its own. This page is the one that needs no network.

SurfaceAnswersCost to open
📄 Static report — you are here
https://hrsi56.github.io/delu-day-ahead-forecast/
Can they reason, and will they say what went wrong? zero network calls
⚡ Interactive Space
the Space · the app directly
Does the thing actually run? The champion's own boosters execute in your browser under Pyodide — no server. ~57 MB first visit, ~1 MB after. A Static Space executes nothing, so it never sleeps.
🔬 MLflow on DagsHub
the tracking server
Is the decision trail real, or is this page the only evidence? anonymous, no sign-in

The decision trail, addressed directly. Every link here was checked from an unauthenticated client. The DagsHub repository UI redirects an anonymous visitor to a sign-in page; the .mlflow tracking host does not, which is why every link uses it.

Runs are named rather than linked by id, because several decision-bearing runs were reproduced and no single id is canonical — the name is what to search for:

Run nameWhat it decided
catalog::basethe selected catalog's development arm
catalog::base_plus_residual_load_proxythe domain-feature arm that lost, by +0.371516%
baseline::similar_day_naivethe headline comparator
baseline::seasonal_naive_168hthe second baseline
baseline::ridgethe third baseline
benchmark::basethe strict-gate arm of the §7.2 benchmark
benchmark::base+a69the post-gate arm -- what the unavailable forecast is worth
champion::final-fit-and-holdoutthe frozen champion and the one-shot holdout
diagnostics::championSHAP, permutation importance, regimes, reliability

Tracking after v1. Research after v1 will be tracked in a separate `delu-generations` experiment on the same tracking server: every policy evaluated since v1 will appear there once, mirrored from the committed evidence, so v1's record stays exactly as the one-shot holdout left it and the two are never mixed in one experiment. See how it evolved.

artifact_fingerprint_sha256
57e3ad40a7f48bb7896628ce2e5dec61314dea567da9867aede4bf1b0a10e0fb
snapshot_sha256
7dd2dc73407706ca6bd3c1ad51d201ac0de35eec5ca129ce320cca639f697f00
catalog
base, 25 features, 9 quantile heads, four CQR thresholds, isotonic last
fit / calibration rows
62,688 raw-fit rows, 1,440 calibration rows
artifact size
python_model.pkl 30,830,306 bytes = 29.4 MiB (30.8 MB); the whole models/champion/ directory 31,623,247 bytes = 30.2 MiB
compute
Apple M3, 16 GB, CPU only, no GPU, $0 run rate

The pickle's bytes are deliberately not the identity to check: MLflow stamps a fresh UUID and creation time into MLmodel on every save and cloudpickle is not byte-reproducible, so models/champion/ changes while the model does not. The fingerprint is computed over the catalog, the feature list, the nine quantiles, the four thresholds and the nine boosters' own serializations.

  • Tagged commit. Check out the tagged commit and run uv sync then make train: the champion is rebuilt from the committed snapshot with pinned dependencies and fixed seeds, no extra fetch.
  • MLflow permalinks. Every decision-bearing run — the three baselines, both catalog candidates, both benchmark arms, the champion's final fit and holdout, and the diagnostics — is public at https://dagshub.com/hrsi56/delu-day-ahead-forecast.mlflow with snapshot hash, code SHA, fold spec, feature list, seed, hyperparameters, metrics and artifact links. Counting runs there will not give you 'one', and it is not meant to: the tracking server shows several runs named champion::final-fit-and-holdout, because the script is deterministic and was re-run while CP-2 was authored — once aborted on the runtime firewall before any outcome was read, and every completed run reproducing the previous run's metrics and artifact fingerprint exactly. “Evaluated exactly once” is a statement about the evaluation decision, not about how many times a deterministic script may be executed — an Integration Critic re-running it from a clean worktree is reproducing the result, not taking a second look at the holdout. No catalog, hyperparameter, threshold or analysis choice was changed after any of them.
  • The registered champion alias. The champion is registered on that MLflow instance as the model delu-day-ahead-champion under the champion alias, carrying release and lineage tags — release_status=portfolio_release, the source run id, the code commit, the snapshot hash and the four cutoffs. It is portfolio evidence only: the deployed demo loads the bundled artifact and never queries the registry.
  • Canonical entry point. The static GitHub Pages report at https://hrsi56.github.io/delu-day-ahead-forecast/ is the canonical entry point, and the interactive Space at https://huggingface.co/spaces/Yarden-Viktor/delu-day-ahead-forecast is linked from it.
  • DuckDB SQL. The hand-authored DuckDB queries in sql/feature_queries.sql express the same calendar-day lag and D-1-frozen rolling semantics as the canonical Python pipeline, and run against the committed Parquet with make sql.
  • The four cutoffs. All four cutoffs are published separately: snapshot 2026-09-06, raw-model fit 2026-04-07, final calibration 2026-04-09..2026-06-07, holdout 2026-06-09..2026-09-06.
  • Attribution. Data: ENTSO-E Transparency Platform; Bundesnetzagentur | SMARD.de — CC BY 4.0. Code MIT; the redistributed data stays CC BY 4.0 with attribution, and the trained champion is a derived work of it. The v3 research model's weather data is derived from NCEP GFS 0.25° (NOAA/NWS/NCEP) via NCAR GDEX d084001 (doi:10.5065/D65D8PWK) and NOAA Open Data Dissemination on AWS, modified and aggregated by this project; it is not an official NOAA product. See LICENSE and DATA-LICENSE.md.
  • Run it yourself. Clone https://github.com/hrsi56/delu-day-ahead-forecast, then uv sync, then uv run python predict_next_day.py --level 80 --self-check forecasts a delivery day offline from the bundled snapshot and re-proves the gate boundary as it goes; make test runs the invariant suite including the CQR order-statistic fixture; make sql runs the DuckDB queries; and docker build -t delu-showcase . && docker run -p 7860:7860 delu-showcase builds and serves the same image the Space runs, champion and snapshot bundled inside it.
  • Compute. Apple M3, 16 GB, CPU only, no GPU, $0 run rate; the whole pipeline — development, benchmark, final fit and diagnostics — runs in well under an hour.

Back to the model comparison · Back to v1

Planned, not evaluated

Next: a re-evaluation on every eligible day, new input data, renewable-generation forecasts and model combinations, then an evaluation of the selected model under a frozen protocol and prospective monitoring.

See planned experiments

Each item is subject to the research plan, where its conditions are set out, and would be compared with v5 on the same days (the plan).

  1. A re-evaluation on every eligible day

    Question it will test
    How do the adopted generations perform when every eligible day is scored, not only the five historical test periods?
    Evidence that would decide it
    An evaluation protocol fixed before any result, then every generation scored on all eligible days, with the five test periods kept as the historical record
    Work item
    Re-evaluation
  2. New input data

    Question it will test
    Do fuel and carbon prices, neighbouring markets, or earlier forecasts that already cover the delivery day add information to v5?
    Evidence that would decide it
    A provenance, licence and availability check for each source, then one predefined comparison with and without it
    Work item
    New data
  3. Wind and solar generation forecasts

    Question it will test
    Does a wind and solar generation forecast add information beyond direct weather?
    Evidence that would decide it
    A generation forecast available before the auction, then an ablation
    Work item
    4.4V · VRE
  4. Combining models

    Question it will test
    Does combining adopted models help?
    Evidence that would decide it
    A predefined combination test
    Work item
    4.8 · Recombination
  5. Frozen-protocol evaluation, then prospective monitoring

    Question it will test
    How does the selected model perform under a frozen evaluation protocol, and then prospectively?
    Evidence that would decide it
    An evaluation window and an evidence classification, both fixed in the protocol before the test
    Work item
    4.7T and live · Final evaluation

How the system works, and how to check it

How the system works

  1. Source data and vintagesENTSO-E and SMARD prices and load forecasts; from v3, the GFS run of the day before
  2. Information cutoffForecast-cutoff checks; source-availability assumptions documented
  3. FeaturesCalendar, price lags, load forecast; weather from v3
  4. Model and interval policyv1: LightGBM quantiles, conformal calibration; v2 and v3: blended LEAR, hour-aware intervals; v4: that blend plus a three-block LightGBM; v5: v4 plus a distributional neural network written in NumPy
  5. Evaluation and artifactsFive historical periods, identical hours; committed predictions, metrics and reviews
  6. Report, demo and trackingThis page, the in-browser v1 demo and the MLflow mirror
  7. Live operation · plannedDaily forecasts scored after the fact

Built with Python, entsoe-py, pandas, NumPy, DuckDB, LightGBM, scikit-learn, Parquet, GitHub Actions, GitHub Pages, marimo, Pyodide, Hugging Face Static Space and MLflow on DagsHub.

Checked in code: controls that fail when a feature crosses the forecast cutoff. Assumed and documented: each source's historical availability (the availability assumptions). Dashed outlines mark planned parts.

Rebuild the report from saved evidence

Rebuild the presentation from committed evidence, without fitting models or downloading source data. Install the pinned dependencies once (this downloads packages), then rebuild:

uv sync
uv run python scripts/rebuild_presentation.py
One measured rebuild

Measured once on 2026-09-25: 9.6 s on the build machine (Darwin arm64, Python 3.13.15), from the release-check record reports/presentation/release-checks/2026-09-25-rebuild.json. It is one measurement, not a benchmark of every revision.

Each experiment below has its own full reproduction. To run the released model, see Run this product; v1's original instructions, with the historical container, are in its archive.

Tracking

Every policy evaluated since v1 is in the MLflow experiment delu-generations, mirrored from the repository's committed evidence; the repository is the source of truth, and this page works without the tracking service.

Experiment delu-cp2 holds v1's own runs. Code and evidence on GitHub

Contribution

I led the project's problem definition, evaluation criteria and research direction, and made the decisions on model adoption and product presentation. AI agents assisted with implementation, analysis and documentation. Automated tests and reviews separate from implementation supported verification. I retained responsibility for approving deliverables and publication.

Yarden Viktor Dejorno

Terms and attribution

Data: ENTSO-E Transparency Platform; Bundesnetzagentur | SMARD.de — CC BY 4.0.

Code MIT; the redistributed data stays CC BY 4.0 with attribution, and the trained champion is a derived work of it. The v3 research model's weather data is derived from NCEP GFS 0.25° (NOAA/NWS/NCEP) via NCAR GDEX d084001 (doi:10.5065/D65D8PWK) and NOAA Open Data Dissemination on AWS, modified and aggregated by this project; it is not an official NOAA product. See LICENSE and DATA-LICENSE.md.

Scroll to see the whole figure.