Pairs-Trading und Kointegration einfach erklärt
Kointegration ist die Grundlage für Pairs-Trading, Korrelation nicht. Ermitteln Sie Hedge-Ratio, Spread und z-Score anhand realer Schlusskurse und von Hand.
Pairs-Trading und Kointegration gehören zusammen: Der Trade beruht auf einer Differenz zwischen zwei Aktienkursen, die immer wieder auf ein stabiles Niveau zurückkehrt. Kointegration ist die statistische Eigenschaft, die besagt, dass eine solche Differenz überhaupt existiert. Die Korrelation misst etwas anderes. Zwei Aktien können eine hohe Korrelation aufweisen und sich dennoch dauerhaft auseinanderentwickeln. Umgekehrt können zwei Aktien, deren tägliche Kursbewegungen kaum übereinstimmen, über Jahre eine stabile Differenz aufweisen. Diese Seite leitet Hedge-Ratio, Spread und z-Score von Hand her, misst alle drei Größen anhand realer Schlusskurse und widmet sich anschließend ebenso ausführlich den Schwächen dieser Konstruktion.
Was bedeutet Kointegration im Pair-Trading?
Korrelation beschreibt, wie eng sich die täglichen prozentualen Kursbewegungen zweier Aktien zueinander verhalten. Sie reicht von -1 bis +1. +1 bedeutet, dass beide Aktien in jeder Sitzung des betrachteten Zeitraums gemeinsam gestiegen oder gefallen sind. Über den Abstand zwischen den beiden Kursen sagt die Korrelation nichts aus.
Kointegration bezieht sich auf diesen Abstand. Ziehen Sie von Aktie B ein festes Vielfaches von Aktie A ab und betrachten Sie den verbleibenden Wert. Wenn diese verbleibende Zeitreihe, der Spread, innerhalb einer begrenzten Bandbreite bleibt, statt sich immer weiter zu entfernen, sind die beiden Titel kointegriert. Die Kurse selbst können sich in jede Richtung bewegen. Die Kombination aus ihnen kann es nicht.
Das Bild aus Lehrbüchern zeigt einen Hund an der Leine. Der Spaziergänger und der Hund bewegen sich auf unvorhersehbaren Wegen die Straße entlang. Die Leine begrenzt jedoch den Abstand zwischen ihnen. Die Korrelation fragt, ob sich beide im selben Moment bewegen. Die Kointegration fragt, ob die Leine hält.
Die folgende Tabelle misst das erste Konzept anhand von fünf bekannten Paaren in den Jahren 2024 und 2025. Die Spalte return_corr zeigt die Korrelation der täglichen prozentualen Kursbewegungen. Das ist normalerweise mit dem Begriff gemeint. Die Spalte price_corr zeigt die Korrelation der unveränderten Schlusskurse. Diese Kennzahl fällt bei fast allen Titeln günstig aus, die beide gestiegen sind.
Das exakte SQL hinter jeder Zahl
WITH
px AS (
SELECT
ticker,
date,
toFloat64(any(close)) AS close_px
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('KO', 'PEP', 'HD', 'LOW', 'XOM', 'CVX', 'V', 'MA', 'AAPL', 'MSFT')
AND date BETWEEN '2024-01-01' AND '2025-12-31'
GROUP BY ticker, date
),
rets AS (
SELECT
ticker,
date,
close_px,
close_px / lagInFrame(close_px) OVER (
PARTITION BY ticker ORDER BY date
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
) - 1 AS ret
FROM px
)
SELECT
p.pair AS pair,
round(corr(a.ret, b.ret), 3) AS return_corr,
round(corr(a.close_px, b.close_px), 3) AS price_corr
FROM
(
SELECT
tupleElement(t, 1) AS leg_a,
tupleElement(t, 2) AS leg_b,
tupleElement(t, 3) AS pair
FROM
(
SELECT arrayJoin([
('KO', 'PEP', 'KO / PEP'),
('HD', 'LOW', 'HD / LOW'),
('XOM', 'CVX', 'XOM / CVX'),
('V', 'MA', 'V / MA'),
('AAPL', 'MSFT', 'AAPL / MSFT')
]) AS t
)
) AS p
INNER JOIN rets AS a ON a.ticker = p.leg_a
INNER JOIN rets AS b ON b.ticker = p.leg_b AND b.date = a.date
WHERE isFinite(a.ret) AND isFinite(b.ret)
GROUP BY pair
ORDER BY return_corr DESCNach der Korrelation der täglichen Kursbewegungen liegt HD / LOW mit 0.868 an der Spitze der Tabelle. Die Korrelation der beiden Kursniveaus im selben Zeitraum betrug 0.849. In der letzten Zeile weist AAPL / MSFT eine Renditekorrelation von 0.479 und eine Preiskorrelation von 0.508 auf. Keine der beiden Spalten beantwortet die Frage, die sich ein Pair-Trader stellt. Beide messen die gemeinsame Bewegung. Für den Trade wird jedoch ein Maß für den Abstand benötigt.
Wie berechnen Sie die Hedge-Ratio und den Spread?
Fünf Schritte in fester Reihenfolge über zwei Listen mit Schlusskursen. Reines Python deckt alles ab, wobei math der einzige Import ist: keine Pakete, kein Datenanbieter, kein Netzwerk.
- Jede Zeitreihe zentrieren.
mean_a = sum(a) / len(a)und entsprechend auch die Listeb. - Die Hedge-Ratio schätzen. Sie ist die Steigung einer Geraden von B in Abhängigkeit von A:
beta = sum((a[i] - mean_a) * (b[i] - mean_b) for i in range(len(a))) / sum((x - mean_a) ** 2 for x in a). Sie gibt an, wie viele Einheiten von A eine Einheit von B ausgleichen. - Den Spread bilden.
spread = [b[i] - beta * a[i] for i in range(len(a))]. Bei einem kointegrierten Paar bewegt sich diese Zeitreihe um ein bestimmtes Niveau, statt einem Trend zu folgen. - Ein nachlaufendes Zeitfenster verwenden. Mit
w = spread[i - win + 1 : i + 1]beträgt der Mittelwert des Fenstersmu = sum(w) / len(w), die Stichprobenstandardabweichungsd = math.sqrt(sum((x - mu) ** 2 for x in w) / (len(w) - 1)). Nachlaufend bedeutet, dass das Fenster am jeweils bewerteten Tag endet und keine späteren Werte verwendet. - Standardisieren und ausgeben.
z = (spread[i] - mu) / sd, anschließend eine Einstiegsmeldung ausgeben, solangeabs(z) > 1.5, und eine Ausstiegsmeldung ausgeben, sobaldabs(z) < 0.5. Ein z-Wert von 2 bedeutet, dass der Spread zwei Standardabweichungen über seinem eigenen jüngsten Mittelwert liegt.
Zwei fest codierte Preislisten reichen aus, um diesen Ablauf zu beobachten. Ein win von 5 hält das Spielbeispiel übersichtlich. Für ernsthafte Anwendungen wird eher ein Zeitraum von 63 Sitzungen verwendet, also etwa ein Quartal. Die Schwellenwerte von 1,5 für den Einstieg und 0,5 für den Ausstieg sind Konventionen, die von einem Tutorial zum nächsten übernommen werden. Sie sind keine empirischen Befunde. Auch die folgenden Panels basieren nicht auf diesen Werten.
Wie sieht ein Z-Score im Pair-Trading bei realen Kursen aus?
Hier ist dieselbe Berechnung für die beiden bekannten Getränkekonzerne KO und PEP. Die Hedge-Ratio wird ausschließlich anhand der Schlusskurse von 2023 ermittelt und bleibt im gesamten von der Grafik abgedeckten Zeitraum 2024 und 2025 unverändert. Die Steigung anhand derselben Stichprobe zu schätzen, die anschließend für die Bewertung verwendet wird, ist Look-ahead-Bias im Backtesting. Eine getrennte Schätz- und Bewertungsperiode ist die einfachste Absicherung dagegen.
Das exakte SQL hinter jeder Zahl
WITH
daily AS (
SELECT
date,
anyIf(toFloat64(close), ticker = 'PEP') AS pep,
anyIf(toFloat64(close), ticker = 'KO') AS ko
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('KO', 'PEP')
AND date BETWEEN '2023-01-01' AND '2025-12-31'
GROUP BY date
HAVING pep > 0 AND ko > 0
),
fitted AS (
SELECT covarSamp(pep, ko) / varSamp(ko) AS beta
FROM daily
WHERE date < '2024-01-01'
),
spread AS (
SELECT
daily.date AS date,
daily.pep - fitted.beta * daily.ko AS spread_usd
FROM daily
CROSS JOIN fitted
),
scored AS (
SELECT
date,
(spread_usd - avg(spread_usd) OVER (
ORDER BY date ROWS BETWEEN 62 PRECEDING AND CURRENT ROW))
/ stddevSampStable(spread_usd) OVER (
ORDER BY date ROWS BETWEEN 62 PRECEDING AND CURRENT ROW) AS z
FROM spread
)
SELECT
toString(toMonday(date)) AS week,
round(argMax(z, date), 2) AS z_score
FROM scored
WHERE date >= '2024-01-01'
AND isFinite(z)
GROUP BY week
ORDER BY weekDie Zeitreihe umfasst 105 Wochenwerte. Zu Beginn liegt der Z-Score bei -1.53, am Ende bei -0.68. Entscheidend ist der Verlauf, nicht ein einzelner Wert. Ein Pair, das sich wie von der Strategie angenommen verhält, überschreitet seinen Schwellenwert, bewegt sich einige Wochen zurück in Richtung null und überschreitet ihn anschließend erneut. Ein Pair, das nicht mehr zum Mittelwert zurückkehrt, bleibt jenseits des Schwellenwerts. In der Grafik erscheint das als lange, flache Strecke mit großem Abstand zur Mitte.
Kommt ein kointegrierter Spread immer zurück?
Nein. Die belastbare Antwort ergibt sich daraus, was auf jeden Ausgangspunkt folgte. Die folgende Darstellung ordnet jede Sitzung von 2019 bis Ende 2025 anhand des Z-Scores des jeweiligen Tages in Gruppen ein. Anschließend wird der durchschnittliche Z-Score desselben Spreads zwanzig Sitzungen später ausgewiesen. Verwendet wird der Logarithmus des Kursverhältnisses und kein geschätzter Spread. Eine nachträglich durchgeführte Regression beeinflusst die Darstellung daher nicht.
Das exakte SQL hinter jeder Zahl
WITH
daily AS (
SELECT
date,
anyIf(toFloat64(close), ticker = 'PEP') AS pep,
anyIf(toFloat64(close), ticker = 'KO') AS ko
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('KO', 'PEP')
AND date BETWEEN '2018-01-01' AND '2025-12-31'
GROUP BY date
HAVING pep > 0 AND ko > 0
),
spread AS (
SELECT
date,
log(pep / ko) AS log_ratio
FROM daily
),
scored AS (
SELECT
date,
(log_ratio - avg(log_ratio) OVER (
ORDER BY date ROWS BETWEEN 62 PRECEDING AND CURRENT ROW))
/ stddevSampStable(log_ratio) OVER (
ORDER BY date ROWS BETWEEN 62 PRECEDING AND CURRENT ROW) AS z
FROM spread
),
horizon AS (
SELECT
date,
z,
leadInFrame(z, 20) OVER (
ORDER BY date ROWS BETWEEN CURRENT ROW AND 20 FOLLOWING
) AS z_fwd
FROM scored
WHERE isFinite(z)
)
SELECT
multiIf(z < -2, 'z below -2',
z < -1, 'z -2 to -1',
z < 0, 'z -1 to 0',
z < 1, 'z 0 to 1',
z < 2, 'z 1 to 2',
'z above 2') AS z_bucket,
round(avg(z), 2) AS avg_z_start,
round(avg(z_fwd), 2) AS avg_z_20d_later,
count() AS episode_count
FROM horizon
WHERE date >= '2019-01-01'
AND date <= '2025-11-15'
AND isFinite(z_fwd)
GROUP BY z_bucket
ORDER BY avg_z_startDie Sitzungen, die in der z below -2-Gruppe begannen, wiesen an diesem Tag im Durchschnitt -2.42 auf. Zwanzig Sitzungen später lag der durchschnittliche Z-Score desselben Spreads bei -0.84. Dies gilt für 138 Sitzungen. Am anderen Ende begann die z above 2-Gruppe bei 2.64. Zwanzig Sitzungen später lag der Wert bei 0.92. Eine Kurve, die sich von beiden Seiten zur Nulllinie bewegt, entspricht dem typischen Muster einer Mean-Reversion.
Beziehen Sie die Spalte mit der Anzahl der Sitzungen in die Betrachtung ein. Die äußeren Gruppen enthalten die wenigsten Sitzungen. Außerdem überschneiden sich die Sitzungen innerhalb einer Gruppe stark. Daher liefern einige wenige lange Phasen den Großteil der Beobachtungen. Ein Durchschnitt ist keine Zusage für einen einzelnen Einstieg.
Warum funktioniert Pairs Trading nicht mehr?
Das Hedge-Verhältnis ist keine Konstante. Es wird in jedem Kalenderjahr neu geschätzt und verändert sich.
Das exakte SQL hinter jeder Zahl
WITH daily AS (
SELECT
date,
anyIf(toFloat64(close), ticker = 'PEP') AS pep,
anyIf(toFloat64(close), ticker = 'KO') AS ko,
anyIf(toFloat64(close), ticker = 'LOW') AS lowes,
anyIf(toFloat64(close), ticker = 'HD') AS hd
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('KO', 'PEP', 'HD', 'LOW')
AND date BETWEEN '2019-01-01' AND '2025-12-31'
GROUP BY date
HAVING ko > 0 AND pep > 0 AND hd > 0 AND lowes > 0
)
SELECT
toYear(date) AS year,
round(covarSamp(pep, ko) / varSamp(ko), 3) AS pep_on_ko_beta,
round(covarSamp(lowes, hd) / varSamp(hd), 3) AS lowes_on_hd_beta
FROM daily
GROUP BY year
ORDER BY yearDie Steigung von PEP gegenüber KO, gemessen 2.338 über 2019 sowie -0.543 über 2025. Das zweite Sektorpaar dient zum Vergleich. Ein Backtest, der eine einzige Steigung über die gesamte Historie schätzt und ab dem ersten Tag damit handelt, weist jedem frühen Trade eine Kennzahl zu, die zu diesem Zeitpunkt niemand hätte besitzen können. Die Lösung ist unspektakulär, aber wirksam: Schätzen Sie das Verhältnis anhand eines rollierenden Zeitfensters neu und bewerten Sie jeden Tag mit den an diesem Tag verfügbaren Parametern. Ein reproduzierbarer Backtest macht diese Vorgehensweise für andere überprüfbar.
Unternehmensmaßnahmen verändern eine Position über Nacht. Bei einem four-for-one-Split wird aus einer Aktie vier, während sich der angezeigte Kurs viertelt. Ein Spread, der über diesen Tag hinweg auf nicht adjustierten Kursen berechnet wird, springt dadurch auf ein Niveau, zu dem nie gehandelt wurde. Fusionen, Abspaltungen und Indexänderungen bewirken dasselbe auf weniger offensichtliche Weise. Beginnen Sie mit einer um Splits bereinigten Kurshistorie. Beachten Sie außerdem, dass ein Ticker einem völlig anderen Unternehmen zugewiesen werden kann. Das ist der Grund, warum Ticker-Symbole Datensätze beschädigen.
Ein Strukturbruch und eine Chance sehen während ihres Auftretens gleich aus. Der höchste jemals beobachtete z-Score eines Paars ist entweder der beste Einstieg, den es je gab, oder die erste Woche einer beendeten Beziehung. Am jeweiligen Tag sehen beide Fälle wie ein stark ausgedehnter Spread aus. Die Positionsgröße übernimmt die Aufgabe, die die Statistik nicht erfüllen kann: Positionsgrößenbestimmung nach dem Kelly-Kriterium und Positionsgrößenbestimmung nach Volatilitätsziel sind zwei Ansätze dafür, wie stark ein einzelner Spread ein Konto bewegen darf. Der maximale Drawdown zeigt, was eine lange Positionierung auf der falschen Seite des Mittelwerts mit einer Eigenkapitalkurve macht.
Ein rollierender z-Score ist kein Kointegrationstest. Es gibt formale Tests. Das Engle-Granger-Verfahren führt zunächst die Regression durch und prüft anschließend, ob der verbleibende Spread stationär ist. Der Johansen-Test erweitert diesen Ansatz über zwei Titel hinaus. Ein z-Score setzt die von diesen Tests geprüfte Eigenschaft voraus. Er kann problemlos einen hohen Wert für einen Spread ausweisen, dessen Mittelwert überhaupt nicht stabil ist, weil eine Trendserie immer weit von ihrem eigenen rollierenden Durchschnitt entfernt sein kann.
Datenhinweise und was diese Zahlen nicht abbilden
Das Korrelationspanel verwendet tägliche Schlusskurse vom 2024-01-01 bis zum 2025-12-31. Die Renditen werden aus aufeinanderfolgenden Schlusskursen berechnet, wobei die jeweils erste Sitzung eines Titels entfällt. Für die z-Score-Zeitreihe wird das Hedge-Verhältnis ausschließlich anhand der Schlusskurse von 2023 geschätzt. Anschließend werden 2024 und 2025 mit einem rollierenden Mittelwert über 63 Sitzungen und der Stichprobenstandardabweichung bewertet. Die Werte werden jeweils zum letzten Messwert der Woche erfasst. Das Reversionspanel lädt die Historie ab 2018 und weist Werte ab 2019 aus. Jeder bewertete Tag verfügt daher über ein vollständiges rollierendes Zeitfenster. Die Auswertung endet Mitte November 2025, sodass innerhalb der Stichprobe für jeden Tag zwanzig Folgesitzungen verfügbar sind.
Keines dieser Panels stellt eine Strategie dar. Handelskosten, der Bid-Ask-Spread, Leihgebühren für die Short-Position, Dividenden und Finanzierungskosten werden nicht berücksichtigt. Verwendet werden ausschließlich Schlusskurse. Ein Einstieg zum Schlusskurs wäre daher ein Einstieg, zu dem niemand tatsächlich hätte ausführen können.
FAQ
Was ist der Unterschied zwischen Korrelation und Kointegration?
Die Korrelation misst, ob sich zwei Aktien an denselben Tagen und in dieselbe Richtung bewegen. Sie wird auf einer Skala von -1 bis +1 angegeben. Die Kointegration misst, ob der Abstand zwischen ihren Kursen innerhalb einer stabilen Bandbreite bleibt. Ein Paar kann bei der Korrelation einen hohen Wert erreichen und bei der Kointegration scheitern. Das ist der übliche Grund dafür, dass ein Korrelationsfilter Paare hervorbringt, die anschließend auseinanderdriften.
Wie berechnet man die Hedge-Ratio im Pair-Trading?
Sie passen eine Gerade an, die den Kurs der einen Aktie gegen den Kurs der anderen beschreibt, und verwenden die Steigung. Diese Steigung gibt an, wie viele Einheiten der ersten Aktie eine Einheit der zweiten Aktie ausgleichen. Sie verändert sich im Zeitverlauf. Deshalb wird die Regression in den meisten Implementierungen über ein rollierendes Zeitfenster erneut geschätzt und nicht nur einmal für den gesamten Beobachtungszeitraum.
Welchen z-Score verwenden Pair-Trader für Ein- und Ausstiege?
In Lehrbeispielen erfolgt der Einstieg meist bei etwa 1,5 bis zwei Standardabweichungen vom rollierenden Mittelwert. Der Ausstieg erfolgt häufig nahe 0,5. Diese Werte sind Konventionen aus früheren Darstellungen und keine gemessenen Optima. Eine Änderung der Schwellenwerte verändert sowohl die Zahl der Trades als auch die Haltedauer.
Können zwei Aktien bei niedriger Korrelation kointegriert sein?
Ja. Die Korrelation wird anhand der täglichen Veränderungen berechnet, die Kointegration anhand des Kursabstands. Daher können sich zwei Aktien im Tagesverlauf selten gleich bewegen und trotzdem langfristig einen stabilen Abstand aufweisen. Das Gegenteil ist ebenfalls möglich: eine hohe tägliche Korrelation bei einem Abstand, der sich Jahr für Jahr vergrößert.
Warum funktioniert ein kointegriertes Paar nicht mehr?
Die Verbindung, die den Abstand zusammenhält, kann sich verändern. Gründe sind etwa eine Fusion, eine Abspaltung, eine veränderte Geschäftszusammensetzung eines Unternehmens oder eine Indexänderung, durch die sich die Eigentümerstruktur der Aktie verändert. Die statistischen Merkmale in den Tagen vor einem Bruch sehen genauso aus wie vor einer gewöhnlichen Rückkehr zum Mittelwert. Deshalb muss die Positionsgröße auf dieses Risiko abgestimmt werden, statt den Bruch vorhersagen zu wollen.
Jede Grafik wird hier mit der zugrunde liegenden SQL-Abfrage bereitgestellt. Dadurch sind die Zeitfenster, der Anpassungszeitraum und die Grenzen der Bins vollständig sichtbar. Um denselben spread und z-Score für ein von Ihnen beobachtetes Paar zu berechnen, formulieren Sie die Frage in einfachem Englisch im Strasmore-Terminal.