Intraday-Handel: Kontinuierlicher Markt

← Learning Hub Lektion 5 · Batterieoptimierungs-Kurs · Geschätzte Dauer: 20 Minuten

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.

Day-Ahead vs. Intraday: Hauptunterschiede

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
Pay-as-bid ist wichtig: Im Intraday-Markt ist dein Gebotspreis DEIN Ausführungspreis. Es gibt keinen einheitlichen Clearing-Preis. Das bedeutet, deine Gebotsstrategie bestimmt direkt den Erlös — bietest du zu aggressiv, verschenkst du Geld; bietest du zu passiv, wirst du nicht ausgeführt.

Warum Batterien Intraday lieben

Drei Hauptanwendungsfälle für Batteriespeicher im Intraday:

  1. Fahrplankorrektur: Deine Day-Ahead-Position basierte auf einer Prognose. Wenn sich Preise bewegt haben, handle dich aus verlustbringenden Stunden heraus und in bessere hinein.
  2. Zusätzlicher Spread-Capture: Intraday-Volatilität übersteigt oft Day-Ahead. Kurzfristige Preisspitzen (Windeinbrüche, Kraftwerksausfälle) schaffen Arbitrage-Möglichkeiten.
  3. Viertelstündlicher Handel: Batterien können in 15-Minuten-Granularität reagieren. Viertelstündliche Produkte erfassen Wert, den stündliche Produkte glätten — besonders bei Sonnenauf-/untergang.

Der rollierende Optimierer

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                 │
└───────────────────────────────────────────────────────┘

Implementierung: der Delta-Ansatz

"""
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)

Order-Typen im kontinuierlichen Markt

Beim Einreichen von Intraday-Orders wählst du:

Praktischer Tipp: Für Fahrplankorrekturen (du musst handeln) nutze aggressive Limit-Orders nahe am aktuellen besten Preis. Für opportunistischen Spread-Capture (nice-to-have) nutze geduldige Limit-Orders und lass den Markt zu dir kommen.

Trigger-basierte Reoptimierung

Du willst nicht jede Sekunde reoptimieren. Häufige Trigger:

Überprüfe dein Verständnis

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?

📖 Empfohlene Lektüre

EPEX SPOT — Intraday Kontinuierlicher Handel — offizielle Dokumentation zu Order-Typen, Gate-Closure-Zeiten und grenzüberschreitender Kopplung.

💬 Fragen? Das Zusammenspiel zwischen Day-Ahead-Positionen und Intraday-Reoptimierung ist dort, wo das meiste Geld verdient wird. Frag nach konkreten Szenarien — z.B. was passiert, wenn dein gesamter Day-Ahead-Fahrplan falsch war?

Rechtliches: Impressum