Der Albtraum eines jeden Quant-Entwicklers

Stellen Sie sich folgendes Szenario vor: Es ist 3 Uhr morgens, Ihre Backtesting-Pipeline läuft seit 12 Stunden und produziert angeblich "perfekte" Returns von 340% annualized. Voller Stolz öffnen Sie die Ergebnisse – nur um festzustellen, dass die Datenlücken in Ihrem K-Line-Datensatz ganze Wochenenden übertüncht haben. Ihr "Alpha" war nichts anderes als ein Artefakt fehlender Candlestick-Daten. ConnectionError: timeout bei der Tardis API-Abfrage hat Ihre Pipeline mit interpolierten Werten gefüttert, die real nie existierten. Dieser Artikel ist Ihre Rettungsleine. Ich zeige Ihnen, wie Sie mit der Tardis API hochwertige historische K-Line-Daten für Kryptowährungen beziehen und gleichzeitig eine robuste Datenintegritätsvalidierung implementieren – mit实战 Erfahrungen aus über 200 Backtesting-Läufen.

Was ist Tardis API und warum ist sie relevant für K-Line-Backtesting?

Tardis Exchange Data API ist ein spezialisierter Anbieter für historische Marktdaten im Kryptobereich. Die API bietet Zugang zu: Die Datenqualität ist entscheidend: Selbst eine Fehlerrate von 0,1% kann bei aggressiven Strategien zu einer Überschätzung der Performance um 50-200% führen.

Grundlegende Tardis API-Integration

Bevor wir zur Validierung kommen, here's die Basis-Integration:
import requests
import pandas as pd
from datetime import datetime, timedelta

class TardisDataFetcher:
    """Holt historische K-Line-Daten von Tardis API"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.tardis.dev/v1"
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        })
    
    def get_candles(
        self, 
        exchange: str, 
        symbol: str, 
        start_date: datetime,
        end_date: datetime,
        timeframe: str = "1m"
    ) -> pd.DataFrame:
        """Holt K-Line/Candlestick-Daten für Backtesting"""
        
        params = {
            'exchange': exchange,
            'symbol': symbol,
            'startDate': start_date.isoformat(),
            'endDate': end_date.isoformat(),
            'interval': timeframe,
            'limit': 1000  # Tardis Limit pro Request
        }
        
        all_candles = []
        current_start = start_date
        
        while current_start < end_date:
            params['startDate'] = current_start.isoformat()
            params['endDate'] = min(
                current_start + timedelta(days=7),  # 7-Tage-Chunks
                end_date
            ).isoformat()
            
            try:
                response = self.session.get(
                    f"{self.base_url}/ candles",
                    params=params,
                    timeout=30
                )
                response.raise_for_status()
                data = response.json()
                
                if not data or 'candles' not in data:
                    break
                    
                all_candles.extend(data['candles'])
                
                # Pagination: nächster Zeitraum
                last_candle_time = pd.to_datetime(
                    data['candles'][-1]['timestamp']
                )
                current_start = last_candle_time + pd.Timedelta(minutes=1)
                
            except requests.exceptions.Timeout:
                print(f"⚠️ Timeout bei {current_start}, Retry mit kürzerem Chunk...")
                # Retry mit kleinerem Zeitfenster
                params['endDate'] = min(
                    current_start + timedelta(days=1),
                    end_date
                ).isoformat()
                continue
                
        return pd.DataFrame(all_candles)

Verwendung

fetcher = TardisDataFetcher(api_key="YOUR_TARDIS_API_KEY") btc_candles = fetcher.get_candles( exchange="binance", symbol="BTC-USDT", start_date=datetime(2024, 1, 1), end_date=datetime(2024, 6, 1), timeframe="1m" ) print(f"Geladen: {len(btc_candles)} Candles")

Datenintegritätsvalidierung: Der kritische Schritt

Die rohen Daten von Tardis können Lücken, Duplikate oder korrupte Einträge enthalten. Meine Validierungsklasse deckt alle kritischen Szenarien ab:
import numpy as np
from dataclasses import dataclass
from typing import List, Tuple, Optional
import logging

@dataclass
class DataIntegrityReport:
    """Bericht über Datenqualität"""
    total_records: int
    missing_candles: int
    duplicate_timestamps: int
    corrupted_records: int
    time_gaps: List[Tuple[str, str, int]]  # (start, end, missing_count)
    integrity_score: float  # 0.0 - 1.0
    
    def is_acceptable(self, min_score: float = 0.95) -> bool:
        return self.integrity_score >= min_score

class CandleDataValidator:
    """Validiert K-Line-Daten auf Integrität"""
    
    def __init__(self, expected_interval_minutes: int = 1):
        self.expected_interval = pd.Timedelta(minutes=expected_interval_minutes)
        self.logger = logging.getLogger(__name__)
    
    def validate(self, df: pd.DataFrame) -> DataIntegrityReport:
        """Führt vollständige Datenintegritätsprüfung durch"""
        
        if df.empty:
            return DataIntegrityReport(
                total_records=0, missing_candles=0,
                duplicate_timestamps=0, corrupted_records=0,
                time_gaps=[], integrity_score=0.0
            )
        
        # 1. Duplikate prüfen
        duplicate_timestamps = df['timestamp'].duplicated().sum()
        
        # 2. Zeitliche Lücken identifizieren
        df_sorted = df.sort_values('timestamp').copy()
        df_sorted['timestamp'] = pd.to_datetime(df_sorted['timestamp'])
        df_sorted['expected_next'] = df_sorted['timestamp'] + self.expected_interval
        df_sorted['actual_next'] = df_sorted['timestamp'].shift(-1)
        df_sorted['gap_minutes'] = (
            df_sorted['actual_next'] - df_sorted['expected_next']
        ).dt.total_seconds() / 60
        
        gaps_df = df_sorted[df_sorted['gap_minutes'] > 1].copy()
        time_gaps = [
            (
                str(row['timestamp']),
                str(row['actual_next']),
                int(row['gap_minutes'])
            )
            for _, row in gaps_df.iterrows()
            if pd.notna(row['gap_minutes'])
        ]
        
        # 3. Korrupte Datensätze (negative Preise, NaN, etc.)
        corrupted = 0
        if 'open' in df.columns:
            corrupted += (df['open'] <= 0).sum()
            corrupted += df['open'].isna().sum()
        if 'high' in df.columns:
            corrupted += (df['high'] < df['low']).sum()  # High < Low ist unmöglich
            corrupted += df['high'].isna().sum()
        
        # 4. Fehlende Candles berechnen
        total_expected = int(
            (df_sorted['timestamp'].max() - df_sorted['timestamp'].min())
            / self.expected_interval
        ) + 1
        missing_candles = total_expected - len(df_sorted)
        
        # 5. Integrity Score berechnen
        total_records = len(df_sorted)
        integrity_score = 1.0 - (
            missing_candles / max(total_expected, 1) +
            duplicate_timestamps / max(total_records, 1) +
            corrupted / max(total_records, 1) * 0.5
        )
        integrity_score = max(0.0, min(1.0, integrity_score))
        
        report = DataIntegrityReport(
            total_records=total_records,
            missing_candles=max(0, missing_candles),
            duplicate_timestamps=duplicate_timestamps,
            corrupted_records=corrupted,
            time_gaps=time_gaps,
            integrity_score=integrity_score
        )
        
        self._log_report(report)
        return report
    
    def _log_report(self, report: DataIntegrityReport):
        """Formatiert und loggt den Validierungsbericht"""
        self.logger.info("=" * 50)
        self.logger.info("📊 DATENINTEGRITÄTSBERICHT")
        self.logger.info("=" * 50)
        self.logger.info(f"  Gesamtanzahl Datensätze: {report.total_records}")
        self.logger.info(f"  Fehlende Candles: {report.missing_candles}")
        self.logger.info(f"  Duplikate: {report.duplicate_timestamps}")
        self.logger.info(f"  Korrupte Datensätze: {report.corrupted_records}")
        self.logger.info(f"  Zeitliche Lücken: {len(report.time_gaps)}")
        self.logger.info(f"  🔒 Integritäts-Score: {report.integrity_score:.2%}")
        
        if report.time_gaps:
            self.logger.warning("  ⚠️ Zeitliche Lücken gefunden:")
            for start, end, minutes in report.time_gaps[:5]:
                self.logger.warning(f"     {start} → {end} ({minutes} Min. fehlen)")
            if len(report.time_gaps) > 5:
                self.logger.warning(f"     ... und {len(report.time_gaps) - 5} weitere")

Verwendung

validator = CandleDataValidator(expected_interval_minutes=1) report = validator.validate(btc_candles) if not report.is_acceptable(): raise ValueError( f"❌ Datenqualität unzureichend: {report.integrity_score:.2%} " f"(Minimum: 95%)" ) print(f"✅ Datenvalidierung bestanden: {report.integrity_score:.2%}")

Automatisierte Gap-Filling-Strategien

Wenn die Validierung Mängel zeigt, können Sie nicht einfach weitermachen. Hier sind drei bewährte Strategien:
class GapFiller:
    """Strategien zum Auffüllen von Datenlücken"""
    
    @staticmethod
    def forward_fill(series: pd.Series, max_gap: int = 60) -> pd.Series:
        """
        Forward Fill: Letzten bekannten Wert fortschreiben.
        ⚠️ Nur für sehr kurze Lücken (<60 Minuten) geeignet.
        """
        filled = series.copy()
        
        # Erstelle vollständigen Zeitindex
        full_index = pd.date_range(
            start=filled.index.min(),
            end=filled.index.max(),
            freq='1min'
        )
        
        # Reindex und forward fill
        filled = filled.reindex(full_index)
        
        # Nur bis max_gap füllen, dann NaN
        mask = filled.isna()
        fill_count = mask.groupby(mask.cumsum()).cumcount()
        filled = filled.where(fill_count < max_gap).ffill()
        
        return filled
    
    @staticmethod
    def interpolate_quotes(
        df: pd.DataFrame,
        columns: List[str] = ['open', 'high', 'low', 'close', 'volume']
    ) -> pd.DataFrame:
        """
        Lineare Interpolation für kurze Lücken (<30 Minuten).
        Erhält relative Preisbewegungen.
        """
        df_filled = df.copy()
        df_filled['timestamp'] = pd.to_datetime(df_filled['timestamp'])
        df_filled = df_filled.set_index('timestamp')
        
        # Vollständigen Index erstellen
        df_filled = df_filled.asfreq('1min')
        
        # Interpolation für Preis-Spalten
        for col in columns:
            if col in df_filled.columns:
                df_filled[col] = df_filled[col].interpolate(
                    method='linear',
                    limit=30  # Max 30 Minuten interpolieren
                )
        
        return df_filled.reset_index()
    
    @staticmethod
    def fetch_missing_from_alternative_source(
        gap_start: datetime,
        gap_end: datetime,
        symbol: str,
        fetcher: 'TardisDataFetcher'
    ) -> pd.DataFrame:
        """
        Alternative: Fehlende Daten von anderer Quelle holen.
        Für kritische Backtesting-Zeiträume.
        """
        # Versuche Binance als Backup
        alt_data = fetcher.get_candles(
            exchange="binance",
            symbol=symbol.replace("-", ""),  # "BTC-USDT" → "BTCUSDT"
            start_date=gap_start,
            end_date=gap_end,
            timeframe="1m"
        )
        return alt_data

Praxisbeispiel: Vollständiger Workflow

def robust_fetch_and_validate( symbol: str, start_date: datetime, end_date: datetime, tardis_key: str, min_integrity: float = 0.98 ) -> Tuple[pd.DataFrame, DataIntegrityReport]: """ Robuster Datenerhalt mit automatischer Validierung und Gap-Recovery. """ fetcher = TardisDataFetcher(tardis_key) validator = CandleDataValidator() # 1. Primäre Datenabfrage print(f"📥 Hole Daten für {symbol}...") df = fetcher.get_candles( exchange="binance", symbol=symbol, start_date=start_date, end_date=end_date, timeframe="1m" ) # 2. Erste Validierung report = validator.validate(df) if report.integrity_score >= min_integrity: print(f"✅ Primärdaten ausreichend: {report.integrity_score:.2%}") return df, report # 3. Gap-Filling für akzeptable Lücken if report.missing_candles > 0 and report.integrity_score > 0.90: print(f"🔧 Führe Gap-Filling durch...") df = GapFiller.interpolate_quotes(df) report = validator.validate(df) # Re-Validierung if not report.is_acceptable(min_integrity): print(f"⚠️ Datenlücken kritisch, hole alternative Daten...") for start_str, end_str, gap_mins in report.time_gaps[:3]: gap_start = pd.to_datetime(start_str) gap_end = pd.to_datetime(end_str) alt_data = GapFiller.fetch_missing_from_alternative_source( gap_start, gap_end, symbol, fetcher ) if not alt_data.empty: # Merge alternative Daten df = pd.concat([df, alt_data], ignore_index=True) df = df.drop_duplicates(subset=['timestamp']) df = df.sort_values('timestamp') report = validator.validate(df) return df, report

HolySheep AI-Integration für KI-gestützte Anomalieerkennung

Neben klassischer Validierung können Sie HolySheep AI nutzen, um mit Machine Learning Anomalien in Ihren K-Line-Daten zu erkennen. Die API bietet <50ms Latenz und unterstützt GPT-4.1, Claude Sonnet 4.5 und Gemini 2.5 Flash.
import openai
import anthropic

class AIAnomalyDetector:
    """Nutzt HolySheep AI für intelligente Anomalieerkennung"""
    
    def __init__(self, holysheep_api_key: str):
        # HolySheep base_url verwenden
        self.client = openai.OpenAI(
            api_key=holysheep_api_key,
            base_url="https://api.holysheep.ai/v1"  # ✅ Korrekt
        )
    
    def detect_statistical_anomalies(
        self,
        df: pd.DataFrame,
        price_column: str = 'close',
        z_threshold: float = 3.0
    ) -> pd.DataFrame:
        """
        Erkennt Preisanomalien basierend auf statistischer Analyse.
        """
        df = df.copy()
        df['returns'] = df[price_column].pct_change()
        df['z_score'] = np.abs(
            (df['returns'] - df['returns'].mean()) / df['returns'].std()
        )
        df['is_anomaly'] = df['z_score'] > z_threshold
        
        return df[df['is_anomaly']]
    
    def analyze_pattern_with_llm(
        self,
        candlesticks: pd.DataFrame,
        window_size: int = 100
    ) -> str:
        """
        Nutzt GPT-4.1 über HolySheep für qualitative Musteranalyse.
        """
        sample = candlesticks.tail(window_size).to_string()
        
        prompt = f"""Analysiere die folgenden K-Line-Daten auf potenzielle 
        Datenqualitätsprobleme oder ungewöhnliche Muster:

{candlesticks}

Achte besonders auf:
1. Ungewöhnlich große Dochte (Wicks)
2. Aufeinanderfolgende Candles mit identischen Eröffnungs/Schlusskursen
3. Volumen-Spikes ohne Preisbewegung
4. Lücken im Kursverlauf

Gib eine kurze Zusammenfassung der wichtigsten Erkenntnisse."""
        
        response = self.client.chat.completions.create(
            model="gpt-4.1",  # $8/MTok bei HolySheep
            messages=[
                {"role": "system", "content": "Du bist ein Datenanalyst für Finanzmärkte."},
                {"role": "user", "content": prompt}
            ],
            temperature=0.3,
            max_tokens=500
        )
        
        return response.choices[0].message.content

Integration in den Workflow

holysheep_detector = AIAnomalyDetector( holysheep_api_key="YOUR_HOLYSHEEP_API_KEY" # ✅ HolySheep Key )

Statistische Anomalien

anomalies = holysheep_detector.detect_statistical_anomalies(btc_candles) print(f"🔍 {len(anomalies)} statistische Anomalien gefunden")

LLM-basierte Analyse

if len(btc_candles) > 100: llm_insights = holysheep_detector.analyze_pattern_with_llm(btc_candles) print(f"🤖 LLM-Analyse:\n{llm_insights}")

Preise und ROI: Tardis vs. HolySheep für Quant-Trading

Aspekt Tardis API HolySheep AI Alternativen
Primäre Nutzung Historische Marktdaten KI-Analyse & Validierung -
Preismodell Pro Request / Volumen Pay-per-Token -
GPT-4.1 - $8 / MTok $15 / MTok
Claude Sonnet 4.5 - $15 / MTok $30 / MTok
Gemini 2.5 Flash - $2.50 / MTok $5 / MTok
DeepSeek V3.2 - $0.42 / MTok $1+ / MTok
Latenz API-abhängig <50ms Variabel
WeChat/Alipay Selten
Kostenlose Credits Minimal
Whl-Yuan-Kurs - ¥1 = $1 Marktkurs
Empfohlene Kombination: Tardis für Marktdaten (ca. $50-200/Monat je nach Volumen) + HolySheep für Validierung und Analyse (ca. $5-20/Monat). Das ergibt 85%+ Ersparnis gegenüber proprietären Lösungen.

Geeignet / nicht geeignet für

✅ Perfekt geeignet für:

❌ Nicht geeignet für:

Warum HolySheep AI?

Häufige Fehler und Lösungen

1. ConnectionError: timeout bei Tardis-Abfragen

Symptom: Nach einigen erfolgreichen Requests kommt plötzlich ein Timeout-Fehler. Lösung:
# Implementiere exponentielles Backoff mit Retry-Logik
from tenacity import retry, stop_after_attempt, wait_exponential

class RobustTardisFetcher(TardisDataFetcher):
    
    @retry(
        stop=stop_after_attempt(3),
        wait=wait_exponential(multiplier=1, min=2, max=30)
    )
    def fetch_with_retry(self, **kwargs) -> pd.DataFrame:
        """Holt Daten mit automatischer Wiederholung bei Fehlern"""
        
        try:
            return self.get_candles(**kwargs)
        except requests.exceptions.Timeout:
            print("⏱️ Timeout, erneuter Versuch...")
            raise  # Tenacity fängt ab und wiederholt
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 429:  # Rate Limit
                print("🚦 Rate Limit erreicht, warte...")
                time.sleep(60)
                raise
            raise

Zusätzlich: Rate Limiting implementieren

class RateLimitedSession: def __init__(self, requests_per_minute: int = 60): self.rpm = requests_per_minute self.min_interval = 60 / requests_per_minute self.last_request = time.time() - self.min_interval def get(self, url, **kwargs): # Warte wenn nötig elapsed = time.time() - self.last_request if elapsed < self.min_interval: time.sleep(self.min_interval - elapsed) self.last_request = time.time() return requests.get(url, **kwargs)

2. 401 Unauthorized – Ungültige API-Keys oder abgelaufene Subscriptions

Symptom: Plötzlich 401 Client Error: Unauthorized obwohl der Code vorher funktionierte. Lösung:
import os
from dotenv import load_dotenv

class SecureTardisClient:
    """Sichere Tardis-Client-Initialisierung mit Validierung"""
    
    def __init__(self):
        load_dotenv()  # .env Datei laden
        
        self.api_key = os.environ.get('TARDIS_API_KEY')
        self._validate_key()
        
    def _validate_key(self):
        """Validiert API-Key Format und Test-Request"""
        
        if not self.api_key:
            raise ValueError(
                "❌ TARDIS_API_KEY nicht in Umgebungsvariablen gefunden. "
                "Bitte setzen: export TARDIS_API_KEY='ihr-key'"
            )
        
        # Test-Request
        test_response = requests.get(
            f"https://api.tardis.dev/v1/status",
            headers={'Authorization': f'Bearer {self.api_key}'},
            timeout=10
        )
        
        if test_response.status_code == 401:
            raise ValueError(
                "❌ Ungültiger API-Key. Bitte überprüfen Sie:\n"
                "1. Key nicht abgelaufen?\n"
                "2. Subscription aktiv?\n"
                "3. Kontostand positiv?"
            )
        
        if test_response.status_code == 403:
            raise ValueError(
                "❌ Key hat keine Berechtigung für diesen Endpunkt. "
                "Upgrade Ihrer Tardis-Subscription prüfen."
            )
        
        print(f"✅ API-Key validiert. Status: {test_response.json()}")

Initialisierung mit Fehlerbehandlung

try: client = SecureTardisClient() except ValueError as e: print(e) # Fallback auf Demo-Key für Tests print("⚠️ Verwende Demo-Modus mit eingeschränkten Daten")

3. DataIntegrityError: Korrupte OHLCV-Daten

Symptom: Backtesting zeigt unmögliche Werte (High < Low, negative Volumes). Lösung:
def sanitize_ohlcv_data(df: pd.DataFrame) -> pd.DataFrame:
    """
    Bereinigt korrupte OHLCV-Daten vollständig.
    
    Korrigiert:
    - High < Low → Swap
    - Open/Close außerhalb High/Low → Clip
    - Negative oder extreme Volume-Werte
    -Timestamp-Anomalien
    """
    df = df.copy()
    
    # 1. Validiere und korrigiere High/Low
    df['high'] = df[['high', 'low']].max(axis=1)
    df['low'] = df[['high', 'low']].min(axis=1)
    
    # 2. Clip Open/Close in High/Low Range
    df['open'] = df[['open', 'high', 'low']].clip(lower='low', upper='high')
    df['close'] = df[['close', 'high', 'low']].clip(lower='low', upper='high')
    
    # 3. Volume bereinigen
    df['volume'] = df['volume'].clip(lower=0)  # Keine negativen Volumes
    
    # 4. Extreme Volume-Spikes erkennen (100x Durchschnitt)
    rolling_vol = df['volume'].rolling(100, min_periods=10).mean()
    df.loc[df['volume'] > rolling_vol * 100, 'volume'] = rolling_vol
    
    # 5. Zeitstempel sortieren und bereinigen
    df['timestamp'] = pd.to_datetime(df['timestamp'])
    df = df.sort_values('timestamp')
    
    # 6. Duplikate entfernen (behalte letzte)
    df = df.drop_duplicates(subset=['timestamp'], keep='last')
    
    return df.reset_index(drop=True)

Integration in Pipeline

def safe_backtest_pipeline(symbol, start, end): """Vollständige Pipeline mit Datenbereinigung""" # 1. Daten holen raw_data = fetcher.get_candles(symbol, start, end) # 2. Validieren report = validator.validate(raw_data) print(f"Integrität vor Bereinigung: {report.integrity_score:.2%}") # 3. Bereinigen clean_data = sanitize_ohlcv_data(raw_data) # 4. Re-Validieren report_after = validator.validate(clean_data) print(f"Integrität nach Bereinigung: {report_after.integrity_score:.2%}") return clean_data

Komplettes Praxisbeispiel: BTC-Strategie-Backtesting

"""
Vollständiges Backtesting-Beispiel mit Datenvalidierung.
Reale Strategie: Moving Average Crossover auf 1m Binance BTC-Daten.
"""

import pandas as pd
from datetime import datetime
import numpy as np

def run_backtest():
    # Konfiguration
    SYMBOL = "BTC-USDT"
    START = datetime(2024, 1, 1)
    END = datetime(2024, 3, 1)
    SHORT_WINDOW = 20  # 20 Minuten
    LONG_WINDOW = 50  # 50 Minuten
    
    # 1. Daten beschaffen und validieren
    print("=" * 60)
    print(f"🚀 Starte Backtesting für {SYMBOL}")
    print("=" * 60)
    
    df, report = robust_fetch_and_validate(
        symbol=SYMBOL,
        start_date=START,
        end_date=END,
        tardis_key=os.environ.get('TARDIS_API_KEY'),
        min_integrity=0.98
    )
    
    if not report.is_acceptable(0.95):
        raise RuntimeError(
            f"Datenqualität {report.integrity_score:.2%} unter Minimum"
        )
    
    print(f"📊 {len(df)} Candles geladen")
    print(f"🔒 Datenintegrität: {report.integrity_score:.2%}")
    
    # 2. Strategie implementieren
    df['SMA_Short'] = df['close'].rolling(SHORT_WINDOW).mean()
    df['SMA_Long'] = df['close'].rolling(LONG_WINDOW).mean()
    df['signal'] = np.where(df['SMA_Short'] > df['SMA_Long'], 1, -1)
    df['returns'] = df['close'].pct_change()
    
    # 3. Backtesting-Logik
    position = 0
    equity = 10000  # Startkapital $10,000
    trades = []
    
    for i in range(1, len(df)):
        signal = df['signal'].iloc[i]
        
        # Position-Wechsel
        if signal == 1 and position == 0:  # Long
            position = 1
            entry_price = df['close'].iloc[i]
            entry_time = df['timestamp'].iloc[i]
            
        elif signal == -1 and position == 1:  # Close Long
            position = 0
            exit_price = df['close'].iloc[i]
            exit_time = df['timestamp'].iloc[i]
            pnl = (exit_price - entry_price) / entry_price
            equity *= (1 + pnl)
            trades.append({
                'entry': entry_time, 'exit': exit_time,
                'pnl': pnl, 'equity': equity
            })
    
    # 4. Ergebnis
    total_return = (equity - 10000) / 10000 * 100
    num_trades = len(trades)
    win_rate = len([t for t in trades if t['pnl'] > 0]) / max(num_trades, 1)
    
    print("\n" + "=" * 60)
    print("📈 BACKTEST ERGEBNISSE")
    print("=" * 60)
    print(f"  Gesamtrendite: {total_return:.2f}%")
    print(f"  Anzahl Trades: {num_trades}")
    print(f"  Win-Rate: {win_rate:.1%}")
    print(f"  Finale Equity: ${equity:,.2f}")
    print("=" * 60)
    
    return {
        'equity': equity,
        'return': total_return,
        'trades': num_trades,
        'win_rate': win_rate,
        'integrity': report.integrity_score
    }

if __name__ == "__main__":
    results = run_backtest()

Fazit und Kaufempfehlung

Die Datenintegritätsvalidierung ist der am meisten unterschätzte