Die Day-Ahead-Auktion (Lektion 4) bindet deine Batterie an einen Fahrplan 12+ Stunden vor Lieferung. Aber die Realität ändert sich: Windprognosen werden aktualisiert, ein Kraftwerk fällt aus, die Nachfrage weicht ab. Der Intraday-Markt erlaubt dir, deine Position bis kurz vor Lieferung anzupassen.
| Merkmal | Day-Ahead | Intraday Kontinuierlich |
|---|---|---|
| Mechanismus | Auktion (einmaliges Clearing) | Kontinuierlich (Orderbuch, Pay-as-bid) |
| Preisbildung | Einheitspreis | Pay-as-bid (du bekommst deinen Gebotspreis) |
| Gate Closure | 12:00 D-1 | 5 Min. vor Lieferung (variiert nach ÜNB) |
| Produkte | Stündlich, Block | Stündlich, halbstündlich, viertelstündlich |
| Liquidität | Sehr hoch | Gut für stündlich, dünner für 15-Min. |
| Batterie-Anwendungsfall | Basisfahrplan | Reoptimierung, Spread-Capture |
Drei Hauptanwendungsfälle für Batteriespeicher im Intraday:
Für Intraday optimierst du nicht einmal — du reoptimierst kontinuierlich wenn neue Informationen eintreffen. Das Muster:
┌───────────────────────────────────────────────────────┐
│ Alle 15 Minuten (oder bei Preistrigger): │
│ │
│ 1. Aktueller SoC → vom BMS lesen │
│ 2. Bestehende Positionen → aus Handelssystem │
│ 3. Aktualisierte Preisprognose → neueste Modellausgabe│
│ 4. Verbleibende Stunden → nur Zukunft, nicht Vergangen│
│ │
│ Optimierer auf verbleibendem Horizont ausführen │
│ ↓ │
│ Neuen Fahrplan mit bestehenden Positionen vergleichen│
│ ↓ │
│ Delta = Trades um zum neuen Fahrplan zu kommen │
│ ↓ │
│ Delta als Intraday-Orders einreichen │
└───────────────────────────────────────────────────────┘
"""
intraday_reoptimierung.py — Rollierende Reoptimierung
"""
import pyomo.environ as pyo
import numpy as np
import pandas as pd
def reoptimieren(aktueller_soc, bestehende_positionen, preis_prognose,
verbleibende_stunden, P_max, E_max, eta, deg_kosten):
"""
Optimierer für den verbleibenden Lieferzeitraum erneut ausführen.
Args:
aktueller_soc: Aktueller Batterie-SoC in MWh (vom BMS)
bestehende_positionen: dict {stunde: netto_mw} — bereits gebundene Trades
preis_prognose: dict {stunde: preis} — aktuelle Prognose
verbleibende_stunden: Liste handelbarer Stunden
Returns:
DataFrame mit Delta-Trades zum Einreichen
"""
T_rest = len(verbleibende_stunden)
stunden = verbleibende_stunden
eta_sqrt = np.sqrt(eta)
model = pyo.ConcreteModel()
model.T = pyo.Set(initialize=range(T_rest))
model.p_laden = pyo.Var(model.T, bounds=(0, P_max))
model.p_entladen = pyo.Var(model.T, bounds=(0, P_max))
model.soc = pyo.Var(model.T, bounds=(0.1 * E_max, 0.9 * E_max))
model.y = pyo.Var(model.T, within=pyo.Binary)
# Zielfunktion: verbleibenden Erlös minus Degradation maximieren
def ziel_regel(m):
erloes = sum(
preis_prognose[stunden[i]] * (m.p_entladen[i] - m.p_laden[i])
for i in m.T
)
deg = sum(deg_kosten * (m.p_laden[i] + m.p_entladen[i]) for i in m.T)
return erloes - deg
model.ziel = pyo.Objective(rule=ziel_regel, sense=pyo.maximize)
# SoC-Bilanz (ausgehend vom aktuellen SoC)
def soc_regel(m, i):
vorher = aktueller_soc if i == 0 else m.soc[i-1]
return m.soc[i] == vorher + eta_sqrt * m.p_laden[i] - m.p_entladen[i] / eta_sqrt
model.soc_bil = pyo.Constraint(model.T, rule=soc_regel)
# Kein gleichzeitiges Laden/Entladen
def kl(m, i): return m.p_laden[i] <= P_max * (1 - m.y[i])
def ke(m, i): return m.p_entladen[i] <= P_max * m.y[i]
model.kl = pyo.Constraint(model.T, rule=kl)
model.ke = pyo.Constraint(model.T, rule=ke)
# Lösen
solver = pyo.SolverFactory('highs')
solver.solve(model, tee=False)
# Delta berechnen: neuer optimaler Fahrplan minus bestehende Positionen
deltas = []
for i, h in enumerate(stunden):
neues_netto = pyo.value(model.p_entladen[i]) - pyo.value(model.p_laden[i])
bestehendes_netto = bestehende_positionen.get(h, 0.0)
delta = neues_netto - bestehendes_netto
if abs(delta) > 0.1: # Nur handeln wenn Delta relevant
deltas.append({
'stunde': h,
'richtung': 'VERKAUF' if delta > 0 else 'KAUF',
'menge_mw': round(abs(delta), 2),
'limitpreis': round(preis_prognose[h] + (2 if delta < 0 else -2), 2),
})
return pd.DataFrame(deltas)
Beim Einreichen von Intraday-Orders wählst du:
Du willst nicht jede Sekunde reoptimieren. Häufige Trigger:
Im Intraday-Markt, wenn du eine Verkaufsorder bei €70/MWh einreichst und sie ausgeführt wird, wie viel bekommst du?
Der „Delta-Ansatz" vergleicht den neuen optimalen Fahrplan mit bestehenden Positionen. Warum nicht einfach alle bestehenden Positionen stornieren und neu einreichen?
Warum sind viertelstündliche Produkte besonders wertvoll für Batterien?
EPEX SPOT — Intraday Kontinuierlicher Handel — offizielle Dokumentation zu Order-Typen, Gate-Closure-Zeiten und grenzüberschreitender Kopplung.
Rechtliches: Impressum