DCC-GARCH: Korelasi Dinamik untuk Pairs dan Risiko Portfolio
Tanya kebanyakan desk kripto tentang korelasi antara BTC dan ETH, dan anda akan mendapat satu nombor — 0.8, mungkin 0.75 — dikira sepanjang tempoh yang tiada siapa ingat bagaimana ia dipilih. Nombor itu adalah pembohongan, atau sekurang-kurangnya penyederhanaan yang berbahaya. Korelasi sampel adalah purata sepanjang tempoh di mana struktur pergantungan sebenar sentiasa berubah. Dalam pasaran yang tenang, BTC dan ETH bergerak berasingan cukup untuk menjadikan pair market-neutral kelihatan menarik. Dalam liquidation cascade, mereka terkunci antara satu sama lain dan dengan segala-galanya, dan diversifikasi yang anda bayar untuk itu menguap pada saat yang tepat anda memerlukannya.
Ini bukan kesan yang halus. Ambil mana-mana drawdown 2022 — kejatuhan LUNA pada Mei, pelepasan 3AC pada Jun, keruntuhan FTX pada November — dan anda akan lihat purata korelasi berpasangan merentas 20 token teratas bergerak dari julat 0.4-0.6 ke arah 0.9+ dalam beberapa hari. Korelasi bukan pemalar yang kadangkala dianggarkan dengan buruk; ia adalah siri masa dengan dinamiknya sendiri, kluster tersendiri, dan rejimnya sendiri. Menganggapnya sebagai skalar adalah setara multivariat dengan menganggap volatiliti konstan — kesilapan yang telah kita habiskan Bahagian 1 siri ini untuk membongkarnya bagi satu aset.
Artikel ini adalah Bahagian 3 daripada siri volatiliti empat bahagian. Bahagian 1 membina GARCH(1,1) univariat dengan pustaka arch dan menunjukkan bagaimana volatiliti berkluster dan kembali ke min. Bahagian 2 menambah asimetri (GJR-GARCH, EGARCH) dan inovasi Student-t untuk menangkap kesan leverage dan ekor tebal. Di sini kita beralih kepada multivariat: kita memodelkan seluruh matriks kovarians bersyarat ketika ia berkembang, menggunakan model Dynamic Conditional Correlation (DCC) oleh Engle. Ini memberikan kita dua perkara yang tidak pernah mampu diberikan oleh korelasi skalar — nisbah lindung nilai dinamik untuk pairs trading, dan varians portfolio yang jujur dan berubah mengikut masa untuk peruntukan berasaskan risiko. Bahagian 4 menutup siri ini dengan backtest volatility-targeted yang mengikat ramalan univariat dan multivariat kepada peraturan position-sizing.
Kami menganggap anda telah membaca Bahagian 1 dan 2, jadi kami tidak akan menerbitkan semula GARCH univariat. Jika anda mahukan gelagat ekor bersama — kebarangkalian dua aset melanggar kuantil 1% mereka secara serentak — itu adalah persoalan copula, dan kami membincangkannya dalam Model Copula untuk Risiko Bersama. DCC dan copula saling melengkapi: copula memberikan anda struktur ketergantungan-ekor yang statik tetapi fleksibel, manakala DCC memberikan anda siri masa yang boleh diurus bagi keseluruhan matriks korelasi. Artikel ini tentang yang kedua.
Mengapa Korelasi Statik Gagal dalam Kripto
Sebelum menyelami mekanismenya, mari kita tepat tentang apa yang gagal. Satu korelasi sampel sepanjang tetingkap menganggarkan
Ini membawa tiga andaian tersirat, semuanya palsu untuk kripto:
- Kestasioneran ketergantungan. Tetingkap tersebut mempunyai satu sebenar. Pada hakikatnya ketergantungan mempunyai rejim — rejim pasaran tenang berhampiran 0.5 dan rejim tekanan berhampiran 0.95 — dan mencampurkan mereka menjadi purata yang tidak bermakna.
- Volatiliti margin yang konstan. Korelasi Pearson ialah kovarians ternormal. Jika dan sendiri bergerak (dan memang bergerak — itulah keseluruhan premis Bahagian 1 dan 2), maka walaupun kovarians yang konstan menghasilkan korelasi yang berubah mengikut masa, dan sebaliknya. Anda tidak boleh memisahkan kedua-duanya tanpa model volatiliti di bawahnya.
- Simetri merentas arah pasaran. Korelasi meningkat dalam drawdown lebih daripada dalam rali. Ini adalah saudara multivariat kepada kesan leverage. Tetingkap bergolek tidak dapat menyatakannya tanpa menjadi begitu pendek sehingga ia menjadi bunyi bising semata-mata.
Penyelesaian tetingkap-bergolek — mengira semula sepanjang 30 atau 60 hari terakhir — menukar satu masalah dengan masalah lain. Tetingkap pendek responsif tetapi bising dan lewat daripada perubahan sebenar; tetingkap panjang stabil tetapi lapuk. Lebih teruk lagi, matriks korelasi bergolek merentas aset tidak dijamin kekal positive semi-definite sebaik sahaja anda mula menyusutkan atau menampalnya, yang merosakkan setiap pengoptimum hiliran. Kita mahukan model yang (a) dipacu oleh proses volatiliti yang betul bagi setiap aset, (b) menghasilkan matriks korelasi yang sah pada setiap langkah secara binaan, dan (c) mempunyai parameter yang boleh kita anggarkan melalui maximum likelihood dan bukannya memilih panjang tetingkap secara sembarangan. Model itu ialah DCC-GARCH.
Masalah Multivariat: Matriks Kovarians Bersyarat
Biarkan menjadi vektor pulangan bagi aset pada masa , dengan min bersyarat (selalunya hanya pemalar atau term AR kecil) dan reja . Kita anggap
di mana ialah matriks kovarians bersyarat diberikan set maklumat , dan ialah taburan bersyarat tertentu (Gaussian atau, lebih baik untuk kripto, Student-t multivariat). Segala-galanya dalam pemodelan volatiliti multivariat adalah jawapan berbeza kepada satu persoalan: bagaimana anda memparameterkan dinamik supaya ia kekal simetri positive definite pada setiap langkah tanpa letupan bilangan parameter?
Dua jawapan klasik menunjukkan mengapa masalah ini sukar.
VECH
Model VECH (Bollerslev, Engle, Wooldridge 1988) menulis half-vectorization sebagai fungsi linear reja kuasa dua lepas dan kovarians lepas:
di mana menyusun segi tiga bawah matriks simetri menjadi vektor sepanjang . Ini adalah paling umum — setiap varians dan kovarians bergantung pada setiap varians dan kovarians lepas — dan paling tidak berguna melebihi . Bagi aset, dan masing-masing berukuran . Pada itu adalah dua matriks , kira-kira 450 parameter, ditambah kekangan positive-definiteness yang menyakitkan untuk dinyatakan pun. Permukaan likelihood adalah rawa.
BEKK
Model BEKK (Engle & Kroner 1995) menjamin positive definiteness secara binaan menggunakan bentuk kuadratik:
dengan segi tiga atas. Kerana setiap term ialah bentuk kuadratik, secara automatik selagi . BEKK lebih parsimoni daripada VECH tetapi masih berskala sebagai parameter — matriks dan masing-masing berukuran . Bagi anda sedang menganggarkan kira-kira 200+ parameter secara bersama melalui MLE, pada data kripto harian yang bising, tanpa jaminan pengoptimum menumpu kepada apa-apa yang bermakna. Pada praktiknya BEKK penuh dihadkan kepada , dan walaupun begitu orang menggunakan sekatan "diagonal" atau "skalar" yang membuang kebanyakan dinamik silang.
Ini adalah kutukan dimensi untuk GARCH multivariat: bilangan parameter berkembang secara kuadratik, tetapi jumlah maklumat dalam data tidak. Anda kehabisan darjah kebebasan jauh sebelum anda kehabisan aset yang anda pedulikan. Mana-mana buku kripto dengan 10-30 token adalah sama sekali di luar jangkauan untuk VECH atau BEKK.
Jalan keluar, hasil kerja Engle, adalah untuk berhenti cuba memodelkan secara langsung dan sebaliknya memfaktorkannya kepada bahagian yang sudah kita tahu cara menganggarkan dengan murah.
DCC Engle (2002): Penguraian Dua-Langkah
Model Constant Conditional Correlation (CCC) Bollerslev (1990) adalah pemfaktoran parsimoni pertama. Ia menulis
di mana ialah matriks diagonal sisihan piawai bersyarat — satu GARCH univariat bagi setiap aset — dan ialah matriks korelasi konstan. Ini adalah penyederhanaan besar: anda memasang model GARCH univariat bebas, kemudian menganggarkan satu matriks korelasi sampel bagi reja ternormal. Positive definiteness adalah automatik selagi adalah matriks korelasi yang sah dan semua .
Masalah CCC ada di dalam namanya sendiri — korelasi itu konstan, yang tepat merupakan andaian yang kita tolak sejak awal artikel ini. Dynamic Conditional Correlation Engle (2002) mengekalkan pemfaktoran indah CCC tetapi membiarkan matriks korelasi bernafas:
Kini berubah mengikut masa. Kebijaksanaannya adalah volatiliti dan korelasi dianggarkan dalam dua langkah berasingan, jadi kita tidak pernah berhadapan dengan pengoptimuman bersama penuh.
Langkah 1: GARCH univariat bagi setiap aset
Bagi setiap aset , pasang model GARCH univariat tepat seperti dalam Bahagian 1 dan 2 — GARCH(1,1), GJR-GARCH, atau EGARCH dengan inovasi Student-t, apa sahaja yang sesuai bagi siri tersebut. Ini memberikan varians bersyarat dan seterusnya .
Daripada model yang dipasang kita ekstrak reja ternormal:
Secara binaan setiap mempunyai (secara anggaran) varians bersyarat unit. Susun mereka ke dalam vektor . Reja ternormal ini adalah bahan mentah bagi langkah korelasi — dinamik volatiliti individu mereka telah dikupas keluar, jadi pergerakan bersama yang tinggal adalah ketergantungan tulen, bukan artifak volatiliti. (Ini adalah logik gaya PIT yang sama yang digunakan artikel copula sebelum memasang margin; di sini kita berhenti pada penormalan dan bukan pergi sepenuhnya kepada uniform.)
Langkah 2: Rekursi korelasi DCC
Kita memodelkan proses bantu , matriks simetri positive-definite, dengan rekursi gaya GARCH dipacu oleh hasil darab luar reja ternormal:
di mana:
- ialah matriks korelasi tidak bersyarat bagi reja ternormal (ini ialah correlation targeting — lebih lanjut di bawah),
- mengawal betapa kuat kejutan hari ini menarik korelasi,
- mengawal ketekalan — berapa banyak semalam terus dibawa,
- dan kekangan kembali-ke-min ialah (dengan ), analog secara langsung dengan dalam GARCH univariat.
Perhatikan strukturnya adalah serupa dengan rekursi GARCH(1,1) skalar, tetapi pada matriks: penambat jangka panjang , term kejutan, dan term ketekalan. Kerana ia adalah gabungan cembung matriks positive-semi-definite (, hasil darab luar rank-1, dan sebelumnya), kekal positive definite selagi dan pemberat tidak negatif. Inilah yang memberikan kita matriks kovarians yang sah secara terjamin secara percuma.
hampir menjadi matriks korelasi tetapi tidak tepat — diagonalnya tidak tepat 1. Jadi kita normalkannya:
Secara unsur, korelasi bersyarat antara aset dan ialah
ini ialah matriks korelasi yang betul — diagonal unit, off-diagonal dalam , positive definite — pada setiap langkah masa, secara binaan. Susun semula kovarians bersyarat penuh:
Bentuk unsur terakhir itu adalah yang akan anda gunakan secara berterusan: kovarians bersyarat dua aset ialah korelasi dinamik mereka didarab dengan setiap volatiliti dinamik mereka. Setiap ramuan di sebelah kanan berubah mengikut masa dan datang daripada model yang boleh anda anggarkan.
Keseluruhan model hanya mempunyai dua parameter korelasi, dan , tanpa mengira sama ada atau . Sisi volatiliti berskala secara linear (satu GARCH univariat bagi setiap aset, masing-masing dengan ~4-5 parameter, semua dipasang secara bebas dan selari secara memalukan). Inilah sebabnya DCC berskala di mana BEKK dan VECH tidak boleh: kutukan dimensi terhad kepada , yang disasarkan (dimasukkan sebagai anggaran sampel) dan bukannya dioptimumkan.
Sekatan skalar dan kosnya
Skalar bermakna setiap pasangan aset berkongsi dinamik korelasi yang sama — kelajuan penyesuaian dan ketekalan yang sama. Korelasi BTC-ETH dan korelasi DOGE-SHIB bergerak pada rentak yang sama walaupun ekonomi mereka berbeza. Ini adalah harga kebolehurusan, dan biasanya harga yang boleh diterima. Generalisasi (Generalized DCC dengan matriks ; DCC asimetri Cappiello-Engle-Sheppard) melonggarkan ini dengan kos parameter dan kestabilan penganggaran. Kami menyebut aDCC di bawah.
Quasi-Log-Likelihood DCC
Untuk menganggarkan dan kita memerlukan likelihood. Keputusan utama Engle ialah log-likelihood Gaussian memisahkan kepada bahagian volatiliti dan bahagian korelasi, yang mewajarkan penganggar dua-langkah. Dengan andaian , sumbangan log-likelihood pada masa ialah
Gantikan . Maka dan , dan menggunakan :
Sekarang pisahkan dengan menambah dan menolak :
Bahagian volatiliti hanya bergantung pada parameter GARCH univariat (melalui ) — memaksimumkannya adalah tepat memasang model GARCH univariat bebas, yang telah kita lakukan dalam Langkah 1. Bahagian korelasi bergantung pada dan (melalui ), diberikan reja ternormal daripada Langkah 1. Jadi dalam Langkah 2 kita hanya memaksimumkan
(term tidak bergantung pada , jadi kita gugurkannya). Ini adalah pengoptimuman dua-parameter tidak kira berapa banyak aset — itulah keseluruhan intinya. Ia dipanggil likelihood quasi kerana penganggar dua-langkah adalah konsisten tetapi tidak sepenuhnya cekap; ralat piawai memerlukan pembetulan (Engle & Sheppard 2001), tetapi untuk penjanaan isyarat anggaran titik itulah yang penting.
Untuk kripto, inovasi Gaussian meremehkan risiko ekor. Menukarkan kepada likelihood Student-t multivariat adalah perubahan drop-in kepada (gantikan kernel Gaussian dengan ketumpatan- multivariat dan tambah parameter darjah kebebasan ). Kami mengekalkan quasi-likelihood Gaussian dalam penganggar di bawah untuk kejelasan dan mencatat di mana masuk — penormalan daripada Bahagian 1-2 telah menggunakan inovasi-t pada margin, yang menangkap kebanyakan manfaat ekor.
Pelaksanaan Python
Satu fakta yang tegas: pustaka arch tidak melakukan GARCH multivariat atau DCC. arch adalah enjin univariat yang cemerlang (kami bergantung padanya untuk itu tepat), tetapi tiada dcc_model di dalamnya. Pilihan praktikal anda ialah:
- Bina DCC anda sendiri di atas
arch— pasang model univariat denganarch, ekstrak reja ternormal, laksanakan rekursi dan quasi-likelihood korelasi dalam NumPy/SciPy, dan optimumkan dua skalar. Inilah yang kita lakukan di bawah. Ia kira-kira 60 baris dan sepenuhnya telus. - Pakej PyPI
mgarch— pelaksanaan DCC-GARCH pure-Python yang ringan. Sesuai untuk pemasangan pantas, kurang fleksibel jika anda mahukan margin GJR atau inovasi-t yang dipasang dengan tepat. rmgarchR (Alexios Galanos) — pelaksanaan rujukan.dccspec/dccfitmenyokong DCC, aDCC, GARCH-copula, Student-t, dan ralat piawai yang betul. Jika anda melakukan penyelidikan volatiliti multivariat yang serius,rmgarch(dipanggil daripada Python melaluirpy2jika perlu) adalah piawaian emas.
Kami membina pilihan 1 kerana ia menjadikan setiap bahagian bergerak jelas dan menggunakan semula kemahiran univariat daripada Bahagian 1-2.
Langkah 1: Pasang margin GARCH univariat dengan arch
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())
Pemeriksaan waras yang pantas pada reja ternormal amat penting. Jika mana-mana lajur mempunyai sisihan piawai jauh daripada 1, atau autokorelasi baki yang berat dalam kuasa duanya (Ljung-Box pada ), margin univariat itu tersalah-spesifikasi dan langkah DCC akan mewarisi ralat tersebut. Betulkan margin dahulu — itulah tujuan Bahagian 2.
Langkah 2: Rekursi DCC dan 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)
Menjalankan ini pada buku BTC/ETH/SOL/BNB sepanjang beberapa tahun data harian menghasilkan output dalam bentuk berikut (nombor di bawah adalah ilustratif, bukan daripada eksperimen bertarikh tertentu — jalankan pada data anda sendiri):
DCC estimates: a = 0.0287, b = 0.9401, a+b = 0.9688
log-likelihood: -3812.44
Cara membacanya:
- adalah kecil — matriks korelasi tidak melonjak dengan kejutan satu hari. Setiap hari menolak ke arah hasil darab luar hanya sebanyak ~3%.
- adalah besar — korelasi sangat berterusan. Sebaik sahaja buku itu tergandeng dalam peristiwa tekanan, ia kekal tergandeng untuk seketika, mereput kembali ke arah secara perlahan. Ini sepadan dengan pengalaman sebenar drawdown kripto: korelasi tidak kembali serta-merta sebaik sahaja harga stabil.
- mengesahkan kembali-ke-min. Proses korelasi mempunyai tahap jangka panjang stasioner () yang ia kembali kepadanya, dengan separuh hayat kira-kira hari. Jika anda pernah menganggarkan hampir sama dengan 1, proses korelasi itu tersepadu — ia tiada penambat jangka panjang, biasanya gejala perubahan struktur di dalam sampel anda yang diserap oleh model sebagai ketekalan tak terhingga.
Ketekalan hampir-unit dan pembebanan kejutan yang kecil adalah cap jari DCC kanonik merentas kelas aset, dan kripto tidak terkecuali. Inilah juga sebabnya korelasi bergolek 30-hari adalah pengganti yang begitu lemah: tetingkap bergolek secara tersirat menganggap dan yang langsung tidak sepadan dengan struktur pereputan ini.
Beberapa nota pelaksanaan yang menjimatkan masa penyahpepijatan sebenar:
- Permulaan. Bermula pada
[0.03, 0.94]mencerminkan anggaran kripto biasa: kecil (korelasi bertindak balas kepada kejutan tetapi tidak ganas), besar (korelasi berterusan). Jika pengoptimum anda mengembara ke proses korelasi itu tersepadu — biasanya tanda perubahan struktur dalam sampel (perubahan rejim yang model itu bertungkus-lumus untuk memuatkan sebagai ketekalan). - Konvensyen pemasaan. Di dalam gelung kita menilai terhadap dan kemudian mengemas kini dengan untuk langkah seterusnya. Ini mengekalkan sebagai fungsi maklumat hingga sahaja — tiada look-ahead. Melakukan silap satu ini adalah bug DCC yang paling biasa, dan ia secara senyap menggembungkan kesesuaian dalam-sampel.
- Correlation targeting. Kami memasukkan sebagai korelasi sampel dan bukannya menganggarkannya. Inilah yang menjadikan pengoptimuman dua-dimensi. Kosnya ialah menggunakan sampel penuh, jadi dalam walk-forward yang ketat anda mesti menganggarkan semula pada tetingkap latihan sahaja (lihat di bawah).
Langkah 3: Membina semula laluan korelasi dan kovarians
Setelah ditetapkan, jalankan rekursi sekali lagi, kali ini menyimpan laluan penuh (dan ) supaya strategi hiliran boleh menggunakannya.
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))
Siri rho_btc_eth adalah ganjaran keseluruhan latihan ini: dan bukannya satu nombor, kini anda mempunyai korelasi harian yang boleh anda plot, ambang, atau suapkan ke dalam strategi. Pada data kripto sebenar anda biasanya akan melihat ia berjulat daripada kira-kira 0.5 dalam tempoh tenang hingga melebihi 0.9 semasa tekanan — julat sebenar yang dipuratakan oleh satu korelasi sampel.
Ramalan satu-langkah-ke-hadapan
Untuk perdagangan langsung anda memerlukan satu-langkah-ke-hadapan daripada maklumat yang tersedia sekarang. Sisi volatiliti datang daripada ramalan satu-langkah setiap model arch; sisi korelasi adalah satu lagi pusingan rekursi:
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)
Ingat segala-galanya dalam unit berskala (×100) kerana kita memasang arch pada series * 100. Bahagikan volatiliti dengan 100 (dan kovarians dengan ) untuk kembali kepada unit pulangan mentah sebelum menyuap ke dalam strategi. Mengekalkan penskalaan yang betul adalah membosankan tetapi sumber bug senyap yang kerap.
Aplikasi 1: Nisbah Lindung Nilai Dinamik untuk Pairs Trading
Pair market-neutral klasik — beli satu aset, jual pendek jumlah beta-weighted aset lain — hidup atau mati bergantung pada nisbah lindung nilai . Anggarkannya melalui OLS statik sepanjang tetingkap latihan dan anda mewarisi tepat masalah korelasi-lapuk yang menjadi tumpuan keseluruhan artikel ini: lindung nilai yang meneutralkan pendedahan pasaran suku lalu adalah salah pada suku ini.
DCC memberikan anda nisbah lindung nilai sebagai siri masa. Lindung nilai varians-minimum bagi pendedahan ETH menggunakan BTC adalah pekali regresi bersyarat
Setiap term di sebelah kanan adalah output DCC. Nisbah lindung nilai bergerak atas dua sebab berbeza, dan DCC memisahkan mereka dengan bersih: korelasi berubah (aset bergandeng atau berpisah), dan nisbah volatiliti berubah (satu aset menjadi lebih volatil secara relatif). Beta rolling-OLS mengaburkan kedua-dua kesan bersama dengan lat; DCC mengaitkan mereka secara berasingan.
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()
Suap spread ke dalam enjin pairs apa sahaja yang anda jalankan. Lindung nilai dinamik itu sendiri tidak mencipta kelebihan — ia menjadikan spread yang anda dagangkan benar-benar market-neutral sepanjang masa, supaya isyarat kembali-ke-min anda tidak tercemar oleh pendedahan arah yang hanyut. Jika anda membina strategi pairs, ini terus masuk ke dalam rangka kerja dalam Statistical Arbitrage & Pairs Trading dalam Kripto dan pendekatan jarak untuk pairs, menggantikan nisbah lindung nilai tetap mereka. Siri korelasi itu sendiri juga merupakan input yang lebih bersih kepada isyarat pair berasaskan korelasi berbanding mana-mana tetingkap bergolek — anda mendapat yang dilicinkan dan konsisten-model dan bukannya anggaran bertetingkap yang bising.
Dua peringatan khusus untuk menggunakan secara langsung. Pertama, lat-kan — dagang pada , bukan semasa, atau anda sedang mengintip. Kedua, nisbah lindung nilai yang berayun setiap hari menjana turnover dan yuran; dalam pasaran 24/7 kripto dengan kos pendanaan pada kaki pendek, lindung nilai yang terlalu bertindak balas boleh berdarah lebih daripada hanyutan yang ia betulkan. Licinkan (EWMA, atau imbang semula lindung nilai hanya apabila ia melepasi jalur) dan saizkan keseluruhan dengan waras — position sizing daripada isyarat bising adalah disiplin tersendiri, dibincangkan dalam saiz strategi Kriteria Kelly.
Aplikasi 2: Varians Portfolio yang Berubah Mengikut Masa
Bagi portfolio dengan vektor pemberat , varians bersyarat ialah
Dengan matriks kovarians statik — lalai Markowitz — nombor ini adalah pemalar yang anda kira sekali dan berpura-pura masih benar. Ia tidak. Risiko portfolio bernafas dengan pasaran, dan ia bernafas paling kuat tepat apabila korelasi melonjak, kerana dalam drawdown kedua-dua term dan term meningkat bersama dan didarab. Portfolio yang kelihatan seperti 40% vol tahunan dalam pasaran tenang boleh berjalan pada 80%+ dalam minggu tekanan, dan matriks kovarians statik akan memberitahu anda tiada apa yang berubah.
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())
yang berubah mengikut masa ini adalah input jujur yang diperlukan oleh peruntukan berasaskan risiko. Pengoptimuman min-varians (Markowitz untuk kripto) dengan kovarians sampel yang statik mengoptimumkan terhadap fiksyen; menyuapkannya (atau ramalan jangka pendeknya) menjadikan sempadan cekap itu sendiri berubah mengikut masa dan memaksa pengoptimum mengurangkan risiko ke dalam rejim korelasi yang meningkat dan bukannya selepas ia berlaku. Pendekatan risk-parity dan hierarki — saluran paip HRP + CVaR — lebih sensitif lagi kepada input kovarians, kerana keseluruhan peruntukan adalah fungsi matriks risiko. Dan jika anda membandingkan pengagih secara bersemuka, seperti dalam algoritma pengoptimuman portfolio dibandingkan, sama ada mereka menggunakan kovarians statik atau dinamik sering menjadi pemacu risiko terealisasi yang lebih besar berbanding pilihan algoritma.
Aplikasi langsung ialah volatility targeting keseluruhan portfolio: pilih vol tahunan sasaran , dan skalakan pendedahan kasar mengikut setiap tempoh supaya risiko terealisasi kekal lebih kurang konstan dan bukannya membengkak dalam krisis. Ini menutup gelung dengan Bahagian 4, yang membina dan mem-backtest peraturan ini secara tepat.
Aplikasi 3: Korelasi sebagai Isyarat Rejim
Selain lindung nilai dan sizing, matriks korelasi membawa isyarat makro. Skalar paling berguna yang boleh anda ekstrak ialah purata korelasi berpasangan:
Apabila meningkat merentas buku, pasaran sedang memasuki rejim risk-off — cerita idiosinkratik berhenti bermakna dan segala-galanya berdagang sebagai satu beta makro. Ini adalah cap jari kuantitatif "korelasi menuju 1 dalam krisis." Ia cenderung mendahului atau berselari dengan drawdown, yang menjadikannya penunjuk rejim yang boleh digunakan dan bukan postmortem yang ketinggalan.
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)
Anda boleh menggunakan risk_off sebagai throttle berdiri sendiri (kurangkan pendedahan kasar, lebarkan stop, hentikan strategi kembali-ke-min yang akan tergilis apabila segala-galanya trend bersama) atau sebagai ciri dalam model rejim yang lebih formal. Ia sepadan secara semula jadi dengan pendekatan hidden-Markov dalam pengesanan rejim dengan HMM: purata korelasi DCC adalah salah satu pembolehubah pemerhatian yang lebih bermaklumat yang boleh anda berikan kepada HMM, kerana ia bersifat prospektif tentang tekanan sistemik dengan cara yang tidak dimiliki oleh pulangan tertinggal. Peringatan jujur: korelasi yang meningkat memberitahu anda diversifikasi sedang gagal, bukan ke arah mana pasaran akan bergerak. Ia adalah isyarat risiko, bukan isyarat alfa, dan harus disaizkan sedemikian — lihat asimetri kerugian dan keuntungan untuk memahami mengapa menganggap rejim risiko sebagai pertaruhan arah berakhir dengan buruk.
Pertimbangan Praktikal
Kestabilan penganggaran dan bilangan aset
DCC berskala jauh lebih baik daripada BEKK, tetapi "berskala" bukan bermakna "percuma." Matriks correlation-targeting adalah korelasi sampel , dan matriks korelasi sampel menjadi ill-conditioned apabila menghampiri bilangan pemerhatian. Dengan 4 aset dan 1000 hari anda baik-baik sahaja. Dengan 60 aset dan 400 hari, hampir singular, songsangannya dalam likelihood meletup, dan boleh mengembara menjadi bukan-PD akibat bunyi berangka. Mitigasi, secara kasar mengikut kekerapan anda akan memerlukannya:
- Susutkan ke arah sasaran berstruktur (Ledoit-Wolf, atau ke arah identiti / matriks korelasi konstan) sebelum menjalankan rekursi. Ini adalah pembetulan paling berkesan untuk buku besar.
- Kumpulkan aset ke dalam beberapa sektor (majors, L1s, DeFi, memes), modelkan dalam dan merentas peringkat sektor, atau jalankan DCC pada faktor komponen utama dan bukan aset mentah.
- Utamakan lebih banyak data berbanding lebih banyak aset. DCC mempunyai selera yang tidak berpuas untuk sejarah yang panjang, bersih, dan serentak — yang tepat tidak dimiliki oleh token muda.
Secara realistik, kekalkan DCC terus kepada beberapa dozen aset sahaja. Untuk semesta yang besar, DCC pada pulangan faktor tambah reja idiosinkratik adalah penyelesaian standard.
Correlation targeting adalah jalan pintas dengan kos
Menyasarkan menjadikan penganggaran boleh diurus tetapi membakar korelasi tidak bersyarat sampel-penuh ke dalam setiap . Dalam backtest yang ketat ini adalah kebocoran look-ahead: matriks korelasi hari- anda "tahu" purata korelasi keseluruhan sampel, termasuk masa depan. Untuk penilaian yang jujur anda mesti menganggarkan semula pada tetingkap latihan sahaja dan menetapkannya di luar-sampel, atau menggolekkannya ke hadapan. Ini adalah disiplin yang sama yang dikuatkuasakan oleh keseluruhan rangka kerja pengoptimuman walk-forward, dan ia mudah dilanggar secara tidak sengaja dengan np.cov(Z) yang mudah sepanjang array penuh — seperti yang dilakukan oleh kod pengajaran kita di atas. Betulkan sebelum anda mempercayai satu nombor P&L.
Kadar pemasangan semula dan disiplin look-ahead
Anda tidak perlu mengoptimumkan semula setiap hari — mereka adalah parameter yang stabil. Kadar produksi yang munasabah:
- Anggarkan semula dan parameter GARCH univariat setiap minggu atau bulan.
- Jalankan penapis (kemas kini , ) setiap tempoh dengan parameter yang dibekukan untuk mendapatkan dan terkini. Penapisan adalah murah; pemasangan tidak.
- Sentiasa ramalkan, jangan sekali-kali licinkan. Gunakan yang dibina daripada maklumat hingga untuk berdagang pada . Struktur dua-laluan (pasang pada tetingkap, kemudian tapis ke hadapan) itulah yang mengekalkan anda jujur.
Jurang antara backtest DCC dan prestasi langsung hampir selalu adalah kebocoran look-ahead — sampel-penuh, semasa, atau pemasangan semula pada data yang termasuk dagangan yang anda nilai. Disiplin memadankan backtest dengan keadaan langsung adalah topik tersendiri dalam parity backtest-langsung, dan DCC adalah model yang menghukum kecuaian di sini lebih daripada kebanyakan. Jika, selepas penilaian walk-forward yang bersih, korelasi dinamik tidak menambah apa-apa berbanding anggaran bergolek yang mudah untuk strategi anda, itu adalah keputusan negatif yang sebenar dan boleh diterbitkan — pemikiran dalam keputusan negatif yang jujur terpakai secara langsung.
DCC Asimetri (aDCC)
Sama seperti kesan leverage univariat (Bahagian 2) bermaksud berita buruk meningkatkan volatiliti lebih daripada berita baik, korelasi meningkat lebih banyak selepas kejutan negatif bersama berbanding selepas kejutan positif bersama. Cappiello, Engle & Sheppard (2006) menangkap ini dengan DCC asimetri, menambah term dipacu oleh hasil darab luar reja ternormal bahagian-negatif :
di mana dan mengukur tendangan korelasi tambahan daripada pergerakan draw bersama. Untuk kripto, di mana korelasi-crash adalah risiko dominan, term asimetri biasanya signifikan dan berbaloi dengan satu parameter tambahan. rmgarch memasang aDCC terus (model="aDCC"); menambah term kepada penganggar NumPy kita adalah latihan yang mudah.
Perbandingan: DCC Berbanding Alternatif
Di mana DCC berdiri antara cara anda boleh mendapatkan matriks kovarians untuk buku kripto? Ringkasan yang jujur:
| Pendekatan | Parameter | Berskala kepada | Berubah Mengikut Masa? | PD Terjamin? | Ketergantungan Ekor? |
|---|---|---|---|---|---|
| Kovarians sampel / bergolek | 0 (panjang tetingkap) | mana-mana | kasar (tertangguh, bising) | tidak (perlu ditampal) | tidak |
| EWMA (RiskMetrics) | 1 () | mana-mana | ya (satu pereputan) | ya | tidak |
| CCC-GARCH | margin + | dozen | tidak ( konstan) | ya | tidak |
| DCC-GARCH | margin + 2 | dozen | ya | ya | tidak |
| aDCC-GARCH | margin + 3 | dozen | ya, asimetri | ya | separa |
| BEKK | ya (kaya) | ya | tidak | ||
| VECH | ya (paling kaya) | menyakitkan | tidak | ||
| GARCH-copula | margin + copula | dozen (vines) | copula statik | ya | ya |
Beberapa bacaan jadual ini:
- EWMA adalah asas murah yang harus dikalahkan oleh semua orang sebelum mendakwa DCC membantu. Ia adalah kes khas satu-parameter dari segi semangat — satu pereputan eksponen tunggal digunakan pada kovarians secara langsung — dan untuk banyak buku ia sukar dipertingkatkan secara mengejutkan di luar-sampel. Jika DCC tidak mengatasi EWMA dalam walk-forward yang bersih, gunakan EWMA.
- CCC vs DCC adalah keseluruhan intipati artikel ini: pemfaktoran sama, tetapi CCC membekukan dan DCC membiarkannya bergerak. Dua parameter tambahan () adalah keseluruhan perbezaan, dan dalam kripto mereka berbaloi dengan usaha mereka.
- BEKK/VECH membeli dinamik yang lebih kaya — setiap kovarians boleh bertindak balas kepada setiap kejutan lepas — tetapi kos parameter mengehadkan mereka kepada buku kecil. Untuk lebih daripada 4 aset ia bukan pilihan sebenar.
- GARCH-copula adalah satu-satunya baris dengan "ya" di bawah ketergantungan ekor. Itulah pelengkap semula: DCC memodelkan pusat dinamik taburan bersama, copula memodelkan ekor statiknya. Jika soalan risiko anda ialah "apa berlaku apabila segala-galanya runtuh sekaligus," rujuk saluran paip copula; jika ia "berapakah nisbah lindung nilai / varians portfolio saya sekarang," rujuk DCC.
Lalai praktikal untuk desk kripto sistematik: DCC (atau aDCC) untuk nisbah lindung nilai dan kovarians dinamik pada badan, overlay copula untuk risiko-ekor dan CVaR, dan EWMA sebagai asas pemeriksaan waras yang mengekalkan anda jujur tentang sama ada mesin tambahan itu berbaloi.
Batasan
- Dinamik skalar. Satu dan satu untuk semua pasangan adalah sekatan yang kuat. BTC-ETH dan dua alt-coin yang jarang dikenali berkongsi kelajuan penyesuaian yang sama. Generalized DCC melonggarkan ini tetapi memperkenalkan semula letupan parameter yang DCC direka untuk mengelakkan.
- Kehilangan kecekapan dua-langkah. Penganggar quasi-likelihood adalah konsisten tetapi tidak sepenuhnya cekap, dan ralat piawai naif adalah salah. Gunakan pembetulan Engle-Sheppard jika anda peduli tentang inferens; untuk penjanaan isyarat anggaran titik sudah memadai.
- Ekor Gaussian secara lalai. Quasi-likelihood Gaussian biasa meremehkan risiko ekor bersama. Inovasi Student-t membantu; untuk ketergantungan ekor yang sebenar (kebarangkalian pergerakan ekstrem serentak), DCC adalah alat yang salah dan model copula adalah yang betul. DCC memberikan anda badan dinamik korelasi; copula memberikan anda ekor statik. Desk yang serius menggunakan kedua-duanya.
- Korelasi bukan sebab-akibat, dan bukan arah. yang meningkat memberi amaran bahawa diversifikasi sedang gagal; ia tidak memberitahu apa-apa tentang arah pasaran. Jangan bebankan isyarat risiko dengan jangkaan arah.
- Kelaparan data. Segala-galanya di atas menganggap sejarah yang panjang, bersih, dan diselaraskan. Token kripto yang paling baru dan menarik melanggar ketiga-tiganya.
Ringkasan
- Korelasi statik adalah pembohongan dalam kripto. Korelasi berkluster, berterusan, dan melonjak ke arah 1 dalam drawdown — tepat apabila diversifikasi sepatutnya membantu. Satu sampel memuratakan proses berganti-rejim menjadi purata yang tidak bermakna.
- GARCH multivariat penuh (VECH, BEKK) tidak berskala. Bilangan parameter berkembang sebagai ; kedua-duanya terhad kepada beberapa aset sahaja pada praktiknya.
- DCC (Engle 2002) memfaktorkan masalah: , dengan daripada pemasangan GARCH univariat bebas (guna semula Bahagian 1-2) dan daripada rekursi dua-parameter. Ia berskala kepada dozen aset kerana hanya yang dioptimumkan.
- Rekursi , dinormalkan kepada , menghasilkan matriks korelasi positive-definite yang sah pada setiap langkah, dengan , .
archtidak melakukan DCC. Pasang margin denganarch, kemudian laksanakan penganggar NumPy/SciPy ~60-baris di sini, atau gunakanmgarch(Python) ataurmgarch(R, rujukan).- Tiga ganjaran konkrit: nisbah lindung nilai dinamik untuk pairs trading; varians portfolio yang jujur dan berubah mengikut masa untuk peruntukan berasaskan risiko; dan purata korelasi berpasangan sebagai isyarat rejim risk-off.
- Disiplin adalah segala-galanya. Correlation targeting membocorkan purata sampel-penuh, jadi anggarkan semula pada data latihan sahaja; lat-kan setiap nisbah lindung nilai; tapis ke hadapan, jangan sekali-kali licinkan. Penilaian walk-forward tidak boleh dirunding.
- aDCC menambah term asimetri-draw dan biasanya berbaloi dalam kripto, di mana korelasi-crash mendominasi.
- Bahagian 4 menggunakan ramalan ini untuk membina dan mem-backtest strategi volatility-targeted.
Rujukan:
- 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
Penyelidikan & Strategi Kuantitatif