← Alle Insights

EUR/USD Mean-Reversion: das Hauptpaar systematisch handeln.

EUR/USD ist statistisch das mean-reverting-freundlichste Paar im FX-Markt. Über Stunden- und Tages-Horizonte kehrt der Kurs konsistent zu rollierenden Mittelwerten zurück. Wer diese Eigenschaft sauber misst und mit Filtern kombiniert, baut sich eine der robustesten Strategien im Forex-Universum.

Warum EUR/USD mean-reverting ist.

Drei strukturelle Faktoren erklären die Tendenz: erstens die schiere Liquidität — EUR/USD ist das meistgehandelte Paar der Welt mit über 1,3 Billionen USD täglichem Volumen. Diese Liquidität glättet Übertreibungen, weil Carry-Trader und Hedger permanent gegen Extreme positionieren. Zweitens die geringe Zins-Differenz zwischen EZB und Fed in den letzten Jahren — fehlende Carry-Belohnung reduziert Trend-Akkumulation. Drittens makroökonomische Kopplung: USA und Eurozone bewegen sich oft synchron im Wirtschaftszyklus, was extreme Divergenzen schnell korrigiert.

Empirisch lässt sich das mit dem Hurst-Exponenten messen: bei EUR/USD liegt er auf Stundenbasis um 0,42–0,45 — klar im mean-reverting Bereich (Werte unter 0,5). Zum Vergleich: USD/JPY liegt oft bei 0,50–0,55 (Random Walk bis leicht trending), GBP/USD um 0,48.

Das Basis-Setup: Z-Score-Mean-Reversion.

Das einfachste mean-reverting-Setup nutzt einen rollierenden Z-Score: Sie berechnen den Mittelwert und die Standardabweichung des Preises über die letzten N Stunden, und gehen short, wenn der Z-Score über +2 steigt, long, wenn er unter -2 fällt. Exit bei Rückkehr zum Mittelwert.

import pandas as pd
import numpy as np

def zscore_mean_reversion(prices, window=50, entry_z=2.0, exit_z=0.3):
    """
    Mean-Reversion via Z-Score auf EUR/USD-Stundendaten.
    prices: pd.Series der Schlusskurse.
    """
    df = prices.to_frame('close')
    df['mean'] = df['close'].rolling(window).mean()
    df['std'] = df['close'].rolling(window).std()
    df['z'] = (df['close'] - df['mean']) / df['std']

    # Signal: -1 = short, 1 = long, 0 = flat
    df['signal'] = 0
    df.loc[df['z'] > entry_z, 'signal'] = -1
    df.loc[df['z'] < -entry_z, 'signal'] = 1

    # Position: halte bis Z zurueck unter exit_z faellt
    df['position'] = 0
    pos = 0
    for i in range(len(df)):
        z = df['z'].iloc[i]
        if pos == 0:
            if z > entry_z: pos = -1
            elif z < -entry_z: pos = 1
        else:
            if abs(z) < exit_z: pos = 0
        df.iat[i, df.columns.get_loc('position')] = pos

    df['return'] = df['close'].pct_change()
    df['strat_return'] = df['return'] * df['position'].shift(1).fillna(0)
    df['equity'] = (1 + df['strat_return']).cumprod()
    return df

Warum naive Z-Score-Strategien scheitern.

Auf historischen Daten sieht das Setup oft brillant aus — bis es live geht und in der ersten echten Trendphase wegläuft. Mean-Reversion-Strategien haben ein charakteristisches Risikoprofil: viele kleine Gewinne, gelegentlich ein großer Verlust. Genau dann, wenn EUR/USD wirklich in einen Trend übergeht (Draghi „whatever it takes", Trump-Wahl, Covid-Schock), verliert die Strategie mehrfach in Folge.

Das ist kein Bug, das ist die Natur des Setups. Wer Mean-Reversion handelt, muss zwei Dinge tun: erstens das Setup so filtern, dass Trend-Phasen erkannt werden; zweitens das Position-Sizing so wählen, dass Verlust-Cluster überlebt werden.

Filter für Regime-Erkennung.

Half-Life als Holding-Period-Indikator.

Eine elegante Methode zur Bestimmung der erwarteten Haltezeit ist die Half-Life einer mean-reverting Zeitreihe. Sie misst, wie schnell der Kurs zu seinem Mittelwert zurückkehrt — und gibt Ihnen damit einen empirischen Anhaltspunkt für Stop-Time und Exit.

import numpy as np
import pandas as pd
from statsmodels.regression.linear_model import OLS

def half_life(prices):
    """
    Schaetzt die Mean-Reversion-Half-Life via OLS auf delta_p = a + b*p_lag.
    Return: erwartete Bars bis Rueckkehr zum halben Distance.
    """
    p = pd.Series(prices).dropna()
    p_lag = p.shift(1).dropna()
    delta = (p - p.shift(1)).dropna()
    p_lag = p_lag.iloc[-len(delta):]
    X = np.column_stack([np.ones(len(p_lag)), p_lag.values])
    res = OLS(delta.values, X).fit()
    b = res.params[1]
    if b >= 0:
        return np.inf  # nicht mean-reverting
    return -np.log(2) / b

hl = half_life(eurusd_hourly['close'].iloc[-500:])
print(f"Half-Life: {hl:.1f} Stunden")

Liegt die Half-Life bei 6–12 Stunden, ist EUR/USD im klassischen mean-reverting Regime — Setup aktiv. Steigt sie über 48 Stunden, ist der Markt im Trend-Modus — Strategie pausieren.

Risikomanagement bei Mean-Reversion.

Mean-Reversion verlangt asymmetrisches Risiko-Management. Da Verluste bei Trendphasen größer sein können als der durchschnittliche Gewinn, müssen Sie:

  1. Risiko pro Trade niedriger ansetzen als bei Trend-Strategien — 0,25–0,4 % statt 1 %.
  2. Time-Stop einbauen: schließen Sie Trades, die länger als 3 × Half-Life offen sind, unabhängig vom P&L. Wenn die Reversion nicht kommt, ist das Setup invalide.
  3. Hard-Stop bei 2,5 × Entry-Abstand zum Mittelwert. Wenn der Z-Score von 2 auf 4 läuft, ist die Annahme gebrochen.
  4. Drawdown-Limit: bei -5 % Strategie-Drawdown Pause für 14 Tage. Verlust-Cluster sind häufig Regime-Wechsel-Signale.

Was realistisch erwartbar ist.

Eine sauber gefilterte EUR/USD-Mean-Reversion-Strategie auf Stundenbasis liefert historisch (2010–2025) zwischen 8–12 % p.a. mit Sharpe-Ratios von 0,9–1,2 und maximalen Drawdowns um 8–10 %. Das klingt unspektakulär — und ist es auch. Genau das ist der Punkt: Mean-Reversion-Setups sind keine Performance-Maschinen, sondern stabile Sharpe-Beiträge in einem diversifizierten Strategie-Portfolio.

Wer 30 % p.a. mit Mean-Reversion verspricht, hat entweder schlecht backgetestet oder extrem überoptimiert. Realistische Erwartungen schützen vor schlechten Live-Entscheidungen.

Sie wollen eine Mean-Reversion-Strategie aufsetzen oder Ihr bestehendes Setup stresstesten? Erstgespräch buchen — wir gehen Filter, Half-Life und Regime-Erkennung gemeinsam durch.