Skip to content

euanmacintyre/gb-imbalance-battery-backtest

Repository files navigation

GB Imbalance Price Nowcast and Battery Dispatch Backtest

This repo pulls GB half-hourly imbalance system prices from the Elexon BMRS Insights API, builds a short-horizon nowcast, then converts that signal into charge and discharge decisions for a SOC-limited battery. It backtests the dispatch and reports £ PnL.

The aim is to show an end-to-end workflow you would use in energy analysis: data access, clean time indexing, forecasting, decision rules, constraint-aware simulation, clear outputs.

Notebooks

Notebook What it does
notebooks/01_pull_system_prices.ipynb Pulls one settlement date, builds timestamps, writes the raw day file to data/raw/ as a sanity check
notebooks/02_build_price_history.ipynb Pulls a date range, caches each day to data/raw/, builds data/processed/prices.parquet
notebooks/03_baseline_forecast.ipynb Creates lag and calendar features, runs a lag-48 baseline (yesterday same settlement period), reports MAE
notebooks/04_train_model.ipynb Trains a gradient-boosted model with time-series cross-validation, compares MAE vs baseline, saves preds.parquet
notebooks/05_backtest.ipynb Turns predictions into a dispatch signal using rolling quantiles, simulates SOC and efficiency, reports PnL and plots

Data

  • Source: Elexon BMRS Insights API
  • Frequency: half-hour settlement periods
  • Series: uses the system price series returned by the Insights endpoint
    If you want SBP and SSP explicitly, swap the endpoint and widen the pull.

Forecasting

  • Baseline: lag-48
  • Model: HistGradientBoostingRegressor
  • Validation: 5-fold time split

Dispatch backtest

Battery assumptions:

  • 1 MW / 2 MWh battery
  • 90% round-trip efficiency
  • Signal: charge, discharge, hold based on rolling quantiles of recent predicted prices
  • Constraints: SOC limited, no simultaneous charge and discharge

Results

  • Baseline MAE: 40.56 £/MWh
  • Model MAE (5-fold time split): 24.92 £/MWh
  • Total PnL: £12,526.36
  • Charge periods: 354
  • Discharge periods: 279

Limitations

This is a simplified backtest intended to demonstrate workflow and reasoning. It ignores transaction costs, bid/offer spreads, imperfect fills, stacking across multiple markets, site constraints, network constraints.

Planned extensions

  • Add transaction costs, bid/offer, execution rules, then re-run sensitivities
  • Extend to multi-market stacking (for example DA, intraday, balancing) with one consistent constraint set
  • Build a half-hourly forward curve shaping module: start from monthly and quarterly prices, apply profile factors (seasonality, day-of-week, peak/off-peak), document monthly and quarterly shape updates
  • Add risk outputs that match procurement decisions: scenario PnL, drawdowns, stress periods, hedge effectiveness

About

mv gitignore.txt .gitignore

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published