Software architecture (Python) for the wholesale electricity market
A High-Level View of the day-ahead and balancing mechanism
Every day, across the United Kingdom (UK), renewable energy companies must predict the weather for the next day, and promise to generate specific amounts of electricity (MWh), and the next day to actually generate that electricity.
In this post I present how a market settlement program is structured, in Python. The renewable energy company “GreenPower Energy Ltd” (the name is fictional in order to keep the real data confidential) operates a solar Photovoltaics farm in England (in Cornwall) whose installed capacity is 50 MW, and also a wind farm in Scotland (in the Scottish Highlands), with 100 MW installed capacity.
Assume that today it is January 14th, 2030 (the actual date has been altered to keep the original data confidential). The Python model presented in this post helps the company understand exactly how much money they’ll make (or lose) when January 15th arrives and their assets (solar PV and wind farm) must generate the electricity they promised.
What makes this particularly interesting is the dual-price structure of the UK wholesale electricity market. Companies receive one price for what they scheduled to generate; this price is called ‘day-ahead wholesale electricity price’, but face different prices (called ‘imbalance prices’) for any imbalances between the electricity they promised to generate and the electricity they actually generated. For example, if on the 14th of January 2030 the wind farm promises that next day (on the 15th of January 2030 at hour 10am - 10:59am) it will generate 100 MWh of electricity, but when that time comes (i.e. hour 10am - 10:59 am on the 15th of January 2030) it generates 108 MWh (because the wind was more intense than it had predicted) then we speak about ‘overdelivery’ and so the company will sell the extra 8 MWh at a price lower than the price that it will sell the 100 MWh that it has promised.
This program calculates all the revenue that the company will receive from its participation in the wholesale electricity market and in the balancing mechanism, for every hour of the 15th of January 2030 (delivery day).
The Software Architecture: Six Python Modules
The system is built from six Python files, each with a specific responsibility:
1. constants.py - The Foundation Layer
This file defines the key elements of the business: company name (GreenPower Energy Ltd), the name of the day-ahead market operators (EPEX SPOT, Nord Pool), the name of the operator of the balancing mechanism (NESO), and most importantly, the portfolio of assets i.e. the 50 MW Cornwall solar farm and the 100 MW Scottish Highlands wind farm.
2. day_ahead_results.py - The Market Contract
This file captures the outcome of the day-ahead auction that occurred on January 14th at 12:30 PM. By that moment, every generator in the UK had submitted their bids, and the market clearing algorithm had determined:
The price for each of the 24 hours on January 15th. These 24 prices are known as the day-ahead wholesale electricity prices. They are all fixed i.e. after 12:30 PM on the 14th of January, they cannot be changed. Even if a hurricane hits Scotland or unprecedented sunshine bathes Cornwall, these prices won’t change.
How much GreenPower, on the 14th of January committed that it will deliver/generate on the 15th of January from each of its assets (solar and wind farm), hour by hour of the 15th of January
The balancing mechanism prices (System Sell Price and System Buy Price) that would apply to any imbalances observed on the 15th of January. An imbalance is the difference between what the solar/wind farm actually generates on the 15th of January, versus what it had promised/committed to generate.
3. actual_generation.py - The Reality Check
This file contains what actually the wind farm generated, and the solar farm also generated on the 15th of January.
4. power_calc.py - The Calculation Engine
The file contains five functions:
Revenue calculation. This is found by multiplying the MWh of electricity times the price.
Imbalance calculation. This is found by subtracting the actual electricity generated from the electricity that the company scheduled/promised to generate at some hour.
Imbalance cost calculation (applying UK Balancing Mechanism rules). If the company under-delivers (i.e. actually generates less electricity than it promised) then it will pay to buy the electricity is misses at the System Sell Price, which is typically higher than day-ahead prices). If it over-delivers, then it will sell the excess electricity at the System Buy Price (typically lower than the day-ahead prices). The prices are deliberately asymmetric to incentivize accurate forecasting.
Total settlement (combining day-ahead revenue with imbalance adjustments)
Daily aggregation (summing across all 24 hours)
5. main.py
This is where everything comes together. The main script follows a clear three-act structure:
Act I: Header & Context
The program announces itself, identifies the company, markets, and delivery date, and reminds the user that day-ahead prices were fixed on D-1.
Act II: Hourly Analysis
For every hour, the program performs detailed calculations:
Retrieves scheduled and actual generation for each asset
Calculates day-ahead revenue at the fixed market price
Computes imbalances (positive or negative)
Applies balancing mechanism prices to determine imbalance costs/revenues
Categorizes the severity of imbalances using the thresholds from
constants.py
Each asset gets its own line in the report, showing scheduled vs. actual, the imbalance in MWh, and three financial figures: day-ahead revenue, imbalance settlement, and total revenue.
Act III: Daily Summary
The program aggregates all 24 hours for each asset, calculating:
Total scheduled vs. actual energy (in MWh)
Capacity factor (how much of maximum potential was achieved)
Daily financial totals across both revenue streams
Portfolio-wide totals and impact analysis
The impact analysis is particularly revealing: it expresses imbalance costs as a percentage of day-ahead revenue, showing exactly how much forecast accuracy matters.
6. forecast_data.py - The Historical Record
This file serves as the historical record of what the company believed would happen when they submitted their bids. It contains the weather forecasts created on January 14th at 10:00 AM—two and a half hours before the market closed.
In a production system, this file would be crucial for post-mortem analysis: “How good were our forecasts? Where did we go wrong? What patterns can we learn?”
The Timeline: Understanding the Workflow
To truly appreciate this architecture, let us look at the temporal sequence:
D-1 (January 14th) at 10:00: Weather forecasts created → forecast_data.py is populated
D-1 at 12:00: Bids submitted to day-ahead market (based on forecasts)
D-1 at 12:30: Market clears → day_ahead_results.py is finalized with prices and commitments
D (January 15th) all day: Actual generation occurs → actual_generation.py is populated in real-time
D+1 (January 16th): Settlement calculation runs → main.py executes and produces the report
The software architecture mirrors this temporal reality. Data files represent distinct stages of market participation, and the calculation engine operates on the completed dataset.
Software Architecture: Dependencies and Data Flow
Now let’s get more technical about how these pieces fit together.
Dependency Graph
The dependency structure is deliberately hierarchical, avoiding circular imports:
Join our community! Visit skool.com, search for “Energy Data Scientist”


