PPA Settlement
Calculate capture prices and settlements
Overview
Power Purchase Agreements (PPAs) are long-term contracts between renewable generators and offtakers. Settlement typically occurs monthly, comparing market reference prices against the agreed strike price.
Key Concepts
Capture Price
Volume-weighted average price achieved by a technology. Wind typically captures 85-95% of baseload due to cannibalization.
Shape Factor
Capture Price ÷ Baseload Price. Values below 1.0 indicate the technology generates when prices are lower.
Reference Price
The market price used for settlement. Can be baseload average, capture price, or a specific index.
Settlement
(Reference Price - Strike Price) × Volume. Positive means offtaker pays generator the difference.
Calculating Capture Price
The capture price is the volume-weighted average price achieved during periods of generation. For wind, this is typically lower than baseload due to price cannibalization when wind output is high.
import { EnergyOracle } from '@energyoracle/sdk';
const oracle = new EnergyOracle({ apiKey: 'your-key' });
// Calculate capture price for wind generation
const capture = await oracle.uk.analytics.capturePrice({
technology: 'wind',
year: 2024,
month: 12,
});
console.log(`Capture Price: £${capture.capturePrice}/MWh`);
console.log(`Baseload Price: £${capture.baseloadPrice}/MWh`);
console.log(`Shape Factor: ${capture.shapeFactor}`);
// Shape Factor = Capture Price / Baseload Price
// < 1.0 means wind captures below average price (cannibalization)
// > 1.0 means wind captures above average priceFormula: Capture Price = Σ(Price × Generation) ÷ Σ(Generation)
Settlement Calculation
Use our SDK to calculate monthly settlements with a single API call.
// Monthly PPA settlement calculation
const settlement = await oracle.uk.settlement.calculate({
volumeMwh: 10000, // 10 GWh monthly generation
contractPrice: 55.00, // Strike price £55/MWh
fromDate: '2024-12-01',
toDate: '2024-12-31',
technology: 'wind', // Optional: use technology-specific capture
});
// Response:
// {
// period: { from: '2024-12-01', to: '2024-12-31' },
// volumeMwh: 10000,
// contractPrice: 55.00,
// referencePrice: 48.50, // Monthly average or capture price
// settlementAmount: -65000, // Negative = generator pays offtaker
// details: {
// capturePrice: 48.50,
// shapeFactor: 0.91,
// baseloadPrice: 53.30
// }
// }Custom Settlement with Python
For complex settlement logic, use raw price data with Pandas.
from energyoracle import EnergyOracle
import pandas as pd
oracle = EnergyOracle(api_key="your-key")
# Get raw price data for custom calculations
prices = oracle.uk.prices.range("2024-12-01", "2024-12-31")
df = prices.to_dataframe()
# Calculate your own settlement index
# Example: Volume-weighted average for specific hours
peak_hours = df[(df['period'] >= 16) & (df['period'] <= 40)] # 8am-8pm
peak_avg = peak_hours['price'].mean()
# Apply contract formula
volume_mwh = 10000
strike_price = 55.00
settlement = (peak_avg - strike_price) * volume_mwh
print(f"Peak Average: £{peak_avg:.2f}/MWh")
print(f"Settlement: £{settlement:,.0f}")Reference Price Indices
Different PPAs use different reference indices. Our API supports all common types.
// Available reference indices
const indices = {
// Simple averages
baseload: 'Average of all settlement periods',
peak: 'Average of periods 16-40 (8am-8pm weekdays)',
offpeak: 'Average of all other periods',
// Technology capture prices
windCapture: 'Volume-weighted by wind generation',
solarCapture: 'Volume-weighted by solar generation',
// System prices
systemSellPrice: 'SSP - for short positions',
systemBuyPrice: 'SBP - for long positions',
};
// Get specific index
const index = await oracle.uk.analytics.referenceIndex({
type: 'windCapture',
year: 2024,
month: 12,
});PPA Contract Types
Implementation patterns for common PPA structures.
// Different PPA contract types
// 1. Fixed Price PPA
const fixedPPA = {
type: 'fixed',
strikePrice: 55.00,
volume: 10000,
settlement: async (oracle, period) => {
const ref = await oracle.uk.prices.monthlyAverage(period.year, period.month);
return (ref.avgPrice - 55.00) * 10000;
}
};
// 2. Baseload Shape PPA (most common)
const baseloadPPA = {
type: 'baseload',
strikePrice: 55.00,
volume: 10000,
settlement: async (oracle, period) => {
const ref = await oracle.uk.prices.monthlyAverage(period.year, period.month);
return (ref.avgPrice - 55.00) * 10000;
}
};
// 3. As-Generated PPA (technology-specific capture)
const asGeneratedPPA = {
type: 'as-generated',
technology: 'wind',
strikePrice: 50.00,
volume: 10000,
settlement: async (oracle, period) => {
const capture = await oracle.uk.analytics.capturePrice({
technology: 'wind',
year: period.year,
month: period.month
});
return (capture.capturePrice - 50.00) * 10000;
}
};
// 4. Sleeved PPA (route-to-market)
const sleevedPPA = {
type: 'sleeved',
strikePrice: 48.00, // Lower due to imbalance risk
shapeDiscount: 0.05, // 5% discount for shape
imbalanceCost: 2.50, // £2.50/MWh imbalance allowance
};On-Chain Settlement
Use our Solidity contracts for trustless, automated settlement.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@energyoracle/contracts/IEnergyOracle.sol";
contract PPASettlement {
IEnergyOracle public oracle;
// Strike price in GBP/MWh (18 decimals)
uint256 public strikePrice = 55e18;
function calculateSettlement(
uint16 year,
uint8 month,
uint256 volumeMwh
) external view returns (int256) {
// Get reference price from oracle
uint256 referencePrice = oracle.getMonthlyAverage(year, month);
// Settlement = (Reference - Strike) × Volume
int256 priceDiff = int256(referencePrice) - int256(strikePrice);
int256 settlement = priceDiff * int256(volumeMwh) / 1e18;
return settlement;
}
}Best Practices
1. Use Final Settlement Data
Elexon publishes initial prices (II) which are later revised. For contractual settlement, wait for SF (Settlement Final) data, typically available 14 working days after the settlement day.
2. Document Your Reference Price
Store the exact timestamp and data source used for each settlement calculation. Our API includes metadata for audit trails.
3. Handle Clock Changes
UK has 46 settlement periods on short days and 50 on long days. Our API handles this automatically, but verify your volume allocation logic.