← Alle Insights

Walk-Forward-Validierung für ML-Trading.

Wer ein ML-Modell im Trading mit klassischem k-fold-Cross-Validation evaluiert, betrügt sich selbst. Zeitreihen brauchen eine eigene Methodik: Walk-Forward. Richtig gemacht ist sie der ehrlichste Stresstest, den ein Modell durchlaufen kann. Falsch gemacht reproduziert sie genau dieselben Bias-Probleme, die sie verhindern soll.

Warum k-fold im Trading falsch ist.

Bei k-fold-CV werden Beobachtungen zufällig in Folds aufgeteilt. Trainings- und Validierungs-Beobachtungen liegen zeitlich vermischt vor. Damit lernt das Modell implizit Zustände der Zukunft, die es nutzt, um Vergangenheit vorherzusagen — und die Performance sieht großartig aus, bis es live geht.

Selbst TimeSeriesSplit von scikit-learn ist nur eine erste Annäherung. Es schützt vor Zukunft im Training, lässt aber andere Probleme offen: feature-engineering mit gloablen Statistiken, scaler-fit auf der gesamten Reihe, hyperparameter-tuning ohne harten Out-of-Sample-Teil.

Die drei Walk-Forward-Varianten.

Welche Variante richtig ist, hängt vom Markt ab. Für trendstabile Assets mit langen Regimen ist Expanding oft besser. Für regimewechselanfällige Märkte — Rolling. Wer unsicher ist, testet beide und vergleicht die Streuung der Out-of- Sample-Performance.

Implementierung in Python.

import numpy as np
import pandas as pd

def walk_forward_splits(n, train_size, val_size, step, mode="rolling"):
    splits = []
    start = 0
    while True:
        train_end = start + train_size
        val_end = train_end + val_size
        if val_end > n:
            break
        train_idx = np.arange(0 if mode == "expanding" else start, train_end)
        val_idx = np.arange(train_end, val_end)
        splits.append((train_idx, val_idx))
        start += step
    return splits

def walk_forward_eval(X, y, model_factory, train_size, val_size, step):
    splits = walk_forward_splits(len(X), train_size, val_size, step)
    metrics = []
    for tr, va in splits:
        model = model_factory()
        # WICHTIG: Scaler/Feature-Pipelines nur auf tr fitten
        model.fit(X.iloc[tr], y.iloc[tr])
        pred = model.predict(X.iloc[va])
        metrics.append({
            "start": X.index[va[0]],
            "end": X.index[va[-1]],
            "ic": np.corrcoef(pred, y.iloc[va])[0, 1],
        })
    return pd.DataFrame(metrics)

Embargo und Purging.

Wenn die Zielvariable aus mehreren Tagen aggregiert ist — etwa 5-Tages-Forward- Return — überlappen Trainings- und Validierungs-Labels. Ein Beispiel: ein Sample am letzten Trainings-Tag enthält implizit das Label der nächsten fünf Tage, also der ersten Tage der Validierung. Das ist subtiler Leakage.

Die Lösung: Purging und Embargo. Marcos López de Prado hat das in "Advances in Financial Machine Learning" formal beschrieben.

def purged_split(train_idx, val_idx, label_horizon, embargo):
    val_start = val_idx[0]
    val_end = val_idx[-1]
    # Purging: Trainings-Samples raus, deren Label in Validierung reichen
    keep = train_idx[(train_idx + label_horizon) < val_start]
    # Embargo: zusaetzliche Pufferzone
    keep = keep[keep < val_start - embargo]
    return keep, val_idx

Hyperparameter-Tuning ohne Selbstbetrug.

Wer 200 Hyperparameter-Kombinationen über Walk-Forward laufen lässt und die beste auswählt, hat aus dem Walk-Forward einen verkleideten In-Sample-Test gemacht. Die korrekte Architektur:

  1. Walk-Forward innerhalb des Trainings-Universums für Hyperparameter-Wahl.
  2. Einen harten, separaten Out-of-Sample-Block am Ende, der nie für Tuning angefasst wird.
  3. Endgültige Performance wird ausschließlich auf diesem letzten Block berichtet.

Wenn der Out-of-Sample-Block deutlich schlechter aussieht als der Walk-Forward- Mittelwert, haben Sie überoptimiert. Lieber jetzt feststellen als im Live-Betrieb.

Was Sie aus den Walk-Forward-Ergebnissen lesen.

Nicht nur der Mittelwert der Out-of-Sample-Metriken zählt. Mindestens genauso wichtig:

Retraining-Frequenz: wie oft ist sinnvoll?

Zu seltenes Retraining heißt veraltete Modelle. Zu häufiges Retraining heißt Overfitting auf jüngste Daten und höheren Operationsaufwand. Praktische Faustregel: Tagesbar-Modelle alle 4–12 Wochen, Intraday-Modelle alle 1–4 Wochen, hochfrequente Modelle täglich oder kontinuierlich. Die genaue Frequenz lässt sich empirisch ermitteln, indem man im Walk-Forward verschiedene Retraining-Intervalle vergleicht.

Sie wollen Ihr ML-Trading-Setup an einer realistischen Walk-Forward-Pipeline validieren? Erstgespräch buchen — wir bauen die Validierung so auf, dass das Modell hält, was der Backtest verspricht.