Sie haben sich jemals gefragt, warum Ihre Bybit-Orders manchmal zu einem anderen Preis ausgeführt werden als geplant? In diesem Tutorial lernen Sie, wie Sie mit Tardis-machine Ihre Bybit-Handelsdaten lokal analysieren und Slippage (滑点) präzise identifizieren können.
Was ist Slippage und warum ist es wichtig?
Slippage bezeichnet die Differenz zwischen dem erwarteten Ausführungspreis und dem tatsächlichen Preis einer Order. Stellen Sie sich vor:
- Sie setzen eine Buy-Order bei $50.000
- Die Order wird tatsächlich bei $50.050 ausgeführt
- Die Differenz von $50 ist Ihr Slippage-Verlust
Nach diesem Tutorial können Sie:
- Ihre Bybit-Handelshistorie herunterladen
- Daten lokal mit Tardis-machine analysieren
- Slippage-Muster erkennen und optimieren
Voraussetzungen
- Bybit-Konto mit Handelshistorie
- Python 3.8+ installiert
- Grundlegende Kommandozeilen-Kenntnisse
- Stable Internetverbindung
Schritt 1: Bybit API-Key erstellen
Melden Sie sich bei Bybit an und navigieren Sie zu:
Dashboard → API-Management → Neuen API-Key erstellen
Wichtige Einstellungen:
- Aktivieren Sie "Read-Only" für maximale Sicherheit
- Wählen Sie nur benötigte Berechtigungen
- Speichern Sie Key und Secret sicher
💡 Profi-Tipp: Verwenden Sie niemals Write-Berechtigungen für Analyse-Tools!
Schritt 2: Tardis-machine installieren
Tardis-machine ist ein lokales Analyse-Tool für Krypto-Handelsdaten. Die Installation ist unkompliziert:
# Installation über pip
pip install tardis-machine
Oder mit pipx für isolierte Umgebung
pipx install tardis-machine
Überprüfung der Installation
tardis --version
Schritt 3: Bybit-Daten herunterladen
Es gibt zwei Methoden, Ihre Handelsdaten zu erhalten:
Methode A: Direkter Download von Bybit
- Loggen Sie sich bei Bybit ein
- Gehen Sie zu "Trade History"
- Filtern Sie nach gewünschtem Zeitraum
- Klicken Sie auf "Export CSV"
Methode B: API-Abruf mit Python
#!/usr/bin/env python3
"""
Bybit Trade Data Fetcher
Sicherer Download Ihrer Handelsdaten
"""
import requests
import time
import csv
from datetime import datetime, timedelta
============= KONFIGURATION =============
BYBIT_API_KEY = "YOUR_BYBIT_API_KEY"
BYBIT_API_SECRET = "YOUR_BYBIT_API_SECRET"
SYMBOL = "BTCUSDT" # oder Ihr gewünschtes Paar
START_DATE = "2026-01-01"
END_DATE = "2026-04-30"
Bybit API Endpunkt
BASE_URL = "https://api.bybit.com"
def get_trade_history():
"""Holt Ihre Handelshistorie von Bybit"""
endpoint = "/v5/account/execution"
params = {
"category": "spot", # oder "linear" für Futures
"symbol": SYMBOL,
"startTime": int(datetime.fromisoformat(START_DATE).timestamp() * 1000),
"endTime": int(datetime.fromisoformat(END_DATE).timestamp() * 1000),
"limit": 100 # Max 100 pro Anfrage
}
headers = {
"X-BAPI-API-KEY": BYBIT_API_KEY,
"X-BAPI-SIGN-TYPE": "2",
# In Produktion: Signatur hier generieren
}
try:
response = requests.get(
f"{BASE_URL}{endpoint}",
params=params,
headers=headers,
timeout=30
)
response.raise_for_status()
data = response.json()
if data.get("retCode") == 0:
return data.get("result", {}).get("list", [])
else:
print(f"API Fehler: {data.get('retMsg')}")
return []
except requests.exceptions.RequestException as e:
print(f"Netzwerkfehler: {e}")
return []
def calculate_slippage(trades):
"""Berechnet Slippage für jeden Trade"""
slippage_results = []
for trade in trades:
# Extrahieren der relevanten Daten
order_price = float(trade.get("orderPrice", 0))
exec_price = float(trade.get("execPrice", 0))
side = trade.get("side", "")
qty = float(trade.get("execQty", 0))
# Slippage berechnen
if order_price > 0:
slippage_pct = ((exec_price - order_price) / order_price) * 100
# Anpassung für Buy/Sell
if side == "Sell":
slippage_pct = -slippage_pct # Negativ = gut für Verkäufer
slippage_value = abs(exec_price - order_price) * qty
slippage_results.append({
"Zeitstempel": trade.get("execTime"),
"Symbol": trade.get("symbol"),
"Seite": side,
"Order-Preis": order_price,
"Ausführungspreis": exec_price,
"Slippage %": round(slippage_pct, 4),
"Slippage $": round(slippage_value, 2),
"Menge": qty,
"Trade-ID": trade.get("execId")
})
return slippage_results
============= HAUPTPROGRAMM =============
if __name__ == "__main__":
print("📊 Starte Bybit Slippage-Analyse...")
print(f"Zeitraum: {START_DATE} bis {END_DATE}")
print("-" * 50)
trades = get_trade_history()
if trades:
print(f"✓ {len(trades)} Trades gefunden")
results = calculate_slippage(trades)
# Statistiken
total_slippage = sum(r["Slippage $"] for r in results)
avg_slippage = total_slippage / len(results) if results else 0
max_slippage = max((r["Slippage $"] for r in results), default=0)
print(f"\n📈 Slippage-Statistik:")
print(f" Gesamte Slippage-Kosten: ${total_slippage:.2f}")
print(f" Durchschnittliche Slippage: ${avg_slippage:.2f}")
print(f" Maximale Slippage: ${max_slippage:.2f}")
# CSV exportieren
output_file = f"bybit_slippage_{SYMBOL}_{START_DATE}.csv"
with open(output_file, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=results[0].keys())
writer.writeheader()
writer.writerows(results)
print(f"\n✓ Daten exportiert nach: {output_file}")
else:
print("⚠ Keine Trades gefunden oder API-Fehler")
Schritt 4: Daten mit Tardis-machine analysieren
#!/usr/bin/env python3
"""
Tardis-machine Slippage-Analyse
Analysiert Ihre Handelsdaten lokal
"""
import json
import csv
from datetime import datetime
from collections import defaultdict
Tardis-machine bietet verschiedene Analyse-Module
pip install tardis-machine[analysis]
class SlippageAnalyzer:
"""Analysiert Slippage-Muster aus Bybit-Daten"""
def __init__(self, data_file):
self.data_file = data_file
self.trades = []
self.load_data()
def load_data(self):
"""Lädt Trades aus CSV oder JSON"""
with open(self.data_file, "r") as f:
if self.data_file.endswith(".json"):
self.trades = json.load(f)
else:
reader = csv.DictReader(f)
self.trades = list(reader)
print(f"✓ {len(self.trades)} Trades geladen")
def analyze_by_hour(self):
"""Analysiert Slippage nach Handelsstunde"""
hourly_slippage = defaultdict(list)
for trade in self.trades:
timestamp = int(trade.get("Zeitstempel", 0))
hour = datetime.fromtimestamp(timestamp/1000).hour
slippage = float(trade.get("Slippage $", 0))
hourly_slippage[hour].append(slippage)
print("\n🕐 Slippage nach Stunde:")
print("-" * 40)
for hour in sorted(hourly_slippage.keys()):
slips = hourly_slippage[hour]
avg = sum(slips) / len(slips)
count = len(slips)
print(f" {hour:02d}:00 Uhr - Ø Slippage: ${avg:.2f} (n={count})")
def analyze_by_symbol(self):
"""Analysiert Slippage pro Handelspaar"""
symbol_slippage = defaultdict(lambda: {"total": 0, "count": 0})
for trade in self.trades:
symbol = trade.get("Symbol", "Unknown")
slippage = float(trade.get("Slippage $", 0))
symbol_slippage[symbol]["total"] += slippage
symbol_slippage[symbol]["count"] += 1
print("\n📊 Slippage nach Paar:")
print("-" * 40)
for symbol, data in sorted(
symbol_slippage.items(),
key=lambda x: x[1]["total"],
reverse=True
):
avg = data["total"] / data["count"]
print(f" {symbol}: ${data['total']:.2f} total, Ø ${avg:.2f}")
def find_outliers(self, threshold_pct=0.5):
"""Findet Trades mit ungewöhnlich hoher Slippage"""
outliers = []
for trade in self.trades:
slippage_pct = float(trade.get("Slippage %", 0))
if abs(slippage_pct) > threshold_pct:
outliers.append(trade)
if outliers:
print(f"\n⚠️ {len(outliers)} Ausreißer gefunden (> {threshold_pct}%):")
for trade in outliers[:10]: # Zeige Top 10
print(f" ID: {trade.get('Trade-ID')[:16]}...")
print(f" Zeit: {trade.get('Zeitstempel')}")
print(f" Slippage: {trade.get('Slippage %')}%")
else:
print(f"\n✓ Keine Ausreißer gefunden")
return outliers
def generate_report(self, output_file="slippage_report.html"):
"""Generiert HTML-Bericht"""
html = f"""
<!DOCTYPE html>
<html>
<head>
<title>Slippage Analyse Bericht</title>
<style>
body {{ font-family: Arial, sans-serif; padding: 20px; }}
table {{ border-collapse: collapse; width: 100%; }}
th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
th {{ background-color: #4CAF50; color: white; }}
.warning {{ background-color: #fff3cd; }}
</style>
</head>
<body>
<h1>Bybit Slippage Analyse Bericht</h1>
<p>Erstellt: {datetime.now().strftime('%Y-%m-%d %H:%M')}</p>
<h2>Zusammenfassung</h2>
<ul>
<li>Gesamte Trades: {len(self.trades)}</li>
<li>Gesamte Slippage-Kosten: ${sum(float(t.get('Slippage $', 0)) for t in self.trades):.2f}</li>
</ul>
<h2>Top Slippage Trades</h2>
<table>
<tr>
<th>Zeit</th><th>Symbol</th><th>Seite</th>
<th>Slippage %</th><th>Slippage $</th>
</tr>
"""
# Sortiere nach Slippage
sorted_trades = sorted(
self.trades,
key=lambda x: float(x.get("Slippage $", 0)),
reverse=True
)
for trade in sorted_trades[:50]:
html += f"""
<tr class="{'warning' if abs(float(trade.get('Slippage %', 0))) > 0.5 else ''}">
<td>{trade.get('Zeitstempel')}</td>
<td>{trade.get('Symbol')}</td>
<td>{trade.get('Seite')}</td>
<td>{trade.get('Slippage %')}</td>
<td>{trade.get('Slippage $')}</td>
</tr>
"""
html += """