Look-ahead bias in energy backtests: forecast vs actual
Every researcher has had the euphoric moment: you finish a strategy, run the backtest, and stare at an impossible Sharpe. Then it bleeds money live. Often the culprit is not overfitting — it is look-ahead bias: your backtest quietly used information that did not exist at the moment of the decision.
In energy markets there are two distinct ways the future leaks in, and people routinely conflate them. Only one of them is fixable with a dataset; being honest about which is which is the whole game.
Leak 1: using the outcome instead of the forecast
This is the common one, and it is specific to weather-driven markets. The day-ahead power auction clears on the forecast of wind and solar. The *actual* generation is only known after the fact. If your dispatch or imbalance model uses the realised generation where the market only had a forecast, you have handed your algorithm tomorrow's weather report. Projected revenues become fiction.
The honest fix is not to pretend the forecast was perfect — it is to model the forecast error explicitly. How wrong was the day-ahead forecast, by zone, by half-hour? That error *is* the tradable quantity behind imbalance and intraday strategies, and it is knowable ex-post without contaminating an ex-ante signal — as long as you feed your model the forecast and keep the actual strictly on the outcome side of the ledger.
That is exactly what our European Renewable Forecast Error dataset is: actual minus day-ahead forecast wind+solar, in MW, for every European bidding zone at half-hourly resolution back to 2018. Pair it with the day-ahead generation forecast (what the market knew ex-ante) and the realised generation by fuel (the outcome), and you can build a backtest that trades on the forecast and is *scored* on the actual — never the other way round.
Leak 2: restated data, and what it actually takes to fix
The second leak is subtler: revisions. Many public series overwrite history. A TSO publishes a metered value, then corrects it two days later. Macro offices publish a GDP print, then revise it for months. If you download the series today and backtest last year, you are using numbers that did not exist at decision time — even though every value is individually "correct."
Fixing this requires point-in-time (PIT) data: an append-only log that records not just the value and its target timestamp, but the observed_at moment it was first published, so you can reconstruct exactly what was known on any past date. You cannot compute PIT after the fact — you have to have been recording vintages all along.
We will be straight with you: like almost all open-data products, ReadySet ships the latest published vintage, not a full revision history. Every product shows its *data-through* date, and where a series is a genuine forecast-versus- actual — like the forecast-error dataset above — we keep both sides explicit. But if your strategy hinges on trading the *first print* of a revised macro series, that is a bitemporal-vintage problem, and no latest-vintage file (ours or anyone else's) is a substitute for having captured the vintages yourself.
Building an honest energy backtest
- Feed the model forecasts, score it on actuals — never let the outcome cross into the feature set.
- Treat forecast error as a first-class, modellable quantity, not noise.
- Know whether your series is revised, and if the first print matters, source true PIT — do not fake it with a revised file.
The forecast side of that is done for you: clean, UTC-aligned, half-hourly forecast error and day-ahead prices across ~40 European zones, as analysis-ready Parquet. You model the strategy; you do not spend a week untangling which column was known when.
Stop building parsers. Start at the analysis.
We've already cleaned, documented and QC'd sources like the one in this post into query-ready Parquet - with a free sample on every dataset. Buy a file from €9, or go All-Access for the lot.