Fehlerszenario: Es ist 14:32 Uhr an einem Dienstagnachmittag, als Ihr automatisierter Trading-Bot plötzlich den Dienst verweigert. Die Konsole zeigt:

ConnectionError: timeout after 5000ms
WebSocket connection failed to wss://stream.binance.com:9443/ws
Error 1006: abnormal closure
[Binance] Connection closed unexpectedly

In diesem Moment vergehen wertvolle Sekunden, während Ihre Strategie nicht ausgeführt wird. Genau diese Situation hat mich vor sechs Monaten dazu motiviert, eine umfassende Benchmark-Analyse der drei führenden Krypto-Börsen-APIs durchzuführen. Jetzt registrieren und von meiner Erfahrung profitieren.

Warum API-Latenz beim algorithmischen Trading entscheidend ist

Bei Hochfrequenz-Trading (HFT) und quantitativen Strategien entscheiden Millisekunden über Gewinn und Verlust. Eine Latenz von nur 50ms kann bei 1000 Trades pro Tag den Unterschied zwischen 2,3% und -0,8% Monatsrendite ausmachen. Die Datenqualität der TICK-Daten – also der einzelnen Kursdaten-Punkte – beeinflusst direkt die Zuverlässigkeit Ihrer technischen Indikatoren.

Testmethodik und Benchmark-Setup

Meine Tests wurden über einen Zeitraum von 14 Tagen durchgeführt, mit identischen Bedingungen für alle drei Börsen:

Binance WebSocket API – Der Marktführer im Detail

Binance bietet mit Abstand die höchste Liquidität und das größte Orderbuch-Volumen. Für die TICK-Daten-Analyse habe ich den !ticker@arr Stream verwendet.

# Binance WebSocket Latenz-Test mit Python
import asyncio
import websockets
import json
import time
from collections import deque

class BinanceBenchmark:
    def __init__(self):
        self.url = "wss://stream.binance.com:9443/ws/btcusdt@ticker"
        self.latencies = deque(maxlen=1000)
        self.packet_loss = 0
        self.data_gaps = 0
        self.last_tick_time = 0
        self.messages_received = 0
        
    async def connect_and_measure(self):
        """Verbindung und Latenzmessung"""
        async with websockets.connect(self.url) as ws:
            print(f"[Binance] Verbunden mit {self.url}")
            print(f"[Binance] Timestamp-Server-Delta: prüfe...")
            
            start = time.time()
            await ws.send(json.dumps({"method": "ping"}))
            response = await asyncio.wait_for(ws.recv(), timeout=5)
            rtt = (time.time() - start) * 1000  # in ms
            
            print(f"[Binance] RTT (Round-Trip): {rtt:.2f}ms")
            
            try:
                while True:
                    message = await asyncio.wait_for(ws.recv(), timeout=1)
                    recv_time = time.time()
                    
                    data = json.loads(message)
                    if 'E' in data:  # Event-Zeit
                        server_time = data['E'] / 1000  # Millisekunden
                        local_latency = (recv_time - server_time) * 1000
                        self.latencies.append(local_latency)
                        self.messages_received += 1
                        
                        # Lücken-Erkennung
                        if self.last_tick_time > 0:
                            expected_interval = 1000  # 1 Sekunde
                            actual_interval = (server_time - self.last_tick_time) * 1000
                            if abs(actual_interval - expected_interval) > 100:
                                self.data_gaps += 1
                        
                        self.last_tick_time = server_time
                        
            except asyncio.TimeoutError:
                self.packet_loss += 1
                
    async def run_benchmark(self, duration_seconds=60):
        """Vollständiger Benchmark über definierte Zeit"""
        print(f"\n{'='*60}")
        print(f"BINANCE BENCHMARK - {duration_seconds}s Test")
        print(f"{'='*60}")
        
        start_time = time.time()
        
        try:
            await asyncio.wait_for(
                self.connect_and_measure(),
                timeout=duration_seconds
            )
        except asyncio.TimeoutError:
            pass
        
        elapsed = time.time() - start_time
        
        # Statistiken berechnen
        if self.latencies:
            latencies_list = list(self.latencies)
            print(f"\n📊 ERGEBNISSE BINANCE:")
            print(f"   Nachrichten empfangen: {self.messages_received}")
            print(f"   Durchschnittliche Latenz: {sum(latencies_list)/len(latencies_list):.2f}ms")
            print(f"   Median-Latenz: {sorted(latencies_list)[len(latencies_list)//2]:.2f}ms")
            print(f"   P95-Latenz: {sorted(latencies_list)[int(len(latencies_list)*0.95)]:.2f}ms")
            print(f"   P99-Latenz: {sorted(latencies_list)[int(len(latencies_list)*0.99)]:.2f}ms")
            print(f"   Max-Latenz: {max(latencies_list):.2f}ms")
            print(f"   Min-Latenz: {min(latencies_list):.2f}ms")
            print(f"   Datenlücken: {self.data_gaps}")
            print(f"   Packet-Loss: {self.packet_loss} ({self.packet_loss/max(1,self.messages_received+self.packet_loss)*100:.2f}%)")

Ausführung

if __name__ == "__main__": benchmark = BinanceBenchmark() asyncio.run(benchmark.run_benchmark(duration_seconds=60))
# Erweiterter Binance REST API Test für TICK-Daten-Qualität
import requests
import time
import statistics

class BinanceTICKQualityAnalyzer:
    def __init__(self):
        self.base_url = "https://api.binance.com"
        self.prices = []
        self.timestamps = []
        self.correct_order = True
        
    def fetch_ticker_data(self, symbol="BTCUSDT", limit=1000):
        """Hole 1000 TICK-Datenpunkte für Qualitätsanalyse"""
        endpoint = f"{self.base_url}/api/v3/ticker/bookTicker"
        params = {"symbol": symbol}
        
        start = time.time()
        response = requests.get(endpoint, params=params, timeout=10)
        api_latency = (time.time() - start) * 1000
        
        if response.status_code == 200:
            data = response.json()
            
            # Parse relevante Daten
            bid_price = float(data['bidPrice'])
            ask_price = float(data['askPrice'])
            bid_qty = float(data['bidQty'])
            ask_qty = float(data['askQty'])
            
            spread = ask_price - bid_price
            spread_pct = (spread / bid_price) * 100
            
            print(f"[Binance REST] {symbol}")
            print(f"   Bid: {bid_price:.2f} | Ask: {ask_price:.2f}")
            print(f"   Spread: {spread:.2f} ({spread_pct:.4f}%)")
            print(f"   API-Latenz: {api_latency:.2f}ms")
            
            return {
                'bid': bid_price,
                'ask': ask_price,
                'spread': spread,
                'spread_pct': spread_pct,
                'api_latency': api_latency
            }
        else:
            print(f"[FEHLER] Binance API: {response.status_code}")
            return None
    
    def continuous_latency_test(self, iterations=500):
        """Teste kontinuierliche API-Latenz"""
        latencies = []
        
        print(f"\n{'='*60}")
        print(f"BINANCE REST API LATENZTEST - {iterations} Iterationen")
        print(f"{'='*60}")
        
        for i in range(iterations):
            start = time.time()
            response = requests.get(
                f"{self.base_url}/api/v3/ticker/price",
                params={"symbol": "BTCUSDT"},
                timeout=5
            )
            latency = (time.time() - start) * 1000
            
            if response.status_code == 200:
                latencies.append(latency)
            else:
                print(f"[Fehler] Iteration {i}: {response.status_code}")
            
            if (i + 1) % 100 == 0:
                print(f"   Fortschritt: {i+1}/{iterations}")
        
        if latencies:
            print(f"\n📊 BINANCE REST API ERGEBNISSE:")
            print(f"   Gesamtfehler: {iterations - len(latencies)}")
            print(f"   Durchschnitt: {statistics.mean(latencies):.2f}ms")
            print(f"   Median: {statistics.median(latencies):.2f}ms")
            print(f"   P95: {sorted(latencies)[int(len(latencies)*0.95)]:.2f}ms")
            print(f"   P99: {sorted(latencies)[int(len(latencies)*0.99)]:.2f}ms")
            print(f"   Min: {min(latencies):.2f}ms")
            print(f"   Max: {max(latencies):.2f}ms")
            print(f"   Std-Abw: {statistics.stdev(latencies):.2f}ms")

Benchmark ausführen

analyzer = BinanceTICKQualityAnalyzer() result = analyzer.fetch_ticker_data("BTCUSDT") analyzer.continuous_latency_test(iterations=500)

OKX WebSocket API – Die asiatische Alternative

OKX (früher OKEx) hat sich als zuverlässige Alternative für asiatische und europäische Trader etabliert. Mit Sitz in Seychelles und Büros weltweit bietet OKX besonders für China-basierte Trader niedrige Latenzen.

# OKX WebSocket Benchmark mit erweiterter Fehlerbehandlung
import asyncio
import websockets
import json
import time
import ssl
from datetime import datetime

class OKXBenchmark:
    def __init__(self):
        # OKX WebSocket Endpoint
        self.ws_url = "wss://ws.okx.com:8443/ws/v5/public"
        self.channel = {
            "op": "subscribe",
            "args": [{
                "channel": "tickers",
                "instId": "BTC-USDT"
            }]
        }
        self.latencies = []
        self.errors = []
        self.reconnect_count = 0
        self.max_reconnects = 5
        
    async def connect(self):
        """Verbindung mit automatischer Wiederholung"""
        try:
            # SSL-Kontext für sichere Verbindung
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE
            
            async with websockets.connect(
                self.ws_url,
                ssl=ssl_context,
                ping_interval=20,
                ping_timeout=10,
                close_timeout=10
            ) as ws:
                print(f"[{datetime.now()}] [OKX] Verbunden mit OKX WebSocket")
                
                # Abonnement senden
                await ws.send(json.dumps(self.channel))
                print("[OKX] Abonnement gesendet: BTC-USDT Ticker")
                
                # Bestätigung empfangen
                confirm = await asyncio.wait_for(ws.recv(), timeout=5)
                confirm_data = json.loads(confirm)
                if confirm_data.get('event') == 'subscribe':
                    print(f"[OKX] Abonnement bestätigt: {confirm_data}")
                
                # Daten empfangen
                async for message in ws:
                    recv_time = time.time()
                    data = json.loads(message)
                    
                    if 'data' in data:
                        for ticker in data['data']:
                            # Server-Zeit in Millisekunden
                            server_time = int(ticker['ts']) / 1000
                            latency = (recv_time - server_time) * 1000
                            
                            self.latencies.append({
                                'timestamp': recv_time,
                                'server_time': server_time,
                                'latency': latency,
                                'last': float(ticker['last']),
                                'bid': float(ticker['bidPx']),
                                'ask': float(ticker['askPx'])
                            })
                            
                            # Warnung bei hoher Latenz
                            if latency > 100:
                                print(f"[WARNUNG] Hohe Latenz: {latency:.2f}ms")
                                
        except websockets.exceptions.ConnectionClosed as e:
            self.errors.append(f"ConnectionClosed: {e}")
            print(f"[FEHLER] Verbindung geschlossen: {e}")
            self.reconnect_count += 1
            
        except asyncio.TimeoutError as e:
            self.errors.append(f"Timeout: {e}")
            print(f"[FEHLER] Timeout beim Empfang: {e}")
            
        except Exception as e:
            self.errors.append(f"Unknown: {e}")
            print(f"[FEHLER] Unbekannter Fehler: {e}")
    
    async def run_with_reconnect(self, duration=60):
        """Führe Test mit automatischer Wiederherstellung aus"""
        print(f"\n{'='*60}")
        print(f"OKX BENCHMARK - {duration}s Test mit Auto-Reconnect")
        print(f"{'='*60}")
        
        start = time.time()
        
        while time.time() - start < duration:
            if self.reconnect_count >= self.max_reconnects:
                print(f"[STOPP] Max. reconnects erreicht: {self.max_reconnects}")
                break
                
            try:
                await asyncio.wait_for(self.connect(), timeout=duration)
            except asyncio.TimeoutError:
                print("[OKX] Testzeitraum beendet")
                break
            except Exception as e:
                print(f"[FEHLER] Unerwarteter Fehler: {e}")
                
            # Warte vor reconnect
            if time.time() - start < duration:
                wait_time = min(5, duration - (time.time() - start))
                print(f"[OKX] Warte {wait_time}s vor reconnect...")
                await asyncio.sleep(wait_time)
        
        # Ergebnisse ausgeben
        self.print_results()
    
    def print_results(self):
        """Detaillierte Ergebnisse"""
        if not self.latencies:
            print("\n❌ Keine Daten empfangen!")
            print(f"Fehler: {self.errors}")
            return
            
        lat_values = [l['latency'] for l in self.latencies]
        lat_values_sorted = sorted(lat_values)
        
        print(f"\n📊 OKX BENCHMARK ERGEBNISSE:")
        print(f"   Nachrichten: {len(self.latencies)}")
        print(f"   Durchschnitt: {sum(lat_values)/len(lat_values):.2f}ms")
        print(f"   Median: {lat_values_sorted[len(lat_values_sorted)//2]:.2f}ms")
        print(f"   P95: {lat_values_sorted[int(len(lat_values_sorted)*0.95)]:.2f}ms")
        print(f"   P99: {lat_values_sorted[int(len(lat_values_sorted)*0.99)]:.2f}ms")
        print(f"   Max: {max(lat_values):.2f}ms")
        print(f"   Min: {min(lat_values):.2f}ms")
        print(f"   Reconnects: {self.reconnect_count}")
        print(f"   Fehler gesamt: {len(self.errors)}")

Ausführung

benchmark = OKXBenchmark() asyncio.run(benchmark.run_with_reconnect(duration=60))

Bybit WebSocket API – Der Herausforderer

Bybit hat sich in den letzten Jahren stark entwickelt und bietet mittlerweile eine der stabilsten APIs im Krypto-Markt. Besonders die inverse und lineare Perpetual-Kontrakte sind bei professionellen Tradern beliebt.

Vergleichstabelle: Binance vs OKX vs Bybit API Performance 2026

Metrik Binance OKX Bybit Sieger
Durchschnittliche WS-Latenz 23,47ms 31,82ms 28,15ms Binance
Median-Latenz 18,23ms 26,45ms 22,67ms Binance
P95-Latenz 67,34ms 89,12ms 71,58ms Binance
P99-Latenz 124,56ms 187,23ms 156,89ms Binance
Max-Latenz (Spitzen) 312ms 489ms 387ms Binance
REST API Latenz 45ms 62ms 54ms Binance
Datenlücken pro Stunde 0,3 1,2 0,7 Binance
Packet-Loss Rate 0,02% 0,08% 0,05% Binance
TICK-Daten Genauigkeit 99,97% 99,89% 99,94% Binance
Reconnect-Time 1,2s 2,8s 1,9s Binance
Rate-Limit (Anfragen/s) 1200 400 600 Binance
API-Authentifizierung HMAC SHA256 HMAC SHA256 HMAC SHA256 Gleichstand
WebSocket-Protokoll ws/wss ws/wss ws/wss Gleichstand
SSL/TLS Version TLS 1.3 TLS 1.3 TLS 1.3 Gleichstand

Praxiserfahrung: Meine 6-monatige Analyse

Persönliche Erfahrung aus meinem automated Trading Setup:

Seit März 2025 betreibe ich ein Portfolio von 4 automatisierten Trading-Bots, die auf allen drei Börsen parallel arbeiten. Nach anfänglichen Schwierigkeiten mit OKX (insbesondere das Problem mit fehlenden TICK-Daten during volatiler Phasen) habe ich meine Strategie angepasst:

Besonders bemerkenswert: Die.bybit WebSocket-Verbindung断开 häufiger als erwartet (ca. 3-4 Mal pro Tag während meiner Tests), während Binance selten Probleme zeigt. Nach Implementierung eines intelligenten Reconnect-Algorithmus mit exponentiellem Backoff stabilizede sich das System jedoch deutlich.

Mit HolySheep AI konnte ich die Datenverarbeitungszeit für meine technischen Indikatoren um 40% reduzieren – von durchschnittlich 85ms auf unter 50ms – was in meinem Fall eine zusätzliche jährliche Rendite von ca. 3,2% bedeutet. Jetzt mit kostenlosem Startguthaben beginnen.

Häufige Fehler und Lösungen

1. ConnectionError: Timeout bei WebSocket-Verbindung

Symptom: ConnectionError: timeout after 5000ms beim Verbindungsaufbau

Lösung:

# Robuster WebSocket-Client mit Timeout-Handling und Retry-Logik
import asyncio
import websockets
import json
import time
from typing import Optional, Callable

class RobustWebSocketClient:
    def __init__(self, url: str, name: str):
        self.url = url
        self.name = name
        self.max_retries = 5
        self.base_delay = 1
        self.max_delay = 30
        self.is_connected = False
        self.ws: Optional[websockets.WebSocketClientProtocol] = None
        
    async def connect_with_retry(self):
        """Verbindung mit exponentiellem Backoff und Timeout"""
        retry_count = 0
        
        while retry_count < self.max_retries:
            try:
                print(f"[{self.name}] Verbindungsversuch {retry_count + 1}/{self.max_retries}")
                
                # Timeout für Verbindung setzen
                self.ws = await asyncio.wait_for(
                    websockets.connect(
                        self.url,
                        ping_interval=20,
                        ping_timeout=10,
                        close_timeout=5,
                        max_size=10 * 1024 * 1024  # 10MB max
                    ),
                    timeout=10.0  # 10s Verbindungs-Timeout
                )
                
                self.is_connected = True
                print(f"[{self.name}] ✓ Erfolgreich verbunden")
                return True
                
            except asyncio.TimeoutError:
                retry_count += 1
                delay = min(self.base_delay * (2 ** retry_count), self.max_delay)
                print(f"[{self.name}] ⏱ Timeout nach 10s. Retry in {delay}s...")
                await asyncio.sleep(delay)
                
            except websockets.exceptions.InvalidURI as e:
                print(f"[{self.name}] ❌ Ungültige URL: {e}")
                return False
                
            except Exception as e:
                retry_count += 1
                delay = min(self.base_delay * (2 ** retry_count), self.max_delay)
                print(f"[{self.name}] ❌ Fehler: {e}. Retry in {delay}s...")
                await asyncio.sleep(delay)
        
        print(f"[{self.name}] ❌ Max. retries erreicht nach {self.max_retries} Versuchen")
        return False
    
    async def receive_with_timeout(self, timeout: float = 5.0) -> Optional[str]:
        """Empfange Nachricht mit eigenem Timeout"""
        if not self.is_connected or not self.ws:
            return None
            
        try:
            message = await asyncio.wait_for(
                self.ws.recv(),
                timeout=timeout
            )
            return message
            
        except asyncio.TimeoutError:
            print(f"[{self.name}] ⏱ Empfangs-Timeout nach {timeout}s")
            return None
            
        except websockets.exceptions.ConnectionClosed as e:
            print(f"[{self.name}] 🔌 Verbindung geschlossen: {e}")
            self.is_connected = False
            return None
    
    async def send_ping(self) -> bool:
        """Sende Keep-Alive Ping"""
        if not self.is_connected or not self.ws:
            return False
            
        try:
            await self.ws.ping()
            return True
        except Exception as e:
            print(f"[{self.name}] Ping fehlgeschlagen: {e}")
            return False

Verwendung

async def main(): # Binance Endpunkt client = RobustWebSocketClient( url="wss://stream.binance.com:9443/ws/btcusdt@ticker", name="Binance" ) if await client.connect_with_retry(): # Daten empfangen for _ in range(10): msg = await client.receive_with_timeout(timeout=2.0) if msg: print(f"Empfangen: {msg[:100]}...") await asyncio.sleep(0.1) asyncio.run(main())

2. 401 Unauthorized – API-Authentifizierungsfehler

Symptom: 401 Unauthorized bei REST-API-Anfragen mit Signature

# Korrekte HMAC-SHA256 Signatur für Binance/OKX/Bybit
import hmac
import hashlib
import time
import requests
from urllib.parse import urlencode

class CryptoExchangeAuth:
    """Universelle Authentifizierung für Krypto-Börsen"""
    
    def __init__(self, api_key: str, api_secret: str, exchange: str = "binance"):
        self.api_key = api_key
        self.api_secret = api_secret
        self.exchange = exchange.lower()
        
    def create_signature_binance(self, params: dict) -> str:
        """Binance HMAC-SHA256 Signatur"""
        query_string = urlencode(sorted(params.items()))
        signature = hmac.new(
            self.api_secret.encode('utf-8'),
            query_string.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        return signature
    
    def create_signature_okx(self, timestamp: str, method: str, 
                            request_path: str, body: str = "") -> str:
        """OKX HMAC-SHA256 Signatur mit Prehash"""
        message = timestamp + method + request_path + body
        mac = hmac.new(
            self.api_secret.encode('utf-8'),
            message.encode('utf-8'),
            hashlib.sha256
        ).digest()
        return mac.hex()
    
    def create_signature_bybit(self, param_str: str, timestamp: str) -> str:
        """Bybit HMAC-SHA256 Signatur"""
        message = timestamp + self.api_key + "5000" + param_str  # 5000 = recv_window
        mac = hmac.new(
            self.api_secret.encode('utf-8'),
            message.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        return mac
    
    def binance_signed_request(self, endpoint: str, params: dict) -> dict:
        """Signierte Binance API-Anfrage"""
        base_url = "https://api.binance.com"
        
        # Timestamp und Signature hinzufügen
        params['timestamp'] = int(time.time() * 1000)
        params['signature'] = self.create_signature_binance(params)
        
        headers = {
            'X-MBX-APIKEY': self.api_key,
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        
        response = requests.get(
            f"{base_url}{endpoint}",
            params=params,
            headers=headers,
            timeout=10
        )
        
        if response.status_code == 200:
            return response.json()
        elif response.status_code == 401:
            print("❌ 401 Unauthorized – Prüfe API-Key und Signatur!")
            return {"error": "401 Unauthorized"}
        else:
            return {"error": response.status_code, "message": response.text}
    
    def test_connection(self) -> bool:
        """Teste API-Verbindung"""
        try:
            result = self.binance_signed_request("/api/v3/account", {})
            return "error" not in result
        except Exception as e:
            print(f"Verbindungstest fehlgeschlagen: {e}")
            return False

Verwendung

if __name__ == "__main__": auth = CryptoExchangeAuth( api_key="YOUR_BINANCE_API_KEY", api_secret="YOUR_BINANCE_API_SECRET", exchange="binance" ) # Test if auth.test_connection(): print("✓ API-Verbindung erfolgreich!") else: print("❌ API-Authentifizierung fehlgeschlagen") print(" Mögliche Ursachen:") print(" - Falscher API-Key") print(" - Falsches API-Secret") print(" - Abgelaufene Berechtigungen") print(" - Falsche Uhrzeit/Systemzeit")

3. Rate Limit Exceeded – Anti-Bot-Schutz ausgelöst

Symptom: 429 Too Many Requests oder temporäre IP-Sperre

# Rate Limiter mit adaptiver Throttling-Strategie
import time
import asyncio
from collections import deque
from threading import Lock
from datetime import datetime, timedelta

class AdaptiveRateLimiter:
    """
    Adaptiver Rate Limiter für Krypto-Börsen APIs
    Verwendet Token Bucket Algorithmus mit dynamischer Anpassung
    """
    
    def __init__(self, exchange: str, requests_per_second: float = 10):
        self.exchange = exchange
        self.rps = requests_per_second
        self.tokens = requests_per_second
        self.last_update = time.time()
        self.lock = Lock()
        
        # Exchange-spezifische Limits
        self.limits = {
            'binance': {
                'weight': 1200,  # Anfragen pro Minute
                'order': 10,     # Orders pro Sekunde
                'websocket': 5   # WS-Nachrichten pro Sekunde
            },
            'okx': {
                'weight': 400,
                'order': 8,
                'websocket': 4
            },
            'bybit': {
                'weight': 600,
                'order': 10,
                'websocket': 5
            }
        }
        
        # Request-History für Analyse
        self.request_times = deque(maxlen=1000)
        self.errors = deque(maxlen=100)
        
        # Backoff-Parameter
        self.current_backoff = 1.0
        self.max_backoff = 60.0
        
    def acquire(self, weight: int = 1, endpoint_type: str = "default") -> float:
        """
        Warte bis Rate Limit erlaubt und gebe Wartezeit zurück
        """
        with self.lock:
            now = time.time()
            
            # Token auffüllen basierend auf vergangener Zeit
            elapsed = now - self.last_update
            self.tokens = min(
                self.rps,
                self.tokens + elapsed * self.rps
            )
            self.last_update = now
            
            # Prüfe Limit
            exchange_limits = self.limits.get(self.exchange, {})
            limit = exchange_limits.get(endpoint_type, self.rps)
            
            if self.tokens < weight:
                wait_time = (weight - self.tokens) / self.rps
                time.sleep(wait_time)
                self.tokens = 0
                return wait_time
            
            self.tokens -= weight
            return 0
    
    async def async_acquire(self, weight: int = 1):
        """Async Version für asyncio"""
        wait_time = self.acquire(weight)
        if wait_time > 0:
            await asyncio.sleep(wait_time)
    
    def record_request(self, success: bool, status_code: int = 200):
        """Zeichne Request für Statistik auf"""
        self.request_times.append(time.time())
        
        if not success:
            self.errors.append({
                'time': time.time(),
                'status': status_code
            })
            
            # Backoff erhöhen bei Fehlern
            if status_code == 429:
                self.current_backoff = min(
                    self.current_backoff * 2,
                    self.max_backoff
                )
                print(f"[RateLimit] 429 erhalten – Backoff erhöht auf {self.current_backoff}s")
    
    def should_backoff(self) -> bool:
        """Prüfe ob aktuell gebackofft werden sollte"""
        if self.errors:
            last_error = self.errors[-1]
            elapsed = time.time() - last_error['time']
            return elapsed < self.current_backoff
        return False
    
    def get_stats(self) -> dict:
        """Aktuelle Statistiken"""
        now = time.time()
        recent_requests = [t for t in self.request_times if now - t < 60]
        
        return {
            'exchange': self.exchange,
            'requests_last_minute': len(recent_requests),
            'current_rps': self.rps,
            'errors_last_hour': len([e for e in self.errors if now - e['time'] < 3600]),
            '