← Alle Insights

WebSocket-APIs für Echtzeit-Marktdaten: was bei der Integration schiefgeht.

REST-Polling fühlt sich einfach an, ist aber für Live-Trading meist die falsche Wahl. WebSocket-APIs liefern Marktdaten in Echtzeit per persistent connection — bringen dafür eine eigene Klasse von Bugs mit, die in keiner Broker-Doku stehen.

Ich habe in den letzten Jahren Dutzende WebSocket-Integrationen gegen IBKR, Binance, Polygon, Alpaca und kleinere Datenanbieter geschrieben. Jede einzelne hat mich mindestens einmal überrascht — meistens nachts, meistens während eines Marktevents. Dieser Artikel ist die Sammlung der Lektionen.

WebSocket vs. REST: wann lohnt sich der Wechsel?

REST ist Request–Response: Sie fragen, der Server antwortet, die Verbindung schließt. Für Quote-Updates bedeutet das Polling — alle 100 ms oder 500 ms eine neue Anfrage, mit allem Overhead (TCP-Handshake, TLS-Handshake, HTTP-Header). WebSocket dagegen ist eine persistent connection: ein Handshake am Anfang, danach fließen Updates server-pushed, mit minimalem Frame-Overhead.

Konkret: ein typischer REST-Poll auf Binance kostet 200–400 ms pro Quote. Per WebSocket bekomme ich dasselbe Update in 5–20 ms, ohne Polling-Overhead. Für jede Strategie unter H1 ist das nicht optional — bei M1- oder Tick-Strategien entscheidet es über Profitabilität.

Bibliotheken: Standard nehmen, nicht selbst bauen.

In Python gibt es zwei Klassiker:

Ich nehme heute fast immer websockets, weil sich async sauber mit dem Rest meiner Trading-Pipeline (Order-Routing, DB-Writes, Telegram) komponieren lässt. Für ältere Codebasen oder kleine Skripte ist websocket-client ok.

Was Sie nicht machen sollten: WebSocket-Framing selbst implementieren. Ich habe in einem alten Projekt mal einen rohen TCP-Socket mit eigenem Frame-Parser gehabt — bei jedem zweiten Binance-Update brach er, weil die Bibliothek einen Edge-Case (zerteilte Frames bei großen Order-Books) nicht abbildete.

Reconnect-Logik: das Herzstück jeder Integration.

WebSockets brechen ab. Immer. Punkt. Broker führen Wartungen durch, Netzwerke haben Aussetzer, Load-Balancer rotieren. Wenn Ihr Bot auf eine einzige offene Verbindung baut, ist er nicht produktionsreif.

Der Standard: exponential backoff mit Jitter.

import asyncio, random, websockets

async def connect_forever(url, on_message):
    delay = 1
    while True:
        try:
            async with websockets.connect(url, ping_interval=20) as ws:
                delay = 1  # reset nach erfolgreichem Connect
                async for msg in ws:
                    await on_message(msg)
        except Exception as e:
            jitter = random.uniform(0, delay * 0.3)
            wait = min(delay + jitter, 60)
            await asyncio.sleep(wait)
            delay = min(delay * 2, 60)

Wichtig: nach Reconnect müssen Sie alle Subscriptions neu anlegen. Der Server vergisst Ihre Stream-Abos, sobald die Verbindung weg ist. Ein häufiger Bug ist, dass nach Reconnect die Verbindung zwar steht, aber keine Daten mehr fließen, weil die Resubscribe-Logik fehlt.

Message-Ordering und Sequence-Validation.

Jeder ernsthafte Datenanbieter sendet eine Sequence-Number oder einen Update-Counter pro Stream. Beispiel Binance Spot Diff-Depth: jedes Update enthält U (first update id) und u (last update id). Wenn zwischen zwei Messages eine Lücke ist, haben Sie ein Problem — das lokale Order-Book ist korrupt.

Der korrekte Algorithmus für Binance Order-Book lokal halten:

  1. WebSocket-Stream öffnen, eingehende Diffs puffern
  2. REST-Snapshot des Order-Books holen, mit lastUpdateId
  3. Alle gepufferten Diffs mit ulastUpdateId verwerfen
  4. Erstes verbleibendes Diff muss UlastUpdateId + 1u erfüllen — sonst neu starten
  5. Ab dann jeweils U = previous u + 1 prüfen — sonst neu starten

Bei Verletzung der Sequence: hartes Reset. Order-Book verwerfen, neuer Snapshot, neu aufbauen. Klingt brutal, ist aber die einzige saubere Lösung. Strategien, die auf einem inkonsistenten Order-Book handeln, verlieren leise und konstant.

Heartbeats und Stale-Connection-Detection.

Das Heimtückische an WebSocket: eine Verbindung kann „tot" sein, ohne dass das close-Event ausgelöst wird. TCP merkt eine NAT-Disconnection oft erst nach Minuten. In der Zwischenzeit hält Ihr Bot eine Verbindung für lebendig, die längst keine Daten mehr empfängt.

Zwei Gegenmaßnahmen, die ich immer kombiniere:

Den zweiten Punkt unterschätzen Anfänger gern. Aber gerade bei Binance ist es Realität, dass die TCP-Verbindung steht, die WS-Pings funktionieren — und trotzdem keine Trade-Updates mehr fließen, weil server-seitig der Stream verloren ging.

Daten-Quality-Checks.

Auch bei intakter Verbindung dürfen Sie den Daten nicht blind vertrauen. Häufige Probleme:

Konkrete Broker-Eigenheiten.

IBKR WebSocket (TWS / Gateway)

IBKR ist ein Sonderfall: kein klassisches WebSocket gegen die API, sondern eine proprietäre Socket-Verbindung gegen TWS oder IB Gateway. Die ib_insync-Library kapselt das gut. Achten Sie auf: 50-Ticker-Limit pro Marktdaten-Subscription (außer mit teurerem Bundle), Verbindungs-Reset bei jedem TWS-Auto-Restart (täglich!), und unzuverlässige Reconnect-Events.

Binance Spot

Stabil, gut dokumentiert — aber: Streams werden nach 24h zwangsweise getrennt (listenKey-Expiry bei User-Streams). Sie müssen alle 30 Minuten den Key verlängern (PUT /api/v3/userDataStream) und alle 23h proaktiv neu connecten. Wer das vergisst, verliert Order-Updates lautlos.

Polygon.io

Saubere API, gute Doku. Ein subtiler Punkt: aggregierte Bars (AM) kommen mit etwa 0,5–1 s Verzögerung nach Bar-Close — wer auf die Bar reagiert, muss das einplanen. Trades (T) und Quotes (Q) sind hingegen sehr schnell.

Häufige Bugs in der Praxis.

Memory-Leaks durch nicht-geschlossene Subscriptions

Symptom: Bot läuft, Speicher wächst über Stunden, irgendwann OOM-Kill. Ursache: bei Reconnect wird ein neuer Stream-Handler erzeugt, der alte aber nicht sauber beendet. Callbacks akkumulieren, Tasks häufen sich. Lösung: jeden Reconnect mit sauberem Teardown — alle Tasks cancel()en, alle Callbacks deregistrieren.

Buffer-Overflows bei großen Order-Book-Streams

Bei BTC/USDT Diff-Depth fliegen leicht 100+ Messages pro Sekunde. Wenn Ihre on_message-Funktion synchron in eine DB schreibt, läuft der WebSocket-Buffer voll, die Lib wirft WebSocketException, alles bricht. Lösung: Producer-Consumer mit asyncio-Queue. on_message macht nur Queue-Put, ein separater Worker verarbeitet.

SSL-Zertifikatsfehler nach OS-Update

Klassiker auf älteren Ubuntu-VPS: ca-certificates ist veraltet, Broker erneuert TLS-Zertifikat, plötzlich SSL-Handshake-Fehler. Lösung: apt update in Wartungs-Routine, plus Monitoring auf TLS-Errors.

Meine Praxis.

Ich nutze WebSocket für alle Live-Strategien — REST nur für Order-Submissions und gelegentliche Snapshots. Pro Stream baue ich ein dünnes Wrapper-Modul mit: Reconnect-Loop, Resubscribe-Logik, Sequence-Validation, Heartbeat-Watchdog, Dedupe, Quality-Filter. Plus: extensives Logging in eine zentrale Timeseries-DB (Prometheus oder InfluxDB), inklusive Messages/Sek, Lücken-Counter, Reconnect-Counter, Latenz-Histogramm.

Bei jedem Reconnect, jedem Sequence-Bruch, jedem Quality-Filter-Hit landet ein strukturiertes Log-Event in der DB. Wenn nachts eine Strategie auffällig wird, kann ich am nächsten Morgen in 60 Sekunden sehen, ob der WebSocket sauber lief oder ob die Strategie auf korrupten Daten gehandelt hat.

Sie integrieren WebSocket-Datenfeeds für eine eigene Strategie und wollen typische Fehlerquellen ausschließen? Erstgespräch buchen — ich schaue mir Ihr Setup konkret an.