DCC-GARCH: Dynamische Korrelationen für Paare und Portfoliorisiko
Fragen Sie die meisten Krypto-Desks nach der Korrelation zwischen BTC und ETH, und Sie erhalten eine einzelne Zahl — 0,8, vielleicht 0,75 — berechnet über irgendein Fenster, an dessen Wahl sich niemand erinnert. Diese Zahl ist eine Lüge, oder zumindest eine gefährliche Vereinfachung. Die Stichprobenkorrelation ist ein Durchschnitt über einen Zeitraum, in dem sich die wahre Abhängigkeitsstruktur ständig bewegt hat. In ruhigen Märkten driften BTC und ETH weit genug auseinander, um ein marktneutrales Paar attraktiv erscheinen zu lassen. In einer Liquidationskaskade koppeln sie sich aneinander und an alles andere, und die Diversifikation, für die Sie bezahlt haben, verdampft genau in dem Moment, in dem Sie sie brauchen.
Das ist kein subtiler Effekt. Nehmen Sie einen beliebigen Drawdown aus 2022 — den LUNA-Kollaps im Mai, die 3AC-Abwicklung im Juni, die FTX-Implosion im November — und Sie werden sehen, wie die durchschnittliche paarweise Korrelation über die Top-20-Token innerhalb von Tagen vom Bereich 0,4-0,6 in Richtung 0,9+ marschiert. Korrelation ist keine Konstante, die gelegentlich schlecht geschätzt wird; sie ist eine Zeitreihe mit eigener Dynamik, eigenem Clustering und eigenen Regimen. Sie als Skalar zu behandeln, ist das multivariate Äquivalent zur Annahme konstanter Volatilität — ein Fehler, den wir bereits in Teil 1 dieser Serie für einen einzelnen Vermögenswert auseinandergenommen haben.
Dieser Artikel ist Teil 3 einer vierteiligen Volatilitätsserie. Teil 1 baute univariates GARCH(1,1) mit der arch-Bibliothek auf und zeigte, wie Volatilität clustert und zum Mittelwert zurückkehrt. Teil 2 fügte Asymmetrie (GJR-GARCH, EGARCH) und Student-t-Innovationen hinzu, um den Leverage-Effekt und Fat Tails zu erfassen. Hier werden wir multivariat: Wir modellieren die gesamte bedingte Kovarianzmatrix in ihrer Entwicklung, unter Verwendung von Engles Dynamic-Conditional-Correlation-Modell (DCC). Das liefert uns zwei Dinge, die eine skalare Korrelation niemals kann — eine dynamische Hedge-Ratio für Pairs-Trading und eine ehrliche, zeitvariable Portfoliovarianz für risikobasierte Allokation. Teil 4 schließt die Serie mit einem volatilitätsgezielten Backtest ab, der die univariaten und multivariaten Prognosen in eine Positionsgrößen-Regel überführt.
Wir setzen voraus, dass Sie Teil 1 und 2 gelesen haben, daher werden wir univariates GARCH nicht erneut herleiten. Wenn Sie das gemeinsame Tail-Verhalten wissen möchten — die Wahrscheinlichkeit, dass zwei Vermögenswerte gemeinsam ihr 1%-Quantil durchbrechen — dann ist das eine Copula-Frage, und wir behandeln sie in Copula-Modelle für gemeinsames Risiko. DCC und Copulas sind komplementär: Die Copula liefert Ihnen eine statische, aber flexible Tail-Abhängigkeitsstruktur, während DCC Ihnen eine handhabbare Zeitreihe der gesamten Korrelationsmatrix liefert. In diesem Artikel geht es um Letzteres.
Warum statische Korrelation in Krypto versagt
Bevor wir zur Maschinerie kommen, sollten wir präzise sagen, was versagt. Eine einzelne Stichprobenkorrelation über ein Fenster schätzt
Dies trägt drei implizite Annahmen in sich, die für Krypto allesamt falsch sind:
- Stationarität der Abhängigkeit. Das Fenster hat ein wahres . In Wirklichkeit hat die Abhängigkeit Regime — ein Ruhemarkt-Regime nahe 0,5 und ein Stress-Regime nahe 0,95 — und vermischt sie zu einer bedeutungslosen Mitte.
- Konstante marginale Volatilität. Die Pearson-Korrelation ist eine normalisierte Kovarianz. Wenn sich und selbst bewegen (sie tun es — das ist die gesamte Prämisse von Teil 1 und 2), dann erzeugt selbst eine konstante Kovarianz eine zeitvariable Korrelation und umgekehrt. Sie können die beiden nicht trennen, ohne ein Volatilitätsmodell darunter.
- Symmetrie über die Marktrichtung. Die Korrelation steigt in Drawdowns stärker als in Rallyes. Dies ist der multivariate Vetter des Leverage-Effekts. Ein rollierendes Fenster kann ihn nicht ausdrücken, ohne so kurz zu werden, dass es reines Rauschen ist.
Der Rolling-Window-Fix — über die letzten 30 oder 60 Tage neu zu berechnen — tauscht ein Problem gegen ein anderes. Kurze Fenster sind reaktionsschnell, aber verrauscht und hinken dem tatsächlichen Bruch hinterher; lange Fenster sind stabil, aber veraltet. Schlimmer noch: Eine rollierende Korrelationsmatrix über Vermögenswerte bleibt nicht garantiert positiv semidefinit, sobald Sie mit Schrumpfung oder Patching beginnen, was jeden nachgelagerten Optimierer bricht. Wir wollen ein Modell, das (a) von einem echten Volatilitätsprozess pro Vermögenswert getrieben wird, (b) per Konstruktion in jedem Schritt eine gültige Korrelationsmatrix erzeugt und (c) Parameter hat, die wir per Maximum-Likelihood schätzen können, statt eine Fensterlänge aus dem Hut zu ziehen. Dieses Modell ist DCC-GARCH.
Das multivariate Problem: Die bedingte Kovarianzmatrix
Sei der Vektor der Renditen für Vermögenswerte zum Zeitpunkt , mit bedingtem Mittelwert (oft nur eine Konstante oder ein kleiner AR-Term) und Residuum . Wir nehmen an
wobei die bedingte Kovarianzmatrix gegeben die Informationsmenge ist und eine bedingte Verteilung ist (Gauß oder, besser für Krypto, multivariate Student-t). Alles in der multivariaten Volatilitätsmodellierung ist eine andere Antwort auf eine Frage: Wie parametrisiert man die Dynamik von , sodass es in jedem Schritt symmetrisch positiv definit bleibt, ohne eine Explosion von Parametern?
Zwei klassische Antworten zeigen, warum das Problem schwer ist.
VECH
Das VECH-Modell (Bollerslev, Engle, Wooldridge 1988) schreibt die Halb-Vektorisierung von als lineare Funktion vergangener quadrierter Residuen und vergangener Kovarianzen:
wobei das untere Dreieck einer symmetrischen Matrix in einen Vektor der Länge stapelt. Dies ist maximal allgemein — jede Varianz und Kovarianz hängt von jeder vergangenen Varianz und Kovarianz ab — und jenseits von maximal nutzlos. Für Vermögenswerte sind und jeweils . Bei sind das zwei -Matrizen, ungefähr 450 Parameter, plus Positive-Definitheits-Beschränkungen, die schon auszudrücken schmerzhaft sind. Die Likelihood-Oberfläche ist ein Sumpf.
BEKK
Das BEKK-Modell (Engle & Kroner 1995) garantiert positive Definitheit per Konstruktion mittels einer quadratischen Form:
mit oberer Dreiecksmatrix. Da jeder Term eine quadratische Form ist, gilt automatisch, solange . BEKK ist sparsamer als VECH, skaliert aber immer noch mit Parametern — die - und -Matrizen sind jeweils . Für schätzen Sie in der Größenordnung von 200+ Parametern gemeinsam per MLE, auf verrauschten täglichen Krypto-Daten, ohne Garantie, dass der Optimierer zu etwas Sinnvollem konvergiert. In der Praxis ist volles BEKK auf beschränkt, und selbst dann verwendet man die diagonalen oder skalaren Restriktionen, die den Großteil der Kreuzdynamik verwerfen.
Dies ist der Fluch der Dimensionalität für multivariates GARCH: Die Anzahl der Parameter wächst quadratisch, aber die Menge an Information in den Daten nicht. Ihnen gehen die Freiheitsgrade lange aus, bevor Ihnen die Vermögenswerte ausgehen, die Sie interessieren. Jedes Krypto-Portfolio mit 10-30 Token ist für VECH oder BEKK völlig unerreichbar.
Der Ausweg, der auf Engle zurückgeht, besteht darin, nicht mehr zu versuchen, direkt zu modellieren, sondern es stattdessen zu faktorisieren in Teile, die wir bereits kostengünstig schätzen können.
Engles DCC (2002): Die zweistufige Zerlegung
Bollerslevs Constant-Conditional-Correlation-Modell (CCC) (1990) war die erste sparsame Faktorisierung. Es schreibt
wobei die Diagonalmatrix der bedingten Standardabweichungen ist — ein univariates GARCH pro Vermögenswert — und eine konstante Korrelationsmatrix ist. Dies ist eine enorme Vereinfachung: Sie passen unabhängige univariate GARCH-Modelle an und schätzen dann eine einzelne Stichprobenkorrelationsmatrix der standardisierten Residuen. Positive Definitheit ist automatisch, solange eine gültige Korrelationsmatrix ist und alle sind.
Das Problem von CCC steckt schon im Namen — die Korrelation ist konstant, was genau die Annahme ist, die wir am Anfang dieses Artikels abgelehnt haben. Engles Dynamic Conditional Correlation (2002) behält CCCs schöne Faktorisierung bei, lässt die Korrelationsmatrix aber atmen:
Nun ist zeitvariabel. Der Geniestreich ist, dass die Volatilitäten und die Korrelationen in zwei getrennten Schritten geschätzt werden, sodass wir niemals mit der vollen -Gemeinschaftsoptimierung konfrontiert sind.
Schritt 1: Univariates GARCH pro Vermögenswert
Für jeden Vermögenswert passen Sie ein univariates GARCH-Modell an, genau wie in Teil 1 und 2 — GARCH(1,1), GJR-GARCH oder EGARCH mit Student-t-Innovationen, was auch immer für diese Reihe am besten passte. Dies liefert bedingte Varianzen und somit .
Aus den angepassten Modellen extrahieren wir die standardisierten Residuen:
Per Konstruktion hat jedes (näherungsweise) eine bedingte Einheitsvarianz. Stapeln Sie sie in einen Vektor . Diese standardisierten Residuen sind das Rohmaterial für den Korrelationsschritt — ihre individuelle Volatilitätsdynamik wurde herausgerechnet, sodass jede verbleibende Mitbewegung reine Abhängigkeit ist und kein Volatilitätsartefakt. (Dies ist dieselbe PIT-artige Logik, die der Copula-Artikel vor dem Anpassen der Ränder verwendet; hier hören wir bei der Standardisierung auf, statt den ganzen Weg bis zu Gleichverteilungen zu gehen.)
Schritt 2: Die DCC-Korrelationsrekursion
Wir modellieren einen Hilfsprozess , eine symmetrische positiv definite Matrix, mit einer GARCH-artigen Rekursion, die durch die äußeren Produkte der standardisierten Residuen getrieben wird:
wobei:
- die unbedingte Korrelationsmatrix der standardisierten Residuen ist (dies ist Korrelations-Targeting — mehr dazu unten),
- steuert, wie stark der heutige Schock die Korrelation zieht,
- steuert die Persistenz — wie viel vom gestrigen übertragen wird,
- und die Mean-Reversion-Beschränkung ist (mit ), direkt analog zu im univariaten GARCH.
Beachten Sie, dass die Struktur identisch mit einer skalaren GARCH(1,1)-Rekursion ist, aber auf Matrizen: ein langfristiger Anker , ein Schockterm und ein Persistenzterm. Da es eine Konvexkombination positiv semidefiniter Matrizen ist (, das Rang-1-äußere-Produkt und das vorherige ), bleibt positiv definit, solange und die Gewichte nicht negativ sind. Das ist es, was uns garantiert gültige Kovarianzmatrizen kostenlos beschert.
ist fast eine Korrelationsmatrix, aber nicht ganz — seine Diagonale ist nicht exakt 1. Daher normalisieren wir es:
Elementweise ist die bedingte Korrelation zwischen den Vermögenswerten und
Dieses ist eine echte Korrelationsmatrix — Einheitsdiagonale, Nebendiagonalen in , positiv definit — in jedem einzelnen Zeitschritt, per Konstruktion. Setzen Sie die volle bedingte Kovarianz wieder zusammen:
Diese letzte elementweise Form ist diejenige, die Sie ständig verwenden werden: Die bedingte Kovarianz zweier Vermögenswerte ist ihre dynamische Korrelation multipliziert mit jeder ihrer dynamischen Volatilitäten. Jede Zutat auf der rechten Seite ist zeitvariabel und stammt aus einem Modell, das Sie schätzen können.
Das gesamte Modell hat nur zwei Korrelationsparameter, und , unabhängig davon, ob oder . Die Volatilitätsseite skaliert linear (ein univariates GARCH pro Vermögenswert, jeweils mit ~4-5 Parametern, alle unabhängig und peinlich parallel angepasst). Deshalb skaliert DCC dort, wo BEKK und VECH es nicht können: Der Dimensionalitätsfluch ist auf beschränkt, das getargetet (als Stichprobenschätzung eingesetzt) statt optimiert wird.
Die skalare Restriktion und ihr Preis
Die -Skalare bedeuten, dass jedes Vermögenswertpaar dieselbe Korrelationsdynamik teilt — dieselbe Anpassungsgeschwindigkeit und dieselbe Persistenz. Die BTC-ETH-Korrelation und die DOGE-SHIB-Korrelation bewegen sich im selben Rhythmus, obwohl sich ihre Ökonomie unterscheidet. Dies ist der Preis der Handhabbarkeit, und es ist normalerweise ein akzeptabler Preis. Verallgemeinerungen (Generalized DCC mit Matrizen ; das asymmetrische DCC von Cappiello-Engle-Sheppard) lockern es auf Kosten von Parametern und Schätzstabilität. Wir erwähnen aDCC weiter unten.
Die DCC-Quasi-Log-Likelihood
Um und zu schätzen, benötigen wir die Likelihood. Engles Schlüsselergebnis ist, dass sich die Gauß-Log-Likelihood in einen Volatilitätsteil und einen Korrelationsteil auftrennt, was den zweistufigen Schätzer rechtfertigt. Unter der Annahme ist der Log-Likelihood-Beitrag zum Zeitpunkt
Setzen Sie ein. Dann gilt und , und mit :
Nun teilen wir es auf, indem wir addieren und subtrahieren:
Der Volatilitätsteil hängt nur von den univariaten GARCH-Parametern ab (über ) — ihn zu maximieren ist genau das Anpassen von unabhängigen univariaten GARCH-Modellen, was wir in Schritt 1 getan haben. Der Korrelationsteil hängt von und ab (über ), gegeben die standardisierten Residuen aus Schritt 1. In Schritt 2 maximieren wir also nur
(der Term hängt nicht von ab, daher lassen wir ihn weg). Dies ist eine zweiparametrige Optimierung, egal wie viele Vermögenswerte — das ist der ganze Sinn. Sie wird Quasi-Likelihood genannt, weil der zweistufige Schätzer konsistent, aber nicht vollständig effizient ist; die Standardfehler benötigen eine Korrektur (Engle & Sheppard 2001), aber für die Signalgenerierung sind die Punktschätzungen das, worauf es ankommt.
Für Krypto unterschätzen Gauß-Innovationen das Tail-Risiko. Der Ersatz durch die multivariate Student-t-Likelihood ist eine Drop-in-Änderung an (ersetzen Sie den Gauß-Kern durch die multivariate -Dichte und fügen Sie einen Freiheitsgrad-Parameter hinzu). Wir behalten die Gauß-Quasi-Likelihood im Schätzer unten der Klarheit halber bei und weisen darauf hin, wo eintritt — die Standardisierung aus Teil 1-2 verwendete bereits t-Innovationen auf den Rändern, was den größten Teil des Tail-Vorteils erfasst.
Python-Implementierung
Eine unverblümte, aber wichtige Tatsache: die arch-Bibliothek macht kein multivariates GARCH oder DCC. arch ist eine hervorragende univariate Engine (wir stützen uns genau dafür darauf), aber es gibt kein dcc_model darin. Ihre praktischen Optionen sind:
- Rollen Sie Ihr eigenes DCC auf
arch— passen Sie univariate Modelle mitarchan, extrahieren Sie standardisierte Residuen, implementieren Sie die -Rekursion und die Korrelations-Quasi-Likelihood in NumPy/SciPy und optimieren Sie die zwei Skalare. Das ist es, was wir unten tun. Es sind etwa 60 Zeilen und vollkommen transparent. - Das
mgarch-PyPI-Paket — eine leichtgewichtige reine-Python-DCC-GARCH-Implementierung. Bequem für eine schnelle Anpassung, weniger flexibel, wenn Sie GJR-Ränder oder t-Innovationen präzise verdrahten möchten. - Rs
rmgarch(Alexios Galanos) — die Referenzimplementierung.dccspec/dccfitunterstützen DCC, aDCC, GARCH-Copula, Student-t und korrekte Standardfehler. Wenn Sie ernsthafte multivariate Volatilitätsforschung betreiben, istrmgarch(bei Bedarf aus Python überrpy2aufgerufen) der Goldstandard.
Wir bauen Option 1, weil sie jedes bewegliche Teil explizit macht und die univariaten Fähigkeiten aus Teil 1-2 wiederverwendet.
Schritt 1: Univariate GARCH-Ränder mit arch anpassen
import numpy as np
import pandas as pd
from arch import arch_model
from scipy.optimize import minimize
def fetch_returns(symbols, start="2022-01-01", end="2025-12-31"):
"""
Daily log returns for a list of crypto symbols.
Replace with your data source (ccxt for 24/7 exchange data,
yfinance for a quick sketch).
"""
import yfinance as yf
px = yf.download([f"{s}-USD" for s in symbols],
start=start, end=end)["Close"]
px.columns = symbols
rets = np.log(px / px.shift(1)).dropna()
return rets
symbols = ["BTC", "ETH", "SOL", "BNB"]
returns = fetch_returns(symbols)
def fit_univariate(series, dist="t"):
"""
Fit GJR-GARCH(1,1) with Student-t innovations (Part 2 model).
Returns the fitted result and the *scaled* series it was fit on.
We scale returns by 100 for the optimizer's numerical health,
exactly as in Parts 1 and 2.
"""
scaled = series * 100.0
model = arch_model(scaled, mean="Constant",
vol="GARCH", p=1, o=1, q=1, dist=dist)
res = model.fit(disp="off")
return res
fits = {s: fit_univariate(returns[s]) for s in symbols}
Z = pd.DataFrame({s: fits[s].std_resid for s in symbols}).dropna()
Sigma = pd.DataFrame({s: fits[s].conditional_volatility
for s in symbols}).loc[Z.index]
print(Z.describe())
Eine schnelle Plausibilitätsprüfung der standardisierten Residuen ist wichtig. Wenn eine Spalte eine Standardabweichung weit von 1 hat oder starke verbleibende Autokorrelation in ihrem Quadrat (Ljung-Box auf ), ist der univariate Rand fehlspezifiziert, und der DCC-Schritt wird diesen Fehler erben. Korrigieren Sie zuerst den Rand — genau dafür war Teil 2 da.
Schritt 2: Die DCC-Rekursion und Quasi-Log-Likelihood
def dcc_negloglik(params, Z):
"""
Negative DCC quasi-log-likelihood (Gaussian) in (a, b).
Z : (T, d) array of standardized residuals from Step 1.
Implements:
Q_t = (1-a-b) Qbar + a z_{t-1} z_{t-1}' + b Q_{t-1}
R_t = diag(Q_t)^{-1/2} Q_t diag(Q_t)^{-1/2}
LL = -1/2 sum_t ( log|R_t| + z_t' R_t^{-1} z_t )
with correlation targeting: Qbar = sample corr of Z.
"""
a, b = params
if a <= 0 or b <= 0 or a + b >= 1.0:
return 1e10
Z = np.asarray(Z)
T, d = Z.shape
Qbar = np.cov(Z, rowvar=False, bias=True) # unconditional (targeted)
dinv = np.diag(1.0 / np.sqrt(np.diag(Qbar)))
Qbar = dinv @ Qbar @ dinv
Q = Qbar.copy() # initialize Q_1 at the target
ll = 0.0
for t in range(T):
q_diag = np.sqrt(np.diag(Q))
R = Q / np.outer(q_diag, q_diag)
sign, logdet = np.linalg.slogdet(R)
if sign <= 0:
return 1e10
z = Z[t]
Rinv_z = np.linalg.solve(R, z)
ll += -0.5 * (logdet + z @ Rinv_z)
Q = (1 - a - b) * Qbar + a * np.outer(z, z) + b * Q
return -ll
def fit_dcc(Z):
"""Estimate (a, b) by maximizing the DCC quasi-log-likelihood."""
res = minimize(
dcc_negloglik, x0=[0.03, 0.94], args=(np.asarray(Z),),
method="L-BFGS-B",
bounds=[(1e-6, 0.5), (1e-6, 0.999)],
)
a, b = res.x
print(f"DCC estimates: a = {a:.4f}, b = {b:.4f}, a+b = {a+b:.4f}")
print(f"log-likelihood: {-res.fun:.2f}")
return a, b
a_hat, b_hat = fit_dcc(Z)
Wenn Sie dies auf einem BTC/ETH/SOL/BNB-Portfolio über einige Jahre täglicher Daten ausführen, entsteht eine Ausgabe in folgender Form (die Zahlen unten sind illustrativ, nicht aus einem konkreten datierten Experiment — führen Sie es mit Ihren eigenen Daten aus):
DCC estimates: a = 0.0287, b = 0.9401, a+b = 0.9688
log-likelihood: -3812.44
So liest man es:
- ist klein — die Korrelationsmatrix ruckt nicht bei einem einzigen Tagesschock. Jeder Tag schiebt nur um ~3% in Richtung des äußeren Produkts .
- ist groß — Korrelationen sind hochgradig persistent. Sobald sich das Portfolio in einem Stressereignis koppelt, bleibt es eine Weile gekoppelt und klingt nur langsam zu ab. Das entspricht der gelebten Erfahrung von Krypto-Drawdowns: Korrelationen springen nicht in dem Moment zurück, in dem sich der Preis stabilisiert.
- bestätigt Mean Reversion. Der Korrelationsprozess hat ein stationäres langfristiges Niveau (), zu dem er zurückkehrt, mit einer Halbwertszeit von ungefähr Tagen. Wenn Sie jemals im Wesentlichen gleich 1 schätzen, ist der Korrelationsprozess integriert — er hat keinen langfristigen Anker, meist ein Symptom eines Strukturbruchs innerhalb Ihrer Stichprobe, den das Modell als unendliche Persistenz absorbiert.
Die nahe-Einheits-Persistenz und die winzige Schockladung sind der kanonische DCC-Fingerabdruck über Anlageklassen hinweg, und Krypto ist keine Ausnahme. Es ist auch der Grund, warum eine 30-Tage-Rolling-Korrelation ein so schlechter Ersatz ist: Ein rollierendes Fenster nimmt implizit und an, die überhaupt nicht zu dieser Abklingstruktur passen.
Ein paar Implementierungshinweise, die echte Debugging-Zeit sparen:
- Initialisierung. Der Start bei
[0.03, 0.94]spiegelt die typische Krypto-Schätzung wider: kleines (Korrelationen reagieren auf Schocks, aber nicht heftig), großes (Korrelationen sind persistent). Wenn Ihr Optimierer zu wandert, ist der Korrelationsprozess integriert — meist ein Zeichen für einen Strukturbruch in der Stichprobe (ein Regimewechsel, den das Modell mit Mühe als Persistenz anzupassen versucht). - Timing-Konvention. Innerhalb der Schleife bewerten wir gegen und aktualisieren dann mit für den nächsten Schritt. Dies hält als eine Funktion der Information nur bis — kein Look-Ahead. Diesen Off-by-One-Fehler falsch zu machen, ist der mit Abstand häufigste DCC-Bug, und er bläht den In-Sample-Fit stillschweigend auf.
- Korrelations-Targeting. Wir setzen als die Stichprobenkorrelation ein, statt es zu schätzen. Das ist es, was die Optimierung zweidimensional macht. Der Preis ist, dass die volle Stichprobe verwendet, sodass Sie es in einem strikten Walk-Forward nur auf dem Trainingsfenster neu schätzen müssen (siehe unten).
Schritt 3: Die Korrelations- und Kovarianzpfade rekonstruieren
Sobald fixiert sind, führen Sie die Rekursion noch einmal aus, diesmal unter Speicherung des vollen - (und -)Pfads, damit nachgelagerte Strategien ihn verwenden können.
def dcc_filter(Z, Sigma, a, b):
"""
Run the DCC recursion with fixed (a,b) and return the full paths:
R_path : (T, d, d) conditional correlation matrices
H_path : (T, d, d) conditional covariance matrices (scaled units)
Sigma : (T, d) conditional volatilities aligned with Z.
"""
Z = np.asarray(Z); Sig = np.asarray(Sigma)
T, d = Z.shape
Qbar = np.cov(Z, rowvar=False, bias=True)
dinv = np.diag(1.0 / np.sqrt(np.diag(Qbar)))
Qbar = dinv @ Qbar @ dinv
Q = Qbar.copy()
R_path = np.empty((T, d, d))
H_path = np.empty((T, d, d))
for t in range(T):
q_diag = np.sqrt(np.diag(Q))
R = Q / np.outer(q_diag, q_diag)
R_path[t] = R
Dt = np.diag(Sig[t]) # D_t = diag(sigma_i,t)
H_path[t] = Dt @ R @ Dt # H_t = D_t R_t D_t
z = Z[t]
Q = (1 - a - b) * Qbar + a * np.outer(z, z) + b * Q
return R_path, H_path
R_path, H_path = dcc_filter(Z, Sigma, a_hat, b_hat)
i, j = symbols.index("BTC"), symbols.index("ETH")
rho_btc_eth = pd.Series(R_path[:, i, j], index=Z.index, name="rho_BTC_ETH")
print(rho_btc_eth.describe())
print("min/max correlation:", rho_btc_eth.min().round(3),
rho_btc_eth.max().round(3))
Die rho_btc_eth-Reihe ist der Ertrag der gesamten Übung: Statt einer Zahl haben Sie nun eine tägliche Korrelation, die Sie plotten, mit Schwellen versehen oder in eine Strategie einspeisen können. Auf echten Krypto-Daten werden Sie typischerweise sehen, dass sie von etwa 0,5 in ruhigen Phasen bis über 0,9 während Stress reicht — genau die Spanne, die eine einzelne Stichprobenkorrelation wegmittelt.
Ein-Schritt-voraus-Prognose
Für den Live-Handel benötigen Sie das nächste aus jetzt verfügbaren Informationen. Die Volatilitätsseite kommt aus der Ein-Schritt-Prognose jedes arch-Modells; die Korrelationsseite ist eine weitere Runde der Rekursion:
def dcc_forecast_next(Z, a, b, fits, symbols):
"""One-step-ahead H_{t+1} using info through the last observation."""
Z = np.asarray(Z); T, d = Z.shape
Qbar = np.cov(Z, rowvar=False, bias=True)
dinv = np.diag(1.0 / np.sqrt(np.diag(Qbar)))
Qbar = dinv @ Qbar @ dinv
Q = Qbar.copy()
for t in range(T):
z = Z[t]
Q = (1 - a - b) * Qbar + a * np.outer(z, z) + b * Q
q_diag = np.sqrt(np.diag(Q))
R_next = Q / np.outer(q_diag, q_diag)
sig_next = np.array([
np.sqrt(fits[s].forecast(horizon=1, reindex=False)
.variance.iloc[-1, 0])
for s in symbols
])
Dt = np.diag(sig_next)
H_next = Dt @ R_next @ Dt
return R_next, H_next, sig_next
R_next, H_next, sig_next = dcc_forecast_next(Z, a_hat, b_hat, fits, symbols)
Denken Sie daran, dass alles in skalierten (×100) Einheiten ist, weil wir arch auf series * 100 angepasst haben. Teilen Sie die Volatilitäten durch 100 (und die Kovarianzen durch ), um zu Roh-Rendite-Einheiten zurückzukehren, bevor Sie eine Strategie speisen. Die Skalierung im Griff zu behalten, ist mühsam, aber eine häufige Quelle stiller Bugs.
Anwendung 1: Eine dynamische Hedge-Ratio für Pairs-Trading
Das klassische marktneutrale Paar — long ein Vermögenswert, short ein beta-gewichteter Betrag eines anderen — steht und fällt mit der Hedge-Ratio . Schätzen Sie sie per statischer OLS über ein Trainingsfenster, und Sie erben genau das Problem der veralteten Korrelation, um das es in diesem gesamten Artikel geht: Der Hedge, der letztes Quartal das Marktexposure neutralisiert hat, ist dieses Quartal falsch.
DCC liefert Ihnen die Hedge-Ratio als Zeitreihe. Der minimum-varianz-Hedge des ETH-Exposures mittels BTC ist der bedingte Regressionskoeffizient
Jeder Term auf der rechten Seite ist eine DCC-Ausgabe. Die Hedge-Ratio bewegt sich aus zwei verschiedenen Gründen, und DCC trennt sie sauber: Die Korrelation ändert sich (die Vermögenswerte koppeln oder entkoppeln sich), und das Volatilitätsverhältnis ändert sich (ein Vermögenswert wird relativ volatiler). Ein Rolling-OLS-Beta verschmiert beide Effekte mit einer Verzögerung zusammen; DCC schreibt sie zu.
def dynamic_hedge_ratio(R_path, Sigma, base="BTC", target="ETH",
symbols=symbols, index=Z.index):
"""
beta_t to hedge `target` exposure with `base`:
beta_t = rho_t * sigma_target,t / sigma_base,t
(Scaling cancels in the ratio, so scaled units are fine here.)
"""
i = symbols.index(target)
j = symbols.index(base)
rho = R_path[:, i, j]
sig = np.asarray(Sigma)
beta = rho * sig[:, i] / sig[:, j]
return pd.Series(beta, index=index, name=f"beta_{target}_{base}")
beta_t = dynamic_hedge_ratio(R_path, Sigma)
print(beta_t.describe())
spread = (returns["ETH"] - beta_t.shift(1) * returns["BTC"]).dropna()
Speisen Sie spread in welche Pairs-Engine auch immer Sie betreiben. Der dynamische Hedge erzeugt für sich allein keinen Edge — er macht den Spread, den Sie handeln, über die Zeit hinweg wirklich marktneutral, sodass Ihr Mean-Reversion-Signal nicht durch driftendes gerichtetes Exposure kontaminiert wird. Wenn Sie Pairs-Strategien bauen, fügt sich dies direkt in die Frameworks in Statistische Arbitrage & Pairs-Trading in Krypto und den Distanz-Ansatz für Paare ein und ersetzt deren feste Hedge-Ratio. Die Korrelationsreihe selbst ist auch ein saubererer Input für ein korrelationsbasiertes Paar-Signal als jedes rollierende Fenster — Sie erhalten ein geglättetes, modellkonsistentes statt einer verrauschten gefensterten Schätzung.
Zwei Vorsichtsmaßnahmen speziell für den Live-Einsatz von . Erstens: lag es — handeln Sie auf , niemals auf dem zeitgleichen , sonst spähen Sie. Zweitens: Eine Hedge-Ratio, die jeden Tag herumpeitscht, erzeugt Umschlag und Gebühren; in Kryptos 24/7-Markt mit Funding-Kosten auf dem Short-Bein kann ein überreaktiver Hedge mehr ausbluten als die Drift, die er korrigiert. Glätten Sie (ein EWMA, oder balancieren Sie den Hedge nur neu, wenn er über ein Band hinaus wandert) und dimensionieren Sie das Ganze vernünftig — die Positionsdimensionierung auf Basis eines verrauschten Signals ist eine eigene Disziplin, behandelt in Kelly-Kriterium-Dimensionierung.
Anwendung 2: Zeitvariable Portfoliovarianz
Für ein Portfolio mit Gewichtsvektor ist die bedingte Varianz
Mit einer statischen Kovarianzmatrix — dem Markowitz-Standard — ist diese Zahl eine Konstante, die Sie einmal berechnet haben und so tun, als wäre sie immer noch wahr. Ist sie nicht. Das Portfoliorisiko atmet mit dem Markt, und es atmet genau dann am heftigsten, wenn Korrelationen hochschnellen, denn in einem Drawdown steigen sowohl die -Terme als auch die -Terme gemeinsam an und multiplizieren sich. Ein Portfolio, das in ruhigen Märkten wie 40% annualisierte Volatilität aussah, kann in einer Stresswoche 80%+ laufen, und eine statische Kovarianzmatrix wird Ihnen sagen, dass sich nichts geändert hat.
def portfolio_vol_path(H_path, weights, index=Z.index, unscale=1e4):
"""
Conditional portfolio volatility sigma_{p,t} = sqrt(w' H_t w).
H_path is in scaled (x100) units, so covariances carry a 100^2
factor: divide by unscale=1e4 to return to raw-return variance.
"""
w = np.asarray(weights)
var_t = np.einsum("i,tij,j->t", w, H_path, w) / unscale
return pd.Series(np.sqrt(var_t), index=index, name="port_vol")
w = np.array([0.4, 0.3, 0.2, 0.1]) # BTC, ETH, SOL, BNB
pv = portfolio_vol_path(H_path, w)
pv_annual = pv * np.sqrt(365)
print(pv_annual.describe())
Dieses zeitvariable ist der ehrliche Input, den die risikobasierte Allokation braucht. Die Mean-Varianz-Optimierung (Markowitz für Krypto) mit einer statischen Stichproben-Kovarianz optimiert gegen eine Fiktion; sie mit (oder dessen kurzfristiger Prognose) zu speisen, macht die Effizienzgrenze selbst zeitvariabel und zwingt den Optimierer, in Regime steigender Korrelation hinein zu de-riskieren, statt erst danach. Risk-Parity- und hierarchische Ansätze — die HRP + CVaR-Pipeline — sind noch empfindlicher gegenüber dem Kovarianz-Input, da die gesamte Allokation eine Funktion der Risikomatrix ist. Und wenn Sie Allokatoren direkt vergleichen, wie in Portfolio-Optimierungsalgorithmen im Vergleich, ist es oft ein größerer Treiber des realisierten Risikos, ob sie statische oder dynamische Kovarianz konsumieren, als die Wahl des Algorithmus.
Die direkte Anwendung ist Volatilitäts-Targeting des gesamten Portfolios: Wählen Sie eine annualisierte Zielvolatilität und skalieren Sie das Brutto-Exposure jede Periode um , sodass das realisierte Risiko grob konstant bleibt, statt in Krisen aufzublähen. Das schließt den Kreis mit Teil 4, der genau diese Regel baut und backtestet.
Anwendung 3: Korrelation als Regime-Signal
Über Hedging und Dimensionierung hinaus trägt die Korrelationsmatrix ein Makro-Signal. Der einzelne nützlichste Skalar, den Sie extrahieren können, ist die durchschnittliche paarweise Korrelation:
Wenn über das Portfolio steigt, tritt der Markt in ein Risk-off-Regime ein — idiosynkratische Geschichten hören auf zu zählen und alles handelt als ein Makro-Beta. Dies ist der quantitative Fingerabdruck von "Korrelationen gehen in einer Krise gegen 1". Es tendiert dazu, Drawdowns voranzugehen oder mit ihnen zusammenzufallen, was es zu einem verwertbaren Regime-Indikator macht statt zu einer hinterherhinkenden Nachbetrachtung.
def avg_pairwise_corr(R_path, index=Z.index):
T, d, _ = R_path.shape
iu = np.triu_indices(d, k=1) # upper-triangle off-diagonals
avg = R_path[:, iu[0], iu[1]].mean(axis=1)
return pd.Series(avg, index=index, name="avg_corr")
avg_corr = avg_pairwise_corr(R_path)
roll_q = avg_corr.rolling(365, min_periods=90).quantile(0.80)
risk_off = (avg_corr > roll_q)
Sie können risk_off als eigenständige Drossel verwenden (Brutto-Exposure kürzen, Stops verbreitern, Mean-Reversion-Strategien einstellen, die überfahren werden, wenn alles gemeinsam trendet) oder als Feature in einem formelleren Regime-Modell. Es passt natürlich zum Hidden-Markov-Ansatz in Regime-Erkennung mit HMMs: Die durchschnittliche DCC-Korrelation ist eine der informativeren Beobachtungsvariablen, die Sie einem HMM übergeben können, weil sie in einer Weise vorausschauend auf systemischen Stress ist, wie es hinterherhinkende Renditen nicht sind. Die ehrliche Einschränkung: Steigende Korrelation sagt Ihnen, dass die Diversifikation versagt, nicht in welche Richtung der Markt geht. Es ist ein Risikosignal, kein Alpha-Signal, und sollte als solches dimensioniert werden — siehe die Asymmetrie von Verlusten und Gewinnen dafür, warum es schlecht endet, ein Risikoregime als gerichtete Wette zu behandeln.
Praktische Überlegungen
Schätzstabilität und Anzahl der Vermögenswerte
DCC skaliert weit besser als BEKK, aber "skaliert" ist nicht "gratis". Die Korrelations-Targeting-Matrix ist eine -Stichprobenkorrelation, und Stichprobenkorrelationsmatrizen werden schlecht konditioniert, wenn sich der Anzahl der Beobachtungen nähert. Mit 4 Vermögenswerten und 1000 Tagen sind Sie fein. Mit 60 Vermögenswerten und 400 Tagen ist nahezu singulär, ihre Inverse in der Likelihood explodiert, und kann durch numerisches Rauschen non-PD wandern. Abmilderungen, grob in der Reihenfolge, wie oft Sie sie brauchen werden:
- Schrumpfen Sie in Richtung eines strukturierten Ziels (Ledoit-Wolf, oder in Richtung der Identität / einer Konstant-Korrelations-Matrix), bevor Sie die Rekursion ausführen. Dies ist der wirkungsvollste Einzelfix für große Portfolios.
- Gruppieren Sie Vermögenswerte in eine Handvoll Sektoren (Majors, L1s, DeFi, Memes), modellieren Sie innerhalb und über die Sektorebene hinweg, oder führen Sie DCC auf Hauptkomponenten-Faktoren statt auf rohen Vermögenswerten aus.
- Bevorzugen Sie mehr Daten gegenüber mehr Vermögenswerten. DCC hat einen unstillbaren Appetit auf eine lange, saubere, zeitgleiche Historie — genau das, was junge Token nicht haben.
Realistisch halten Sie direktes DCC auf höchstens ein paar Dutzend Vermögenswerte. Für ein großes Universum ist DCC auf Faktorrenditen plus idiosynkratischen Residuen der Standard-Workaround.
Korrelations-Targeting ist eine Abkürzung mit einem Preis
Das Targeting von macht die Schätzung handhabbar, backt aber die Voll-Stichproben-unbedingte Korrelation in jedes ein. In einem strikten Backtest ist dies ein Look-Ahead-Leck: Ihre Korrelationsmatrix am Tag "kennt" die durchschnittliche Korrelation der gesamten Stichprobe, einschließlich der Zukunft. Für eine ehrliche Evaluation müssen Sie nur auf dem Trainingsfenster neu schätzen und es out-of-sample fixieren, oder es vorwärts rollen. Dies ist dieselbe Disziplin, die das gesamte Walk-Forward-Optimierungs-Framework durchsetzt, und sie ist leicht versehentlich zu verletzen mit einem bequemen np.cov(Z) über das volle Array — wie es unser Lehrcode oben tut. Korrigieren Sie es, bevor Sie einer einzigen P&L-Zahl trauen.
Neuanpassungs-Kadenz und Look-Ahead-Disziplin
Sie müssen nicht jeden Tag neu optimieren — sie sind stabile Parameter. Eine sinnvolle Produktionskadenz:
- Schätzen Sie und die univariaten GARCH-Parameter neu wöchentlich oder monatlich.
- Führen Sie den Filter aus (aktualisieren Sie , ) jede Periode mit den eingefrorenen Parametern, um frische und zu erhalten. Filtern ist billig; Anpassen ist es nicht.
- Prognostizieren Sie immer, glätten Sie nie. Verwenden Sie das aus Information bis gebaute , um bei zu handeln. Die zweistufige Struktur (Anpassen auf einem Fenster, dann Vorwärtsfiltern) ist das, was Sie ehrlich hält.
Die Lücke zwischen einem DCC-Backtest und Live-Performance ist fast immer ein Look-Ahead-Leck — Voll-Stichproben-, zeitgleiches oder Neuanpassen auf Daten, die den Trade enthalten, den Sie evaluieren. Die Disziplin, den Backtest an die Live-Bedingungen anzupassen, ist ein eigenes Thema in Backtest-Live-Parität, und DCC ist ein Modell, das Schlampigkeit hier mehr bestraft als die meisten. Wenn nach sauberer Walk-Forward-Evaluation die dynamische Korrelation für Ihre Strategie nichts über eine einfache rollierende Schätzung hinaus beiträgt, ist das ein reales und publizierbares negatives Ergebnis — die Denkweise in ehrliche negative Ergebnisse gilt direkt.
Asymmetrisches DCC (aDCC)
So wie der univariate Leverage-Effekt (Teil 2) bedeutet, dass schlechte Nachrichten die Volatilität stärker anheben als gute Nachrichten, steigen Korrelationen stärker nach gemeinsamen negativen Schocks als nach gemeinsamen positiven. Cappiello, Engle & Sheppard (2006) erfassen dies mit asymmetrischem DCC, indem sie einen Term hinzufügen, der durch das äußere Produkt der Negativteil-standardisierten Residuen getrieben wird:
wobei und den zusätzlichen Korrelationsschub aus gemeinsamen Abwärtsbewegungen misst. Für Krypto, wo Crash-Korrelation das dominante Risiko ist, ist der Asymmetrieterm meist signifikant und den einen zusätzlichen Parameter wert. rmgarch passt aDCC direkt an (model="aDCC"); den -Term zu unserem NumPy-Schätzer hinzuzufügen ist eine unkomplizierte Übung.
Vergleich: DCC gegen die Alternativen
Wo steht DCC unter den Möglichkeiten, wie Sie eine Kovarianzmatrix für ein Krypto-Portfolio erhalten könnten? Die ehrliche Zusammenfassung:
| Ansatz | Params | Skaliert bis | Zeitvariables ? | PD garantiert? | Tail-Abhängigkeit? |
|---|---|---|---|---|---|
| Stichproben-/rollierende Kovarianz | 0 (Fensterlänge) | beliebiges | grob (verzögert, verrauscht) | nein (braucht Patching) | nein |
| EWMA (RiskMetrics) | 1 () | beliebiges | ja (einzelner Zerfall) | ja | nein |
| CCC-GARCH | Ränder + | Dutzende | nein (konstantes ) | ja | nein |
| DCC-GARCH | Ränder + 2 | Dutzende | ja | ja | nein |
| aDCC-GARCH | Ränder + 3 | Dutzende | ja, asymmetrisch | ja | partiell |
| BEKK | ja (reich) | ja | nein | ||
| VECH | ja (am reichsten) | schmerzhaft | nein | ||
| GARCH-Copula | Ränder + Copula | Dutzende (Vines) | statische Copula | ja | ja |
Ein paar Lesarten dieser Tabelle:
- EWMA ist die günstige Baseline, die jeder schlagen sollte, bevor er behauptet, DCC helfe. Es ist im Geiste ein Ein-Parameter-Spezialfall — ein einzelner exponentieller Zerfall, direkt auf die Kovarianz angewandt — und für viele Portfolios ist es verblüffend schwer, es out-of-sample zu übertreffen. Wenn DCC EWMA nicht im sauberen Walk-Forward schlägt, verwenden Sie EWMA.
- CCC vs DCC ist der ganze Sinn dieses Artikels: dieselbe Faktorisierung, aber CCC friert ein und DCC lässt es sich bewegen. Die zwei zusätzlichen Parameter () sind der gesamte Unterschied, und in Krypto verdienen sie sich ihren Lebensunterhalt.
- BEKK/VECH erkaufen reichere Dynamik — jede Kovarianz kann auf jeden vergangenen Schock reagieren — aber die Parameterkosten beschränken sie auf winzige Portfolios. Für alles jenseits von 4 Vermögenswerten sind sie keine echte Option.
- GARCH-Copula ist die einzige Zeile mit einem "ja" unter Tail-Abhängigkeit. Das ist wieder die Komplementarität: DCC modelliert das dynamische Zentrum der gemeinsamen Verteilung, Copulas modellieren ihre statischen Tails. Wenn Ihre Risikofrage lautet "was passiert, wenn alles auf einmal bricht", greifen Sie zur Copula-Pipeline; wenn sie lautet "was ist gerade jetzt meine Hedge-Ratio / Portfoliovarianz", greifen Sie zu DCC.
Der praktische Standard für ein systematisches Krypto-Desk: DCC (oder aDCC) für Hedge-Ratios und dynamische Kovarianz im Zentrum, ein Copula-Overlay für Tail-Risiko und CVaR und EWMA als Plausibilitäts-Baseline, die Sie ehrlich darüber hält, ob sich die zusätzliche Maschinerie auszahlt.
Grenzen
- Skalare Dynamik. Ein und ein für alle Paare ist eine starke Restriktion. BTC-ETH und zwei obskure Altcoins teilen dieselbe Anpassungsgeschwindigkeit. Generalized DCC lockert dies, führt aber die Parameterexplosion wieder ein, die DCC vermeiden sollte.
- Effizienzverlust durch zwei Schritte. Der Quasi-Likelihood-Schätzer ist konsistent, aber nicht vollständig effizient, und naive Standardfehler sind falsch. Verwenden Sie die Engle-Sheppard-Korrektur, wenn Ihnen Inferenz wichtig ist; für die Signalgenerierung genügen die Punktschätzungen.
- Gauß-Tails standardmäßig. Die einfache Gauß-Quasi-Likelihood unterschätzt das gemeinsame Tail-Risiko. Student-t-Innovationen helfen; für echte Tail-Abhängigkeit (die Wahrscheinlichkeit gleichzeitiger extremer Bewegungen) ist DCC das falsche Werkzeug und ein Copula-Modell das richtige. DCC liefert Ihnen den dynamischen Körper der Korrelation; Copulas liefern den statischen Tail. Ernsthafte Desks verwenden beides.
- Korrelation ist keine Kausalität und keine Richtung. Steigendes warnt, dass die Diversifikation versagt; es sagt nichts über die Marktrichtung. Überladen Sie ein Risikosignal nicht mit gerichteten Erwartungen.
- Datenhunger. Alles oben setzt lange, saubere, synchronisierte Historien voraus. Kryptos neueste und interessanteste Token verletzen alle drei.
Zusammenfassung
- Statische Korrelation ist eine Lüge in Krypto. Korrelationen clustern, persistieren und schießen in Drawdowns gegen 1 — genau dann, wenn die Diversifikation helfen soll. Ein einzelnes Stichproben- mittelt einen Regime-wechselnden Prozess zu einer bedeutungslosen Mitte.
- Volles multivariates GARCH (VECH, BEKK) skaliert nicht. Die Parameteranzahl wächst mit ; beide sind in der Praxis auf eine Handvoll Vermögenswerte beschränkt.
- DCC (Engle 2002) faktorisiert das Problem: , mit aus unabhängigen univariaten GARCH-Anpassungen (Wiederverwendung von Teil 1-2) und aus einer Zwei-Parameter-Rekursion. Es skaliert auf Dutzende von Vermögenswerten, weil nur optimiert werden.
- Die Rekursion , normalisiert zu , erzeugt in jedem Schritt eine gültige positiv definite Korrelationsmatrix, mit , .
archmacht kein DCC. Passen Sie die Ränder mitarchan, implementieren Sie dann den ~60-Zeilen-NumPy/SciPy-Schätzer hier, oder verwenden Siemgarch(Python) oderrmgarch(R, die Referenz).- Drei konkrete Erträge: eine dynamische Hedge-Ratio für Pairs-Trading; eine ehrliche zeitvariable Portfoliovarianz für risikobasierte Allokation; und die durchschnittliche paarweise Korrelation als Risk-off-Regime-Signal.
- Disziplin ist alles. Das Korrelations-Targeting leckt den Voll-Stichproben-Durchschnitt, also schätzen Sie nur auf Trainingsdaten neu; laggen Sie jede Hedge-Ratio; filtern Sie vorwärts, glätten Sie nie. Walk-Forward-Evaluation ist nicht verhandelbar.
- aDCC fügt einen Abwärts-Asymmetrieterm hinzu und ist in Krypto meist lohnenswert, wo Crash-Korrelation dominiert.
- Teil 4 verwendet diese Prognosen, um eine volatilitätsgezielte Strategie zu bauen und zu backtesten.
Referenzen:
- Engle, R. (2002). Dynamic Conditional Correlation: A Simple Class of Multivariate Generalized Autoregressive Conditional Heteroskedasticity Models. Journal of Business & Economic Statistics, 20(3), 339-350. DOI
- Engle, R. & Sheppard, K. (2001). Theoretical and Empirical Properties of Dynamic Conditional Correlation Multivariate GARCH. NBER Working Paper 8554. DOI
- Bollerslev, T. (1990). Modelling the Coherence in Short-Run Nominal Exchange Rates: A Multivariate Generalized ARCH Model. Review of Economics and Statistics, 72(3), 498-505. DOI
- Cappiello, L., Engle, R., & Sheppard, K. (2006). Asymmetric Dynamics in the Correlations of Global Equity and Bond Returns. Journal of Financial Econometrics, 4(4), 537-572. DOI
- Engle, R. & Kroner, K. (1995). Multivariate Simultaneous Generalized ARCH. Econometric Theory, 11(1), 122-150. DOI
- Bollerslev, T., Engle, R., & Wooldridge, J. (1988). A Capital Asset Pricing Model with Time-Varying Covariances. Journal of Political Economy, 96(1), 116-131. DOI
- Galanos, A. (2022). rmgarch: Multivariate GARCH Models. R package. CRAN.
MarketMaker.cc Team
Quantitative Research & Strategy