Augur

Wholesale electricity price forecasting for the Netherlands

All data includes random noise for educational purposes. Consumer prices include additional taxes and grid fees.

Loading energy price data...

Offshore Wind Speed (10-day)

Solar Irradiance (7-day)

Temperature & Wind (10-day)

Cloud Cover & Humidity

System Imbalance (yesterday)

Cross-border Flows (yesterday)

Load Forecast vs Actual (today+tomorrow)

NL Renewable Production — Forecast vs Actual (NED)

French Nuclear Generation (ENTSO-E)

Loading market data...

Architecture

energyDataHub
18+ APIs, daily 16:00 UTC
Feature Builder
26 features: lags, rolling stats, calendar, wind, solar, load
ARF Regressor
10-tree adaptive forest, continuous learning via River
48h Forecast
Price + 80% confidence band, updated daily

Model Card

--
vs Exchange MAE
EUR/MWh — lower is better
--
Overall MAE
EUR/MWh on actuals
--
Training Samples
hours learned
48h
Forecast Horizon
29h exchange + 19h ML-only

Model Performance

Live convergence tracking. These charts update daily as the model learns from new price observations.

MAE Over Time

Error Distribution (last 500 predictions)

MAE by Hour of Day

Feature Analysis

Feature importance changes dramatically with forecast horizon. At 1h, recent price momentum dominates (R²=0.81). At 48h, only weekly patterns and load forecast survive (R²=0.21).

Feature Importance by Forecast Horizon (Lasso L1)

Correlation Matrix

Data Patterns

Average NL electricity price by hour shows the daily demand cycle. Wind speed scatter reveals the nonlinear wind-price relationship.

Daily Price Profile (6 months avg)

Offshore Wind vs Price

Strategy: Learning to Match the Market

The Convergence Experiment

Day-ahead electricity prices are set by exchanges (EPEX, ENTSO-E) around 13:00 CET, based on aggregated buy/sell bids from hundreds of market participants. Our model predicts these same prices using only publicly available data: weather forecasts, historical prices, and grid conditions.

The key question: how close can an ML model get to the market consensus, and how fast?

We measure this as "vs Exchange MAE" — the average difference between our prediction and the published exchange price for the same hour. This number should decrease over time as the model learns from more data and seasonal patterns.

Hybrid Forecast Strategy

For the first ~29 hours, exchange day-ahead prices are already published. We use these as lag features — giving the model perfect recent price information to predict further out.

For hours 30-48, beyond the exchange horizon, the model relies on its own predictions recursively plus weather/wind forecasts. The confidence band widens here to reflect the increased uncertainty.

Expected Convergence

Now: ~16 EUR/MWh vs exchange (6 months of training data)

1-3 months: ~8-12 EUR/MWh (spring/summer transition learned)

6-12 months: ~5-8 EUR/MWh (full seasonal cycle observed)

The floor is likely ~5 EUR/MWh — intraday surprises (plant outages, interconnector trips) and private market information are fundamentally unpredictable from public data alone.

How It Works

Continuous Learning

The model uses River's Adaptive Random Forest (ARF) — an ensemble of 10 Hoeffding trees that adapt to concept drift. Each day, new price observations arrive and the model updates incrementally via predict_one() then learn_one(). It never retrains from scratch.

Confidence Bands

The 80% confidence interval is computed empirically from the last 500 prediction errors. The band widens linearly over the forecast horizon to reflect increasing uncertainty. Prices below 0 are clamped.

Data Pipeline

energyDataHub collects from 18+ APIs daily at 16:00 UTC. A cron job on sadalsuud pulls the data, updates the model, generates the forecast, and pushes to GitHub — triggering a Netlify rebuild. The full cycle takes under 30 seconds.

Target Variable

We predict ENTSO-E NL wholesale day-ahead prices (EUR/MWh). Consumer prices (e.g., EnergyZero) include taxes and grid fees that add a roughly constant markup — the price shape (when cheap vs expensive) is driven entirely by the wholesale market.

Feature Decisions

What data we use, what we don't, and why.

Used: Price Lags & Rolling Stats

Autoregressive features (lag 1h-168h, rolling mean/std 6h-168h) are the dominant predictors at all horizons. The 6h rolling mean is the single best feature for 1h-ahead; the 168h lag captures weekly seasonality for 24-48h ahead.

Used: Wind Speed (Gemini NL, 80m)

Offshore wind speed from Open-Meteo at the Gemini wind farm. Only one of 4 NL farms and one height is used — adding more locations adds noise without improving prediction, because NL offshore wind is highly correlated across farms. Raw correlation with price is low (r=0.01) because the effect is nonlinear: wind suppresses prices only above ~12 m/s.

Used: Solar GHI (Eindhoven NL)

Global Horizontal Irradiance from Open-Meteo. One NL location is representative — solar irradiance varies little across the Netherlands. Matters most at the 6h horizon where daytime solar surplus creates negative/zero prices.

Used: Load Forecast (ENTSO-E NL)

TSO demand forecast. The most stable exogenous predictor across all horizons — high demand means high prices regardless of supply mix.

Dropped: Temperature

Lasso assigns zero weight. Temperature affects prices indirectly through heating/cooling demand, but this signal is already captured by the load forecast and calendar features.

Not Used: Gas/Carbon Prices

Gas TTF and carbon EUA prices from Alpha Vantage are single daily snapshots with no intraday variation. They set the long-term price floor (marginal cost of gas plants) but don't help predict hourly price swings. Could improve multi-day forecasts if historical time series were available.

Not Used: Grid Imbalance & Flows

TenneT imbalance data and ENTSO-E cross-border flows are published with a 1-day lag — by the time we have yesterday's imbalance, today's prices are already known. Useful for analysis but not for forecasting.

Not Used: Multiple Locations

energyDataHub provides wind data from 9 offshore farms, solar from 7 locations, and weather from 6 cities. We use one NL site per type because: (a) NL is small — weather is highly correlated across locations, (b) more features increase overfitting risk with limited training data (6 months), (c) Lasso confirms additional locations add no predictive value.