Markets
The engine supports five electricity markets. Each can be independently enabled via the enabled_markets parameter in the run configuration.
{
"run": {
"enabled_markets": ["day_ahead", "intraday", "afrr", "fcr"]
}
}Market Overview
Day-Ahead (day_ahead)
The primary energy trading market. The optimizer buys energy when prices are low and sells when prices are high.
| Property | Value |
|---|---|
| Resolution | 15 minutes |
| Price field | DA_price_15min |
| Type | Energy arbitrage |
Revenue is calculated as:
revenue = (discharge_mwh - charge_mwh) × price × 0.25Day-ahead is the default market and is always enabled unless explicitly excluded.
Intraday (intraday)
Continuous intraday market for short-term trading. Uses the same charge/discharge logic as day-ahead but on intraday prices.
| Property | Value |
|---|---|
| Resolution | 15 minutes |
| Price field | ID3_price |
| Type | Energy arbitrage |
Intraday trading captures additional spread between day-ahead and intraday prices.
Imbalance (imbalance)
Real-time settlement based on the system imbalance direction. Unlike the energy markets, imbalance uses separate prices for charging and discharging.
| Property | Value |
|---|---|
| Resolution | 15 minutes |
| Price fields | Imb_Long_price (discharge), Imb_Short_price (charge) |
| Signal fields | Regulation_State, signal |
| Type | Balancing energy |
Revenue calculation:
revenue = discharge × imb_long_price - charge × imb_short_priceThe optimizer uses regulation state signals to determine when imbalance trading is allowed:
| State | Meaning |
|---|---|
1 | Discharge favorable (system needs upward regulation) |
-1 | Charge favorable (system needs downward regulation) |
0, 2 | No trading allowed |
aFRR — Automatic Frequency Restoration Reserve (afrr)
A two-stage market combining capacity reservation and energy activation.
Capacity Auction
The battery commits MW capacity for potential activation by the TSO. Capacity bids must be constant within each block.
| Property | Value |
|---|---|
| Block duration | 4 hours (German market) or 24 hours (configurable via afrr_block_hours) |
| Price fields | afrr_capacity_up, afrr_capacity_down |
capacity_revenue = capacity_bid × capacity_price × block_durationEnergy Activation
When activated, the battery responds with upward (discharge) or downward (charge) regulation.
| Property | Value |
|---|---|
| Price fields | afrr_energy_up, afrr_energy_down |
energy_revenue = activation_mw × energy_price × durationActivation is limited by the committed capacity bid.
Allocation
Control how much battery power is available for aFRR:
max_afrr_allocation— maximum fraction of battery power for aFRR (0-1)max_capacity_allocation— combined limit for aFRR + FCR
FCR — Frequency Containment Reserve (fcr)
Capacity-only market for primary frequency response. The battery reserves MW capacity that must remain available for frequency response at all times.
| Property | Value |
|---|---|
| Price field | fcr_price |
| Type | Capacity reservation |
revenue = capacity_bid × fcr_price × durationReserved FCR capacity is unavailable for energy trading. Control allocation with max_fcr_allocation.
Revenue Breakdown
Adjust the sliders to explore how revenue distributes across markets:
Example Annual Revenue Breakdown
Capacity Allocation
When both aFRR and FCR are enabled, the optimizer balances capacity between markets. Use the interactive diagram below to see how battery power is split:
Battery Power Allocation
The optimizer enforces:
afrr_bid + fcr_bid ≤ battery_power × max_capacity_allocationRemaining power after capacity allocation is available for energy markets (day-ahead, intraday, imbalance).
Solar & Wind Subsidies
Co-located solar and wind generation earn subsidy revenue independent of battery trading.
Subsidy Calculation
subsidy_revenue = Σ(generation_mw × subsidy_eur_mwh × 0.25)Negative Price Shutdown
- Track consecutive 15-minute periods with negative DA prices
- If consecutive negative hours reach
shutdownConsecutiveHours(default: 6), subsidies are withheld for remaining negative periods - When prices turn positive, the counter resets
Generation continues during shutdown but without subsidy payment.
Grid Costs
Transport Costs
| Parameter | Description |
|---|---|
gridStandingChargeTransport | Fixed annual charge (EUR/year) |
gridTransportedEnergy | Variable charge per MWh (EUR/MWh) |
gridYearlyTariffIncrease | Annual escalation rate (default: 2%) |
Power Limits
| Parameter | Description |
|---|---|
gridChargingCapacity | Maximum charge power from grid (MW) |
gridDischargingCapacity | Maximum discharge power to grid (MW) |
gridChargingCapacityByMonth | Per-month charge limits (12-element array) |
gridChargingCapacityByHour | Per-hour-of-day charge limits (24-element array) |