Average price Tue 20 Oct (Ensemble)
178€/MWh
−29 vs Mon 19 Oct
Cheapest / most expensive hour
12:00 / 18:00
129 / 242 €/MWh
Chance of a negative price
<5%
below 5% in every hour
Live accuracy vs naive
−53%
Ensemble vs the weekly naive, MAE over 6 live days since 13 Oct
Forecast for the next delivery day, with recent actual prices (EUR/MWh)
Days tracked
6
since 13 Oct 2026
Ensemble error (MAE)
23
€/MWh, last 30 days
Naive error (MAE)
50
€/MWh, last 30 days
Ensemble 90% range, live
89.6%
of hours in the 90% range, 6 live days
Live forecasts vs actual prices, last 30 days (EUR/MWh)
Accuracy by model, last 30 days
Model Days tracked MAE (€/MWh) RMSE (€/MWh)
BMT-X 6 20.3 24.5
Ensemble 6 23.2 27.7
LEAR-X 6 23.2 27.8
XGBoost-X 6 29.1 36.9
Naive 6 49.6 66.0

Every forecast here was saved before the auction and never changed.

Expected battery revenue Tue 20 Oct
207€
planned with the ensemble before the auction
Revenue at risk (95% VaR)
133€
1 day in 20 earns less than 74 €
Expected shortfall (95%)
181€
average shortfall on those days
Days below the floor, live
0 of 6
target 1 day in 20
Live days: battery revenue and its 95% floor (€)
Day Planned Expected 95% floor Revenue Below the floor
Mon 19 Oct 2026 184 207 83 153
Sun 18 Oct 2026 138 172 23 77
Sat 17 Oct 2026 137 174 12 64
Thu 15 Oct 2026 156 191 37 238
Wed 14 Oct 2026 281 316 156 320
Tue 13 Oct 2026 65 89 −45 59
How it works

The plan is fixed before the auction, so the risk is the forecast errors in the hours it trades. Past days’ 24-hour errors, scaled by recent volatility (EWMA), are run through tomorrow’s plan.

VaR: how far below expected the worst day in 20 falls. ES: the average shortfall on those days.

Challengers: tested live before they can replace the ensemble
Challenger Live days Live MAE Live p Status
Bias-corrected 5 24.7 → 16.7 <0.001 running

MAE: ensemble → challenger, €/MWh. Saved every day next to the ensemble, but not shown. On 1 March 2027 it replaces the ensemble only if its live MAE is lower with p < 0.05 (Diebold-Mariano, Newey-West). Rule set before the first live day.

How it works

Forecast. Tomorrow’s hourly prices (the average of the four quarter-hours), made at about 10:15 the day before and never changed.

Models. Four forecasts are made every morning and compared: BMT-X (boosting with multiple testing, from my thesis), LEAR-X (a lasso per hour), XGBoost-X, and the ensemble, their average, which is the headline forecast. Benchmark: the weekly naive. Re-estimated every day on the last two years.

Inputs. Only data published before the noon auction. The list is in inputs.csv, and the dashboard won’t build if the forecast uses anything else.

Input Source Published
DK1 prices from D-1, D-2, D-3 and D-7 Energi Data Service the day before each day at about 13:00
Neighbour prices from D-1 (DE, DK2, NO2, SE3, SE4) Energi Data Service D-2 at about 13:00
Danish holidays calendar known in advance
Weather forecast for DK1 (wind at 100 m, solar radiation), made 48 hours ahead Open-Meteo 48 hours before each hour
Weather forecast for Germany (wind at 100 m, solar radiation), made 48 hours ahead Open-Meteo 48 hours before each hour

Tried and dropped: Energinet wind and solar forecasts (published too late); ENTSO-E load forecasts for DK1 and Germany (no gain, p = 0.71).

Hindsight is kept apart. Data published after the auction (actual generation, load, flows) is only used in the analysis folder, to understand prices and errors. It is never a forecast input.

Ranges. 5–95% quantiles from each model’s recent errors. The chance of a negative price comes from the same quantiles.

Challengers. Changes run live next to the ensemble and only replace it if they win on a rule set in advance.

Data: Energi Data Service (Energinet).
Code: github.com/jacobazu/dk1-price-forecasting
Last updated: 19 October 2026, 10:18 (Danish time)