← Kembali ke artikel
July 12, 2026
5 menit baca

DCC-GARCH: Korelasi Dinamis untuk Pairs dan Risiko Portofolio

#volatility
#GARCH
#DCC
#correlation
#portfolio
#pairs-trading
#crypto

Tanyakan pada sebagian besar meja perdagangan kripto tentang korelasi antara BTC dan ETH, dan Anda akan mendapatkan satu angka tunggal — 0,8, mungkin 0,75 — yang dihitung atas suatu jendela yang tak seorang pun ingat pernah memilihnya. Angka itu adalah sebuah kebohongan, atau setidaknya penyederhanaan yang berbahaya. Korelasi sampel adalah rata-rata sepanjang suatu periode di mana struktur ketergantungan yang sebenarnya bergerak terus-menerus. Di pasar yang tenang, BTC dan ETH melenceng cukup jauh sehingga membuat pair yang market-neutral tampak menarik. Dalam sebuah kaskade likuidasi, keduanya saling terkunci satu sama lain dan dengan segala hal lainnya, dan diversifikasi yang telah Anda bayar menguap tepat pada saat Anda membutuhkannya.

Ini bukan efek yang halus. Tarik drawdown mana pun dari tahun 2022 — keruntuhan LUNA pada Mei, unwinding 3AC pada Juni, keruntuhan FTX pada November — dan Anda akan melihat rata-rata korelasi berpasangan di antara 20 token teratas beranjak dari kisaran 0,4-0,6 menuju 0,9+ dalam hitungan hari. Korelasi bukanlah konstanta yang sesekali diestimasi dengan buruk; ia adalah sebuah deret waktu dengan dinamikanya sendiri, clustering-nya sendiri, dan rezim-rezimnya sendiri. Memperlakukannya sebagai skalar adalah padanan multivariat dari mengasumsikan volatilitas yang konstan — sebuah kesalahan yang sudah kita bongkar untuk satu aset tunggal di Bagian 1 dari seri ini.

Artikel ini adalah Bagian 3 dari seri volatilitas empat bagian. Bagian 1 membangun GARCH(1,1) univariat dengan library arch dan menunjukkan bagaimana volatilitas mengelompok dan kembali ke rata-rata (mean-revert). Bagian 2 menambahkan asimetri (GJR-GARCH, EGARCH) dan inovasi Student-t untuk menangkap efek leverage dan fat tails. Di sini kita beralih ke multivariat: kita memodelkan seluruh matriks kovariansi kondisional HtH_t saat ia berevolusi, menggunakan model Dynamic Conditional Correlation (DCC) dari Engle. Itu memberi kita dua hal yang tidak pernah bisa diberikan oleh korelasi skalar — sebuah hedge ratio dinamis untuk pairs trading, dan variansi portofolio yang jujur serta berubah seiring waktu untuk alokasi berbasis risiko. Bagian 4 menutup seri ini dengan sebuah backtest yang menargetkan volatilitas (volatility-targeted) yang mengikat prakiraan univariat dan multivariat ke dalam sebuah aturan penentuan ukuran posisi.

Kami mengasumsikan Anda telah membaca Bagian 1 dan 2, sehingga kami tidak akan menurunkan ulang GARCH univariat. Jika Anda menginginkan perilaku tail bersama — probabilitas bahwa dua aset menembus kuantil 1% mereka secara bersamaan — itu adalah pertanyaan copula, dan kami membahasnya di Copula Models for Joint Risk. DCC dan copula bersifat saling melengkapi: copula memberi Anda struktur ketergantungan ekor (tail-dependence) yang statis namun fleksibel, sementara DCC memberi Anda sebuah deret waktu yang tractable dari keseluruhan matriks korelasi. Artikel ini membahas yang terakhir.

Mengapa Korelasi Statis Gagal di Kripto

Sebelum masuk ke mekanismenya, mari kita tepat mengenai apa yang gagal. Sebuah korelasi sampel tunggal ρ^\hat{\rho} atas jendela [tw,t][t-w, t] mengestimasi

ρ^ij=s(ri,srˉi)(rj,srˉj)s(ri,srˉi)2s(rj,srˉj)2\hat{\rho}_{ij} = \frac{\sum_{s} (r_{i,s} - \bar{r}_i)(r_{j,s} - \bar{r}_j)}{\sqrt{\sum_s (r_{i,s}-\bar{r}_i)^2}\sqrt{\sum_s (r_{j,s}-\bar{r}_j)^2}}

Ini membawa tiga asumsi implisit, semuanya keliru untuk kripto:

  1. Stasioneritas ketergantungan. Jendela tersebut memiliki satu ρ\rho yang sebenarnya. Pada kenyataannya ketergantungan memiliki rezim — sebuah rezim pasar tenang di sekitar 0,5 dan sebuah rezim stres di sekitar 0,95 — dan ρ^\hat{\rho} mencampur keduanya menjadi sebuah nilai tengah yang tak bermakna.
  2. Volatilitas marginal yang konstan. Korelasi Pearson adalah kovariansi yang dinormalisasi. Jika σi,t\sigma_{i,t} dan σj,t\sigma_{j,t} sendiri bergerak (dan memang demikian — itulah keseluruhan premis dari Bagian 1 dan 2), maka bahkan sebuah kovariansi yang konstan pun menghasilkan sebuah korelasi yang berubah seiring waktu, dan sebaliknya. Anda tidak dapat memisahkan keduanya tanpa sebuah model volatilitas yang mendasarinya.
  3. Simetri lintas arah pasar. Korelasi naik dalam drawdown lebih besar ketimbang dalam rally. Ini adalah sepupu multivariat dari efek leverage. Sebuah jendela bergulir (rolling window) tidak dapat mengekspresikannya tanpa menjadi begitu pendek sehingga menjadi murni derau (noise).

Perbaikan berupa jendela bergulir — menghitung ulang ρ^\hat{\rho} atas 30 atau 60 hari terakhir — menukar satu masalah dengan masalah lain. Jendela pendek responsif tetapi berisik dan tertinggal dari titik patah yang sesungguhnya; jendela panjang stabil tetapi usang. Lebih buruk lagi, sebuah matriks korelasi bergulir atas dd aset tidak dijamin tetap positive semi-definite begitu Anda mulai menyusutkan atau menambalnya, dan itu merusak setiap optimizer hilir (downstream). Kita menginginkan sebuah model yang (a) digerakkan oleh sebuah proses volatilitas yang tepat per aset, (b) menghasilkan sebuah matriks korelasi yang valid pada setiap langkah secara konstruksi, dan (c) memiliki parameter yang dapat kita estimasi melalui maximum likelihood alih-alih dengan memilih panjang jendela secara sembarangan. Model itu adalah DCC-GARCH.

Masalah Multivariat: Matriks Kovariansi Kondisional

Misalkan rtRdr_t \in \mathbb{R}^d adalah vektor imbal hasil untuk dd aset pada waktu tt, dengan rata-rata kondisional μt\mu_t (sering kali hanya sebuah konstanta atau suku AR kecil) dan residual ϵt=rtμt\epsilon_t = r_t - \mu_t. Kita asumsikan

ϵtFt1D(0,Ht)\epsilon_t \mid \mathcal{F}_{t-1} \sim \mathcal{D}(0, H_t)

di mana HtH_t adalah matriks kovariansi kondisional berukuran d×dd \times d dengan diberikan himpunan informasi Ft1\mathcal{F}_{t-1}, dan D\mathcal{D} adalah suatu distribusi kondisional (Gaussian atau, lebih baik untuk kripto, Student-t multivariat). Segala hal dalam pemodelan volatilitas multivariat adalah jawaban yang berbeda atas satu pertanyaan: bagaimana Anda memarametrisasi dinamika HtH_t agar ia tetap symmetric positive definite pada setiap langkah tanpa ledakan jumlah parameter?

Dua jawaban klasik menunjukkan mengapa masalah ini sulit.

VECH

Model VECH (Bollerslev, Engle, Wooldridge 1988) menuliskan half-vectorization dari HtH_t sebagai fungsi linier dari residual kuadrat masa lalu dan kovariansi masa lalu:

vech(Ht)=c+Avech(ϵt1ϵt1)+Bvech(Ht1)\mathrm{vech}(H_t) = c + A\,\mathrm{vech}(\epsilon_{t-1}\epsilon_{t-1}') + B\,\mathrm{vech}(H_{t-1})

di mana vech()\mathrm{vech}(\cdot) menumpuk segitiga bawah dari sebuah matriks simetris menjadi sebuah vektor berpanjang d(d+1)/2d(d+1)/2. Ini bersifat maksimal umum — setiap variansi dan kovariansi bergantung pada setiap variansi dan kovariansi masa lalu — dan maksimal tak berguna melewati d=3d=3. Untuk dd aset, AA dan BB masing-masing berukuran d(d+1)2×d(d+1)2\frac{d(d+1)}{2} \times \frac{d(d+1)}{2}. Pada d=5d=5 itu berarti dua matriks 15×1515\times 15, kira-kira 450 parameter, ditambah kendala positive-definiteness yang menyakitkan bahkan untuk sekadar diekspresikan. Permukaan likelihood-nya adalah sebuah rawa.

BEKK

Model BEKK (Engle & Kroner 1995) menjamin positive definiteness secara konstruksi menggunakan sebuah bentuk kuadratik:

Ht=CC+Aϵt1ϵt1A+BHt1BH_t = C'C + A'\,\epsilon_{t-1}\epsilon_{t-1}'\,A + B'\,H_{t-1}\,B

dengan CC berbentuk segitiga atas (upper triangular). Karena setiap suku merupakan bentuk kuadratik, Ht0H_t \succ 0 secara otomatis selama CC0C'C \succ 0. BEKK lebih hemat parameter ketimbang VECH tetapi tetap berskala sebagai O(d2)O(d^2) parameter — matriks AA dan BB masing-masing berukuran d×dd \times d. Untuk d=10d=10 Anda mengestimasi dalam orde 200+ parameter secara bersamaan melalui MLE, atas data kripto harian yang berisik, tanpa jaminan bahwa optimizer akan konvergen ke sesuatu yang bermakna. Dalam praktik BEKK penuh terbatas pada d4d \le 4, dan bahkan pada saat itu orang menggunakan pembatasan "diagonal" atau "skalar" yang membuang sebagian besar dinamika lintas-aset.

Inilah kutukan dimensionalitas untuk GARCH multivariat: jumlah parameter tumbuh secara kuadratik, tetapi jumlah informasi dalam data tidak. Anda kehabisan derajat kebebasan jauh sebelum Anda kehabisan aset yang Anda pedulikan. Setiap book kripto dengan 10-30 token sepenuhnya di luar jangkauan VECH atau BEKK.

Jalan keluarnya, berkat Engle, adalah berhenti mencoba memodelkan HtH_t secara langsung dan alih-alih memfaktorkannya menjadi bagian-bagian yang sudah kita ketahui cara mengestimasinya secara murah.

DCC dari Engle (2002): Dekomposisi Dua Langkah

Model Constant Conditional Correlation (CCC) dari Bollerslev (1990) adalah faktorisasi hemat parameter yang pertama. Ia menuliskan

Ht=DtRDtH_t = D_t\, R\, D_t

di mana Dt=diag(σ1,t,,σd,t)D_t = \mathrm{diag}(\sigma_{1,t}, \ldots, \sigma_{d,t}) adalah matriks diagonal dari deviasi standar kondisional — satu GARCH univariat per aset — dan RR adalah sebuah matriks korelasi konstan. Ini merupakan penyederhanaan besar: Anda mencocokkan (fit) dd model GARCH univariat yang independen, lalu mengestimasi sebuah matriks korelasi sampel tunggal dari residual yang telah distandarisasi. Positive definiteness terjamin secara otomatis selama RR adalah matriks korelasi yang valid dan semua σi,t>0\sigma_{i,t} > 0.

Masalah CCC ada tepat di namanya — korelasinya konstan, yang persis merupakan asumsi yang kita tolak di pembuka artikel ini. Dynamic Conditional Correlation dari Engle (2002) mempertahankan faktorisasi indah CCC tetapi membiarkan matriks korelasi bernapas:

Ht=DtRtDtH_t = D_t\, R_t\, D_t

Kini RtR_t berubah seiring waktu. Kejeniusannya adalah bahwa volatilitas dan korelasi diestimasi dalam dua langkah terpisah, sehingga kita tidak pernah menghadapi optimasi bersama O(d2)O(d^2) yang penuh.

Langkah 1: GARCH univariat per aset

Untuk setiap aset ii, cocokkan sebuah model GARCH univariat persis seperti di Bagian 1 dan 2 — GARCH(1,1), GJR-GARCH, atau EGARCH dengan inovasi Student-t, apa pun yang paling cocok untuk deret tersebut. Ini memberikan variansi kondisional σi,t2\sigma_{i,t}^2 dan karenanya Dt=diag(σ1,t,,σd,t)D_t = \mathrm{diag}(\sigma_{1,t}, \ldots, \sigma_{d,t}).

Dari model-model yang telah dicocokkan kita mengekstrak residual yang distandarisasi:

zi,t=ϵi,tσi,tz_{i,t} = \frac{\epsilon_{i,t}}{\sigma_{i,t}}

Secara konstruksi setiap zi,tz_{i,t} memiliki (secara aproksimasi) variansi kondisional satuan. Tumpuk mereka menjadi sebuah vektor zt=(z1,t,,zd,t)z_t = (z_{1,t}, \ldots, z_{d,t})'. Residual yang distandarisasi ini adalah bahan mentah untuk langkah korelasi — dinamika volatilitas individualnya telah dilucuti, sehingga pergerakan bersama apa pun yang tersisa adalah ketergantungan murni, bukan artefak volatilitas. (Ini adalah logika gaya PIT yang sama yang digunakan artikel copula sebelum mencocokkan margin; di sini kita berhenti pada standarisasi alih-alih melangkah sampai ke uniform.)

Langkah 2: Rekursi korelasi DCC

Kita memodelkan sebuah proses bantu QtQ_t, sebuah matriks d×dd \times d yang simetris positive-definite, dengan rekursi ala GARCH yang digerakkan oleh outer product dari residual yang distandarisasi:

Qt=(1ab)Qˉ+azt1zt1+bQt1Q_t = (1 - a - b)\,\bar{Q} + a\, z_{t-1} z_{t-1}' + b\, Q_{t-1}

di mana:

  • Qˉ=1Tt=1Tztzt\bar{Q} = \frac{1}{T}\sum_{t=1}^{T} z_t z_t' adalah matriks korelasi tak-bersyarat (unconditional) dari residual yang distandarisasi (inilah correlation targeting — lebih lanjut mengenai ini di bawah),
  • a0a \ge 0 mengatur seberapa kuat guncangan hari ini zt1zt1z_{t-1}z_{t-1}' menarik korelasi,
  • b0b \ge 0 mengatur persistensi — seberapa banyak Qt1Q_{t-1} kemarin yang terbawa ke depan,
  • dan kendala mean-reversion adalah a+b<1a + b < 1 (dengan a,b>0a, b > 0), analog langsung dengan α+β<1\alpha + \beta < 1 pada GARCH univariat.

Perhatikan bahwa strukturnya identik dengan rekursi GARCH(1,1) skalar, tetapi pada matriks: sebuah jangkar jangka panjang Qˉ\bar{Q}, sebuah suku guncangan, dan sebuah suku persistensi. Karena ia merupakan kombinasi konveks dari matriks-matriks positive-semi-definite (Qˉ\bar{Q}, outer product berperingkat 1, dan Qt1Q_{t-1} sebelumnya), QtQ_t tetap positive definite selama Qˉ0\bar{Q} \succ 0 dan bobot-bobotnya non-negatif. Inilah yang memberi kita matriks kovariansi yang valid secara terjamin secara gratis.

QtQ_t hampir menjadi sebuah matriks korelasi tetapi tidak sepenuhnya — diagonalnya tidak persis 1. Maka kita menormalisasinya:

Rt=(diag(Qt))1/2Qt(diag(Qt))1/2R_t = \left(\mathrm{diag}(Q_t)\right)^{-1/2}\, Q_t\, \left(\mathrm{diag}(Q_t)\right)^{-1/2}

Secara elemen demi elemen, korelasi kondisional antara aset ii dan jj adalah

ρij,t=qij,tqii,tqjj,t\rho_{ij,t} = \frac{q_{ij,t}}{\sqrt{q_{ii,t}\, q_{jj,t}}}

RtR_t ini adalah matriks korelasi yang tepat — diagonal satuan, elemen luar-diagonal dalam [1,1][-1,1], positive definite — pada setiap langkah waktu, secara konstruksi. Susun kembali matriks kovariansi kondisional penuh:

Ht=DtRtDt,hij,t=ρij,tσi,tσj,tH_t = D_t\, R_t\, D_t, \qquad h_{ij,t} = \rho_{ij,t}\,\sigma_{i,t}\,\sigma_{j,t}

Bentuk elemen demi elemen yang terakhir itulah yang akan terus-menerus Anda gunakan: kovariansi kondisional dua aset adalah korelasi dinamis mereka dikalikan dengan masing-masing volatilitas dinamis mereka. Setiap bahan di ruas kanan berubah seiring waktu dan berasal dari sebuah model yang dapat Anda estimasi.

Keseluruhan model hanya memiliki dua parameter korelasi, aa dan bb, terlepas dari apakah d=2d = 2 atau d=50d = 50. Sisi volatilitas berskala secara linier (satu GARCH univariat per aset, masing-masing dengan ~4-5 parameter, semuanya dicocokkan secara independen dan sangat paralel). Inilah sebabnya DCC berskala di tempat BEKK dan VECH tidak bisa: kutukan dimensionalitas terbatas pada Qˉ\bar{Q}, yang di-target (dimasukkan sebagai estimasi sampel) alih-alih dioptimasi.

Pembatasan skalar dan biayanya

Skalar a,ba, b berarti setiap pasang aset berbagi dinamika korelasi yang sama — kecepatan penyesuaian yang sama dan persistensi yang sama. Korelasi BTC-ETH dan korelasi DOGE-SHIB bergerak pada irama yang sama meskipun ekonomi keduanya berbeda. Inilah harga dari tractability, dan biasanya ini adalah harga yang dapat diterima. Generalisasi (Generalized DCC dengan matriks A,BA, B; DCC asimetris Cappiello-Engle-Sheppard) melonggarkannya dengan mengorbankan parameter dan stabilitas estimasi. Kami menyebut aDCC di bawah.

Quasi-Log-Likelihood DCC

Untuk mengestimasi aa dan bb kita membutuhkan likelihood. Hasil kunci dari Engle adalah bahwa log-likelihood Gaussian terpisah menjadi sebuah bagian volatilitas dan sebuah bagian korelasi, yang merupakan pembenaran bagi estimator dua langkah. Dengan mengasumsikan ϵtFt1N(0,Ht)\epsilon_t \mid \mathcal{F}_{t-1} \sim \mathcal{N}(0, H_t), kontribusi log-likelihood pada waktu tt adalah

t=12(dlog(2π)+logHt+ϵtHt1ϵt)\ell_t = -\frac{1}{2}\left( d\log(2\pi) + \log|H_t| + \epsilon_t' H_t^{-1} \epsilon_t \right)

Substitusikan Ht=DtRtDtH_t = D_t R_t D_t. Maka Ht=Dt2Rt|H_t| = |D_t|^2 |R_t| dan Ht1=Dt1Rt1Dt1H_t^{-1} = D_t^{-1} R_t^{-1} D_t^{-1}, dan dengan menggunakan zt=Dt1ϵtz_t = D_t^{-1}\epsilon_t:

t=12(dlog(2π)+2logDt+logRt+ztRt1zt)\ell_t = -\frac{1}{2}\left( d\log(2\pi) + 2\log|D_t| + \log|R_t| + z_t' R_t^{-1} z_t \right)

Sekarang pisahkan dengan menambah dan mengurangi ztztz_t'z_t:

t=12(dlog(2π)+2logDt+ϵtDt2ϵt)bagian volatilitas   tV  12(logRt+ztRt1ztztzt)bagian korelasi   tC\ell_t = \underbrace{-\frac{1}{2}\left( d\log(2\pi) + 2\log|D_t| + \epsilon_t' D_t^{-2}\epsilon_t \right)}_{\text{bagian volatilitas }\;\ell_t^{V}} \;\underbrace{-\frac{1}{2}\left( \log|R_t| + z_t' R_t^{-1} z_t - z_t' z_t \right)}_{\text{bagian korelasi }\;\ell_t^{C}}

Bagian volatilitas tV\ell_t^V hanya bergantung pada parameter GARCH univariat (melalui DtD_t) — memaksimalkannya persis sama dengan mencocokkan dd model GARCH univariat yang independen, yang telah kita lakukan di Langkah 1. Bagian korelasi tC\ell_t^C bergantung pada aa dan bb (melalui RtR_t), dengan diberikan residual yang distandarisasi dari Langkah 1. Jadi di Langkah 2 kita hanya memaksimalkan

LC(a,b)=12t=1T(logRt+ztRt1zt)\mathcal{L}^C(a, b) = -\frac{1}{2}\sum_{t=1}^{T}\left( \log|R_t| + z_t' R_t^{-1} z_t \right)

(suku ztztz_t'z_t tidak bergantung pada a,ba, b, sehingga kita membuangnya). Ini adalah optimasi dua parameter tak peduli berapa banyak aset — itulah inti keseluruhannya. Ia disebut quasi-likelihood karena estimator dua langkah bersifat konsisten tetapi tidak sepenuhnya efisien; galat baku (standard error) memerlukan koreksi (Engle & Sheppard 2001), tetapi untuk pembangkitan sinyal yang penting adalah estimasi titiknya.

Untuk kripto, inovasi Gaussian meremehkan risiko ekor. Menukarnya dengan likelihood Student-t multivariat merupakan perubahan langsung (drop-in) pada t\ell_t (ganti kernel Gaussian dengan densitas tt-multivariat dan tambahkan sebuah parameter derajat kebebasan ν\nu). Kami mempertahankan quasi-likelihood Gaussian dalam estimator di bawah demi kejelasan dan menandai di mana ν\nu masuk — standarisasi dari Bagian 1-2 sudah menggunakan inovasi-t pada margin, yang menangkap sebagian besar manfaat ekor.

Implementasi Python

Sebuah fakta yang tumpul tetapi penting: library arch tidak melakukan GARCH multivariat atau DCC. arch adalah mesin univariat yang unggul (kita bersandar padanya persis untuk itu), tetapi tidak ada dcc_model di dalamnya. Opsi praktis Anda adalah:

  1. Buat DCC sendiri di atas arch — cocokkan model univariat dengan arch, ekstrak residual yang distandarisasi, implementasikan rekursi QQ dan quasi-likelihood korelasi dalam NumPy/SciPy, dan optimasi kedua skalar. Inilah yang kita lakukan di bawah. Panjangnya sekitar 60 baris dan sepenuhnya transparan.
  2. Paket mgarch di PyPI — sebuah implementasi DCC-GARCH pure-Python yang ringan. Praktis untuk pencocokan cepat, kurang fleksibel jika Anda menginginkan margin GJR atau inovasi-t yang tersambung secara presisi.
  3. rmgarch dari R (Alexios Galanos) — implementasi rujukan. dccspec / dccfit mendukung DCC, aDCC, GARCH-copula, Student-t, dan galat baku yang tepat. Jika Anda melakukan riset volatilitas multivariat yang serius, rmgarch (dipanggil dari Python via rpy2 jika terpaksa) adalah standar emas.

Kita membangun opsi 1 karena ia membuat setiap bagian yang bergerak menjadi eksplisit dan menggunakan kembali keterampilan univariat dari Bagian 1-2.

Langkah 1: Cocokkan 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())

Sebuah pemeriksaan kewarasan cepat pada residual yang distandarisasi itu penting. Jika ada kolom yang memiliki deviasi standar jauh dari 1, atau autokorelasi tersisa yang berat pada kuadratnya (Ljung-Box pada zi,t2z_{i,t}^2), berarti margin univariatnya salah spesifikasi (misspecified) dan langkah DCC akan mewarisi galat tersebut. Perbaiki dulu marginnya — itulah gunanya Bagian 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 sebuah book BTC/ETH/SOL/BNB atas beberapa tahun data harian menghasilkan keluaran dalam bentuk berikut (angka-angka di bawah bersifat ilustratif, bukan berasal dari eksperimen bertanggal tertentu — jalankan pada data Anda sendiri):

DCC estimates: a = 0.0287, b = 0.9401, a+b = 0.9688
log-likelihood: -3812.44

Cara membacanya:

  • a=0,029a = 0,029 kecil — matriks korelasi tidak melonjak karena guncangan satu hari. Setiap hari hanya menyentuh RtR_t ke arah outer product zt1zt1z_{t-1}z_{t-1}' sekitar ~3%.
  • b=0,940b = 0,940 besar — korelasi sangat persisten. Begitu book saling berpaut (couple up) dalam sebuah peristiwa stres, ia tetap berpaut untuk beberapa waktu, meluruh kembali menuju Qˉ\bar{Q} secara perlahan. Ini cocok dengan pengalaman nyata drawdown kripto: korelasi tidak langsung pulih (snap back) saat harga stabil.
  • a+b=0,969<1a + b = 0,969 < 1 mengonfirmasi mean reversion. Proses korelasi memiliki sebuah tingkat jangka panjang stasioner (Qˉ\bar{Q}) yang menjadi tujuan pulangnya, dengan half-life kira-kira log(0.5)/log(a+b)22\log(0.5)/\log(a+b) \approx 22 hari. Jika Anda pernah mengestimasi a+ba + b pada dasarnya sama dengan 1, proses korelasinya terintegrasi (integrated) — ia tidak memiliki jangkar jangka panjang, biasanya merupakan gejala dari sebuah structural break di dalam sampel Anda yang diserap model sebagai persistensi tak hingga.

Persistensi mendekati satuan dan pembebanan guncangan yang mungil adalah sidik jari (fingerprint) kanonik DCC di seluruh kelas aset, dan kripto tidak terkecuali. Inilah pula mengapa korelasi bergulir 30 hari merupakan pengganti yang begitu buruk: sebuah jendela bergulir secara implisit mengasumsikan aa dan bb yang sama sekali tidak cocok dengan struktur peluruhan ini.

Beberapa catatan implementasi yang menghemat banyak waktu debugging nyata:

  • Inisialisasi. Memulai pada [0.03, 0.94] mencerminkan estimasi kripto yang tipikal: aa kecil (korelasi bereaksi terhadap guncangan tetapi tidak dengan keras), bb besar (korelasi persisten). Jika optimizer Anda mengembara ke a+b1a+b \to 1 maka proses korelasinya terintegrasi — biasanya sebuah tanda structural break dalam sampel (sebuah perubahan rezim yang berusaha keras dicocokkan model sebagai persistensi).
  • Konvensi waktu (timing). Di dalam loop kita menilai (score) RtR_t terhadap ztz_t dan lalu memperbarui QQ dengan ztztz_t z_t' untuk langkah berikutnya. Ini menjaga RtR_t sebagai fungsi dari informasi hingga t1t-1 saja — tanpa look-ahead. Salah menangani off-by-one ini adalah bug DCC yang paling umum, dan ia secara diam-diam menggelembungkan kecocokan in-sample.
  • Correlation targeting. Kita memasukkan Qˉ\bar{Q} sebagai korelasi sampel alih-alih mengestimasinya. Inilah yang membuat optimasinya menjadi dua dimensi. Biayanya adalah Qˉ\bar{Q} menggunakan seluruh sampel, sehingga dalam walk-forward yang ketat Anda harus mengestimasinya ulang hanya pada jendela pelatihan (lihat di bawah).

Langkah 3: Rekonstruksi jalur korelasi dan kovariansi

Begitu a,ba, b tetap, jalankan rekursi sekali lagi, kali ini menyimpan seluruh jalur RtR_t (dan HtH_t) sehingga strategi hilir dapat 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))

Deret rho_btc_eth adalah hasil (payoff) dari keseluruhan latihan ini: alih-alih satu angka, Anda kini memiliki sebuah korelasi harian yang dapat Anda plot, ambil ambang batasnya (threshold), atau umpankan ke sebuah strategi. Pada data kripto nyata Anda biasanya akan melihatnya berkisar dari kira-kira 0,5 pada masa-masa tenang hingga di atas 0,9 selama stres — persis rentang yang dirata-ratakan hilang oleh sebuah korelasi sampel tunggal.

Prakiraan satu langkah ke depan

Untuk perdagangan langsung (live) Anda membutuhkan Ht+1H_{t+1} periode berikutnya dari informasi yang tersedia sekarang. Sisi volatilitas berasal dari prakiraan satu langkah tiap model arch; sisi korelasi adalah satu putaran rekursi lagi:

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 bahwa segalanya berada dalam satuan yang diskalakan (×100) karena kita mencocokkan arch pada series * 100. Bagi volatilitas dengan 100 (dan kovariansi dengan 1002=10,000100^2 = 10{,}000) untuk kembali ke satuan imbal hasil mentah sebelum mengumpankan ke sebuah strategi. Menjaga penskalaan tetap benar itu membosankan tetapi merupakan sumber bug diam-diam yang sering.

Aplikasi 1: Sebuah Hedge Ratio Dinamis untuk Pairs Trading

Pair market-neutral klasik — long satu aset, short sejumlah aset lain yang dibobot beta — hidup atau mati bergantung pada hedge ratio β\beta. Estimasikan ia dengan OLS statis atas sebuah jendela pelatihan dan Anda mewarisi persis masalah korelasi usang yang menjadi bahasan keseluruhan artikel ini: hedge yang menetralkan paparan pasar kuartal lalu keliru pada kuartal ini.

DCC memberi Anda hedge ratio sebagai sebuah deret waktu. Hedge variansi-minimum dari paparan ETH menggunakan BTC adalah koefisien regresi kondisional

βt=Covt(rETH,rBTC)Vart(rBTC)=hETH,BTC,tσBTC,t2=ρETH,BTC,tσETH,tσBTC,t\beta_t = \frac{\mathrm{Cov}_t(r_{\text{ETH}}, r_{\text{BTC}})}{\mathrm{Var}_t(r_{\text{BTC}})} = \frac{h_{\text{ETH,BTC},t}}{\sigma_{\text{BTC},t}^2} = \rho_{\text{ETH,BTC},t}\,\frac{\sigma_{\text{ETH},t}}{\sigma_{\text{BTC},t}}

Setiap suku di ruas kanan adalah keluaran DCC. Hedge ratio bergerak karena dua alasan yang berbeda, dan DCC memisahkannya dengan bersih: korelasi ρt\rho_t berubah (aset saling berpaut atau melepas), dan rasio volatilitas σETH,t/σBTC,t\sigma_{\text{ETH},t}/\sigma_{\text{BTC},t} berubah (satu aset menjadi relatif lebih volatil). Beta rolling-OLS mengaburkan kedua efek itu bersamaan dengan lag; DCC mengatribusikannya.

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()

Umpankan spread ke mesin pairs apa pun yang Anda jalankan. Hedge dinamis dengan sendirinya tidak menciptakan sebuah edge — ia membuat spread yang Anda perdagangkan benar-benar market-neutral sepanjang waktu, sehingga sinyal mean-reversion Anda tidak terkontaminasi oleh paparan direksional yang menyimpang (drifting). Jika Anda membangun strategi pairs, ini langsung terpasang ke dalam kerangka kerja di Statistical Arbitrage & Pairs Trading in Crypto dan pendekatan jarak untuk pairs, menggantikan hedge ratio tetap mereka. Deret korelasi itu sendiri juga merupakan masukan yang lebih bersih untuk sebuah sinyal pair berbasis korelasi ketimbang jendela bergulir apa pun — Anda memperoleh ρt\rho_t yang mulus dan konsisten-model alih-alih sebuah estimasi berjendela yang berisik.

Dua peringatan yang spesifik untuk menggunakan βt\beta_t secara langsung. Pertama, beri lag padanya — perdagangkan berdasarkan βt1\beta_{t-1}, jangan pernah βt\beta_t sekontemporer, atau Anda mengintip (peeking). Kedua, sebuah hedge ratio yang berputar liar setiap hari menghasilkan turnover dan biaya; di pasar kripto 24/7 dengan biaya funding pada kaki short, sebuah hedge yang terlalu reaktif dapat menguras lebih banyak ketimbang penyimpangan yang dikoreksinya. Haluskan βt\beta_t (sebuah EWMA, atau seimbangkan ulang hedge hanya ketika ia bergerak melewati sebuah band) dan tentukan ukuran keseluruhannya secara wajar — penentuan ukuran posisi dari sebuah sinyal yang berisik adalah disiplin tersendiri, dibahas di penentuan ukuran dengan kriteria Kelly.

Aplikasi 2: Variansi Portofolio yang Berubah Seiring Waktu

Untuk sebuah portofolio dengan vektor bobot ww, variansi kondisionalnya adalah

σp,t2=wHtw=ijwiwjρij,tσi,tσj,t\sigma_{p,t}^2 = w'\, H_t\, w = \sum_{i}\sum_{j} w_i w_j\, \rho_{ij,t}\,\sigma_{i,t}\,\sigma_{j,t}

Dengan matriks kovariansi statis — default Markowitz — angka ini adalah sebuah konstanta yang Anda hitung sekali dan Anda anggap masih benar. Padahal tidak. Risiko portofolio bernapas bersama pasar, dan ia bernapas paling keras persis ketika korelasi melonjak, karena dalam sebuah drawdown baik suku σi,t\sigma_{i,t} maupun suku ρij,t\rho_{ij,t} naik bersamaan dan saling mengalikan. Sebuah portofolio yang tampak seperti vol tahunan 40% di pasar yang tenang bisa berjalan pada 80%+ dalam sepekan penuh stres, dan sebuah matriks kovariansi statis akan memberitahu Anda bahwa tidak ada 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())

σp,t\sigma_{p,t} yang berubah seiring waktu ini adalah masukan jujur yang dibutuhkan oleh alokasi berbasis risiko. Optimasi mean-variance (Markowitz untuk kripto) dengan kovariansi sampel yang statis berarti mengoptimasi terhadap sebuah fiksi; mengumpankannya HtH_t (atau prakiraannya berhorizon pendek) membuat efficient frontier itu sendiri berubah seiring waktu dan memaksa optimizer untuk menurunkan risiko (de-risk) memasuki rezim-rezim korelasi yang naik alih-alih sesudahnya. Pendekatan risk-parity dan hierarkis — pipeline HRP + CVaR — bahkan lebih sensitif terhadap masukan kovariansi, karena keseluruhan alokasinya adalah sebuah fungsi dari matriks risiko. Dan jika Anda membandingkan para allocator secara langsung, seperti di perbandingan algoritma optimasi portofolio, apakah mereka mengonsumsi kovariansi statis atau dinamis sering kali merupakan pendorong risiko terealisasi yang lebih besar ketimbang pilihan algoritmanya.

Aplikasi langsungnya adalah volatility targeting untuk keseluruhan portofolio: pilih sebuah vol tahunan target σ\sigma^{*}, dan skalakan paparan bruto (gross) dengan σ/σp,t\sigma^{*} / \sigma_{p,t} setiap periode sehingga risiko terealisasi tetap kira-kira konstan alih-alih menggelembung dalam krisis. Itu menutup lingkaran dengan Bagian 4, yang membangun dan melakukan backtest persis atas aturan ini.

Aplikasi 3: Korelasi sebagai Sinyal Rezim

Di luar hedging dan penentuan ukuran, matriks korelasi membawa sebuah sinyal makro. Skalar tunggal paling berguna yang dapat Anda ekstrak adalah korelasi berpasangan rata-rata:

ρˉt=2d(d1)i<jρij,t\bar{\rho}_t = \frac{2}{d(d-1)}\sum_{i < j} \rho_{ij,t}

Ketika ρˉt\bar{\rho}_t naik di seluruh book, pasar sedang memasuki sebuah rezim risk-off — kisah-kisah idiosinkratik berhenti berarti dan segalanya diperdagangkan sebagai satu beta makro. Ini adalah sidik jari kuantitatif dari "korelasi menuju 1 dalam krisis." Ia cenderung mendahului atau berbarengan dengan drawdown, yang menjadikannya sebuah indikator rezim yang dapat dipakai alih-alih sebuah postmortem yang tertinggal.

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 dapat menggunakan risk_off sebagai sebuah throttle mandiri (potong paparan bruto, lebarkan stop, hentikan strategi mean-reversion yang tergilas ketika segalanya bergerak seiring tren bersama) atau sebagai sebuah fitur dalam sebuah model rezim yang lebih formal. Ia berpadu secara alami dengan pendekatan hidden-Markov di deteksi rezim dengan HMM: korelasi DCC rata-rata adalah salah satu variabel observasi yang lebih informatif yang dapat Anda serahkan ke sebuah HMM, karena ia bersifat forward-looking mengenai stres sistemik dengan cara yang tidak dimiliki imbal hasil masa lalu. Peringatan jujurnya: korelasi yang naik memberitahu Anda bahwa diversifikasi sedang gagal, bukan ke arah mana pasar akan bergerak. Ia adalah sebuah sinyal risiko, bukan sinyal alfa, dan seharusnya ditentukan ukurannya demikian — lihat asimetri kerugian dan keuntungan untuk memahami mengapa memperlakukan sebuah rezim risiko sebagai taruhan direksional berakhir buruk.

Pertimbangan Praktis

Stabilitas estimasi dan jumlah aset

DCC berskala jauh lebih baik ketimbang BEKK, tetapi "berskala" tidaklah sama dengan "gratis." Matriks correlation-targeting Qˉ\bar{Q} adalah sebuah korelasi sampel d×dd \times d, dan matriks korelasi sampel menjadi ill-conditioned saat dd mendekati jumlah observasi. Dengan 4 aset dan 1000 hari Anda baik-baik saja. Dengan 60 aset dan 400 hari, Qˉ\bar{Q} nyaris singular, invers-nya dalam likelihood meledak, dan RtR_t dapat mengembara menjadi non-PD akibat derau numerik. Mitigasi, kira-kira dalam urutan seberapa sering Anda akan membutuhkannya:

  • Susutkan (shrink) Qˉ\bar{Q} menuju sebuah target terstruktur (Ledoit-Wolf, atau menuju identitas / sebuah matriks korelasi konstan) sebelum menjalankan rekursi. Ini adalah perbaikan bertuas paling tinggi untuk book besar.
  • Kelompokkan aset ke dalam segelintir sektor (majors, L1, DeFi, memes), modelkan di dalam dan lintas pada tingkat sektor, atau jalankan DCC pada faktor komponen utama (principal-component) alih-alih aset mentah.
  • Utamakan lebih banyak data ketimbang lebih banyak aset. DCC memiliki selera tak terpuaskan akan sejarah yang panjang, bersih, dan sekontemporer — yang persis merupakan hal yang tidak dimiliki token-token muda.

Secara realistis, batasi DCC langsung hingga paling banyak beberapa lusin aset. Untuk semesta yang besar, DCC pada imbal hasil faktor ditambah residual idiosinkratik adalah workaround standarnya.

Correlation targeting adalah jalan pintas dengan biaya

Menargetkan Qˉ\bar{Q} membuat estimasi menjadi tractable tetapi memanggang korelasi tak-bersyarat seluruh-sampel ke dalam setiap RtR_t. Dalam sebuah backtest yang ketat ini merupakan sebuah kebocoran look-ahead: matriks korelasi hari-tt Anda "mengetahui" korelasi rata-rata seluruh sampel, termasuk masa depan. Untuk evaluasi yang jujur Anda harus mengestimasi ulang Qˉ\bar{Q} hanya pada jendela pelatihan dan menahannya tetap di luar-sampel, atau menggulirkannya ke depan. Ini adalah disiplin yang sama yang ditegakkan oleh keseluruhan kerangka kerja walk-forward optimization, dan ia mudah dilanggar secara tak sengaja dengan sebuah np.cov(Z) yang praktis atas seluruh array — seperti yang dilakukan kode pengajaran kita di atas. Perbaiki dulu sebelum Anda memercayai satu angka P&L pun.

Irama pencocokan ulang (refit) dan disiplin look-ahead

Anda tidak perlu mengoptimasi ulang a,ba, b setiap hari — keduanya parameter yang stabil. Sebuah irama produksi yang masuk akal:

  • Estimasi ulang a,ba, b dan parameter GARCH univariat secara mingguan atau bulanan.
  • Jalankan filter (perbarui QtQ_t, σi,t\sigma_{i,t}) setiap periode dengan parameter yang dibekukan untuk memperoleh RtR_t dan HtH_t yang segar. Filtering itu murah; fitting tidak.
  • Selalu prakirakan, jangan pernah menghaluskan (smooth). Gunakan RtR_t yang dibangun dari informasi hingga t1t-1 untuk berdagang pada tt. Struktur dua-lintasan (fit pada sebuah jendela, lalu filter ke depan) itulah yang menjaga Anda tetap jujur.

Kesenjangan antara backtest DCC dan performa langsung hampir selalu merupakan sebuah kebocoran look-ahead — Qˉ\bar{Q} seluruh-sampel, βt\beta_t sekontemporer, atau pencocokan ulang pada data yang mencakup perdagangan yang sedang Anda evaluasi. Disiplin mencocokkan backtest dengan kondisi langsung adalah topik tersendiri di paritas backtest-langsung, dan DCC adalah sebuah model yang menghukum kecerobohan di sini lebih dari kebanyakan model lain. Jika, setelah evaluasi walk-forward yang bersih, korelasi dinamis tidak menambahkan apa pun di atas sebuah estimasi bergulir sederhana untuk strategi Anda, itu adalah sebuah hasil negatif yang nyata dan layak dipublikasikan — pola pikir di hasil negatif yang jujur berlaku secara langsung.

DCC Asimetris (aDCC)

Sama seperti efek leverage univariat (Bagian 2) berarti kabar buruk menaikkan volatilitas lebih besar ketimbang kabar baik, korelasi naik lebih besar setelah guncangan negatif bersama ketimbang setelah guncangan positif bersama. Cappiello, Engle & Sheppard (2006) menangkap ini dengan DCC asimetris, menambahkan sebuah suku yang digerakkan oleh outer product dari residual yang distandarisasi bagian-negatif zt=min(zt,0)z_t^- = \min(z_t, 0):

Qt=(QˉaQˉbQˉgNˉ)+azt1zt1+gzt1zt1+bQt1Q_t = (\bar{Q} - a\bar{Q} - b\bar{Q} - g\bar{N}) + a\, z_{t-1} z_{t-1}' + g\, z_{t-1}^- z_{t-1}^{-\prime} + b\, Q_{t-1}

di mana Nˉ=1Ttztzt\bar{N} = \frac{1}{T}\sum_t z_t^- z_t^{-\prime} dan g0g \ge 0 mengukur tendangan korelasi ekstra dari pergerakan turun (downside) bersama. Untuk kripto, di mana korelasi-kehancuran (crash-correlation) adalah risiko dominan, suku asimetri biasanya signifikan dan sepadan dengan satu parameter tambahan itu. rmgarch mencocokkan aDCC di luar kotak (model="aDCC"); menambahkan suku ztz_t^- ke estimator NumPy kita adalah sebuah latihan yang lugas.

Perbandingan: DCC Melawan Alternatif-Alternatifnya

Di mana posisi DCC di antara cara-cara Anda mungkin memperoleh sebuah matriks kovariansi untuk sebuah book kripto? Ringkasan jujurnya:

Pendekatan Parameter Berskala hingga ρ\rho berubah seiring waktu? PD terjamin? Ketergantungan ekor?
Kovariansi sampel / bergulir 0 (panjang jendela) dd berapa pun secara kasar (lag, berisik) tidak (perlu ditambal) tidak
EWMA (RiskMetrics) 1 (λ\lambda) dd berapa pun ya (peluruhan tunggal) ya tidak
CCC-GARCH dd margin + Qˉ\bar{Q} lusinan tidak (RR konstan) ya tidak
DCC-GARCH dd margin + 2 lusinan ya ya tidak
aDCC-GARCH dd margin + 3 lusinan ya, asimetris ya parsial
BEKK O(d2)O(d^2) 4\le 4 ya (kaya) ya tidak
VECH O(d4)O(d^4) 3\le 3 ya (paling kaya) menyakitkan tidak
GARCH-copula dd margin + copula lusinan (vines) copula statis ya ya

Beberapa pembacaan atas tabel ini:

  • EWMA adalah baseline murah yang seharusnya dikalahkan setiap orang sebelum mengklaim DCC membantu. Ia adalah kasus khusus satu-parameter dalam semangatnya — sebuah peluruhan eksponensial tunggal yang diterapkan langsung pada kovariansi — dan untuk banyak book ia mengejutkan sulit untuk diperbaiki di luar-sampel. Jika DCC tidak mengalahkan EWMA dalam walk-forward yang bersih, gunakan EWMA.
  • CCC vs DCC adalah inti keseluruhan artikel ini: faktorisasi yang sama, tetapi CCC membekukan RR dan DCC membiarkannya bergerak. Kedua parameter tambahan (a,ba, b) adalah keseluruhan perbedaannya, dan dalam kripto keduanya sepadan dengan bayarannya.
  • BEKK/VECH membeli dinamika yang lebih kaya — setiap kovariansi dapat merespons setiap guncangan masa lalu — tetapi biaya parameternya membatasinya pada book yang mungil. Untuk apa pun melewati 4 aset keduanya bukan opsi nyata.
  • GARCH-copula adalah satu-satunya baris dengan "ya" di bawah ketergantungan ekor. Itulah kembali sifat saling melengkapinya: DCC memodelkan pusat dinamis dari distribusi bersama, copula memodelkan ekor statisnya. Jika pertanyaan risiko Anda adalah "apa yang terjadi ketika segalanya hancur sekaligus," raihlah pipeline copula; jika ia adalah "berapa hedge ratio / variansi portofolio saya sekarang," raihlah DCC.

Default praktis untuk sebuah meja kripto sistematis: DCC (atau aDCC) untuk hedge ratio dan kovariansi dinamis di badan, sebuah overlay copula untuk risiko-ekor dan CVaR, dan EWMA sebagai baseline pemeriksa-kewarasan yang menjaga Anda tetap jujur mengenai apakah mesin tambahan itu membayar dirinya sendiri.

Batasan

  • Dinamika skalar. Satu aa dan satu bb untuk semua pasangan adalah pembatasan yang kuat. BTC-ETH dan dua altcoin yang tak dikenal berbagi kecepatan penyesuaian yang sama. Generalized DCC melonggarkan ini tetapi memperkenalkan kembali ledakan parameter yang justru dirancang untuk dihindari oleh DCC.
  • Kehilangan efisiensi dua-langkah. Estimator quasi-likelihood bersifat konsisten tetapi tidak sepenuhnya efisien, dan galat baku yang naif keliru. Gunakan koreksi Engle-Sheppard jika Anda peduli mengenai inferensi; untuk pembangkitan sinyal, estimasi titik sudah cukup.
  • Ekor Gaussian secara default. Quasi-likelihood Gaussian polos meremehkan risiko ekor bersama. Inovasi Student-t membantu; untuk ketergantungan ekor yang sesungguhnya (probabilitas pergerakan ekstrem yang simultan), DCC adalah alat yang keliru dan sebuah model copula adalah yang benar. DCC memberi Anda badan dinamis dari korelasi; copula memberi Anda ekor statis. Meja yang serius menggunakan keduanya.
  • Korelasi bukanlah kausasi, dan bukan arah. ρˉt\bar{\rho}_t yang naik memperingatkan bahwa diversifikasi sedang gagal; ia tidak mengatakan apa pun mengenai arah pasar. Jangan membebani sebuah sinyal risiko dengan ekspektasi direksional.
  • Kelaparan data. Segala hal di atas mengasumsikan sejarah yang panjang, bersih, dan tersinkronisasi. Token kripto yang paling baru dan paling menarik melanggar ketiganya.

Ringkasan

  • Korelasi statis adalah kebohongan di kripto. Korelasi mengelompok, persisten, dan melonjak ke arah 1 dalam drawdown — persis ketika diversifikasi seharusnya membantu. Sebuah korelasi sampel tunggal ρ^\hat{\rho} merata-ratakan sebuah proses yang berpindah rezim menjadi sebuah nilai tengah yang tak bermakna.
  • GARCH multivariat penuh (VECH, BEKK) tidak berskala. Jumlah parameter tumbuh sebagai O(d2)O(d^2); keduanya dalam praktik terbatas pada segelintir aset.
  • DCC (Engle 2002) memfaktorkan masalah: Ht=DtRtDtH_t = D_t R_t D_t, dengan DtD_t dari pencocokan GARCH univariat independen (gunakan kembali Bagian 1-2) dan RtR_t dari sebuah rekursi dua-parameter. Ia berskala hingga lusinan aset karena hanya a,ba, b yang dioptimasi.
  • Rekursi Qt=(1ab)Qˉ+azt1zt1+bQt1Q_t = (1-a-b)\bar{Q} + a\,z_{t-1}z_{t-1}' + b\,Q_{t-1}, dinormalisasi menjadi RtR_t, menghasilkan sebuah matriks korelasi positive-definite yang valid pada setiap langkah, dengan a,b>0a,b>0, a+b<1a+b<1.
  • arch tidak melakukan DCC. Cocokkan margin dengan arch, lalu implementasikan estimator NumPy/SciPy ~60 baris di sini, atau gunakan mgarch (Python) atau rmgarch (R, rujukan).
  • Tiga hasil konkret: sebuah hedge ratio dinamis βt=ρtσETH,t/σBTC,t\beta_t = \rho_t\,\sigma_{\text{ETH},t}/\sigma_{\text{BTC},t} untuk pairs trading; sebuah variansi portofolio yang jujur dan berubah seiring waktu wHtww'H_t w untuk alokasi berbasis risiko; dan korelasi berpasangan rata-rata sebagai sebuah sinyal rezim risk-off.
  • Disiplin adalah segalanya. Correlation targeting membocorkan rata-rata seluruh-sampel, jadi estimasi ulang Qˉ\bar{Q} hanya pada data pelatihan; beri lag pada setiap hedge ratio; filter ke depan, jangan pernah menghaluskan. Evaluasi walk-forward tidak dapat ditawar.
  • aDCC menambahkan sebuah suku asimetri downside dan biasanya sepadan di kripto, di mana korelasi-kehancuran mendominasi.
  • Bagian 4 menggunakan prakiraan-prakiraan ini untuk membangun dan melakukan backtest atas sebuah strategi yang menargetkan volatilitas.

Referensi:

  • 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.
Penafian: Informasi yang disediakan dalam artikel ini hanya untuk tujuan edukasi dan informasi serta tidak merupakan nasihat keuangan, investasi, atau trading. Trading mata uang kripto mengandung risiko kerugian yang signifikan.

MarketMaker.cc Team

Riset & Strategi Kuantitatif

Diskusikan di Telegram
Newsletter

Selangkah Lebih Maju dari Pasar

Berlangganan newsletter kami untuk wawasan AI trading eksklusif, analisis pasar, dan pembaruan platform.

Kami menghormati privasi Anda. Berhenti berlangganan kapan saja.