GARCH(1,1): Memprediksi Volatilitas Crypto
Buka grafik return harian BTC dan Anda akan melihat sesuatu yang tidak pernah dipersiapkan oleh buku teks tentang random walk: ketenangan dan kekacauan datang secara berkelompok. Hari turun 6% jarang sendirian. Ia berada di tengah minggu dengan swing 4-8%, lalu pasar menghela napas dan melewati sebulan sesi 1% yang tenang sebelum badai berikutnya datang. Return itu sendiri terlihat hampir tidak dapat diprediksi — Anda tidak bisa dengan yakin mengatakan apakah besok naik atau turun — tetapi besarannya sangat dapat diprediksi. Turbulensi hari ini memberi tahu banyak hal tentang besok.
Hampir setiap alat manajemen risiko yang digunakan trader diam-diam mengasumsikan hal ini tidak benar. Black-Scholes memberi harga opsi dengan satu konstan. Angka Value-at-Risk statis mengalikan satu estimasi volatilitas dengan kuantil normal. Stop-loss tetap 3% memperlakukan hari Selasa yang datar dan jam-jam di sekitar rilis FOMC atau de-peg bursa besar seolah membawa risiko yang sama. Masing-masing gagal dengan cara yang persis sama: mereka meruntuhkan besaran yang berubah seiring waktu menjadi konstanta, lalu terkejut ketika konstanta itu ternyata bergerak.
Artikel ini adalah Bagian 1 dari seri empat bagian tentang pemodelan volatilitas untuk crypto. Artikel ini membangun fondasinya: model GARCH(1,1), mengapa model ini cocok dengan return crypto, cara mengestimasinya secara jujur dengan maximum likelihood menggunakan library arch, dan cara mengubah prakiraan conditional variance menjadi dua hal yang langsung berguna — ukuran posisi dan lebar stop yang keduanya menyesuaikan dengan pasar. Bagian 2 menambahkan asimetri dan ekor tebal (heavy tails), Bagian 3 masuk ke ranah multivariat, dan Bagian 4 merangkai backtest volatility-targeting secara lengkap. Kami sengaja membuat aplikasi di sini tetap sederhana; strategi yang divalidasi secara walk-forward secara jujur adalah topik Bagian 4.
Fakta-Fakta Terpola dari Return Crypto
Sebelum memodelkan apa pun, penting untuk tepat mengenai apa yang ingin kita reproduksi. Return finansial empiris — saham, forex, dan terutama crypto — memiliki sejumlah kecil keteraturan statistik yang kuat dan telah didokumentasikan selama puluhan tahun. Ini biasa disebut stylized facts, dan tiga di antaranya mendorong semua yang berikut.
1. Volatility clustering. Pergerakan besar cenderung diikuti oleh pergerakan besar lainnya (dengan tanda apa pun), dan pergerakan kecil oleh pergerakan kecil. Mandelbrot melihat ini pada harga kapas pada tahun 1963. Secara formal, meskipun return hampir tidak berkorelasi secara serial, return yang dikuadratkan (proksi untuk realized variance) menunjukkan autokorelasi positif yang kuat dan meluruh secara perlahan.
2. Ekor tebal (leptokurtosis). Distribusi tak bersyarat dari return memiliki jauh lebih banyak massa di area ekstrem dibanding distribusi Gaussian. Jika distribusi normal memiliki kurtosis 3, log-return harian BTC secara rutin berada di atas 8-10, dan return crypto berfrekuensi lebih tinggi bisa lebih buruk lagi. Hari six-sigma, yang menurut model normal seharusnya terjadi kira-kira sekali dalam sejuta tahun, muncul beberapa kali dalam satu dekade.
3. Tidak ada autokorelasi linear pada return, tetapi autokorelasi kuat pada return kuadrat. Ini adalah sidik jari yang membedakan proses volatilitas sejati dari tren yang trivial. Jika Anda meregresikan terhadap lag-nya sendiri, Anda tidak mendapatkan apa-apa yang bisa dieksploitasi. Jika Anda meregresikan terhadap lag-nya, Anda menemukan sinyal yang jelas dan persisten. Inilah struktur yang seharusnya ditangkap oleh model variance — dan persis apa yang dibuang oleh model dengan konstan.
Kita bisa melihat ketiganya secara sekilas hanya dengan beberapa baris kode. Tidak ada yang memerlukan sumber data khusus; gunakan ccxt untuk produksi, tapi untuk cuplikan yang dapat direproduksi yfinance sudah cukup.
import numpy as np
import pandas as pd
import yfinance as yf
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.stats.diagnostic import acorr_ljungbox
from scipy import stats
px = yf.download("BTC-USD", start="2021-01-01", end="2025-12-31")["Close"]
ret = np.log(px / px.shift(1)).dropna() # log returns
ret = ret.rename("btc")
print(f"Observations: {len(ret)}")
print(f"Ann. volatility: {ret.std() * np.sqrt(365):.2%}")
print(f"Skewness: {stats.skew(ret):.2f}")
print(f"Excess kurtosis: {stats.kurtosis(ret):.2f}") # 0 == Gaussian
lb_ret = acorr_ljungbox(ret, lags=[10], return_df=True)
lb_ret2 = acorr_ljungbox(ret ** 2, lags=[10], return_df=True)
print("\nLjung-Box p-value, returns (lag 10):", float(lb_ret["lb_pvalue"].iloc[0]))
print("Ljung-Box p-value, squared (lag 10):", float(lb_ret2["lb_pvalue"].iloc[0]))
Pembacaan tipikal (ilustratif — jendela waktu Anda akan berbeda): excess kurtosis jauh di atas 3, p-value Ljung-Box pada return mentah yang gagal menolak "tidak ada autokorelasi," dan p-value pada return kuadrat yang praktis nol. Kontras terakhir itulah inti permainannya. Tidak ada yang bisa diperdagangkan dari tanda return pada horizon harian, tetapi ada banyak sekali struktur pada variance-nya, dan struktur itu dapat diprediksi.
Catatan tentang sifat 24/7 dari crypto. Berbeda dengan saham, tidak ada gap semalam dan tidak ada penutupan akhir pekan, sehingga "hari" adalah bar 24 jam yang bersih dan faktor annualisasinya adalah , bukan . Volatility clustering juga bertahan pada skala intraday, yang penting jika Anda menjalankan GARCH pada bar per jam — pergantian funding rate dan cascade likuidasi menyuntikkan ledakan variance yang tajam dan berkelompok, yang diratakan oleh model harian.
Dari ARCH ke GARCH
Masalahnya sekarang telah dirumuskan dengan tajam: memodelkan variance yang tidak konstan tetapi bergantung pada masa lalu yang baru saja terjadi. Model pertama yang melakukan ini dengan benar adalah ARCH milik Engle (Autoregressive Conditional Heteroskedasticity, 1982), yang membawanya memenangkan Hadiah Nobel pada tahun 2003.
Tuliskan return sebagai conditional mean ditambah shock:
Di sini adalah variance bersyarat (conditional) — variance dari dengan diketahuinya semua informasi hingga waktu — dan adalah inovasi standar (normal standar pada kasus paling sederhana). Kata "bersyarat" melakukan seluruh pekerjaan di sini: secara tak bersyarat variance-nya mungkin konstan, tetapi dengan syarat kemarin, ia bergerak.
ARCH() milik Engle membuat variance hari ini sebagai jumlah tertimbang dari shock kuadrat terakhir:
dengan dan untuk menjaga variance tetap positif. Ini menangkap clustering secara langsung: shock besar mendorong naik , yang meningkatkan peluang shock besar lainnya, yang membuat variance tetap tinggi. Masalahnya adalah peluruhan empiris. Persistensi volatilitas di pasar riil membentang sepanjang banyak lag, sehingga untuk mencocokkannya model ARCH memerlukan yang besar — sering kali 8, 10, atau lebih — dan itu berarti mengestimasi vektor yang panjang dan tidak stabil, yang cenderung overfit.
Wawasan Bollerslev pada tahun 1986 adalah menambahkan istilah yang menyerap seluruh persistensi itu dengan satu parameter saja. Rekursi GARCH(1,1) — Generalized ARCH — adalah:
Tiga parameter, tiga interpretasi yang jelas:
- — baseline atau lantai. Konstanta yang menjadi jangkar tingkat variance jangka panjang. Variance tidak pernah meluruh di bawah apa yang didukung oleh .
- — reaksi terhadap berita. Seberapa keras variance merespons kejutan kemarin. yang besar berarti conditional variance mudah melonjak dan sensitif terhadap shock.
- — persistensi atau memori. Seberapa banyak variance kemarin terbawa ke hari ini. yang besar berarti volatilitas halus dan lambat memudar — masa tenang tetap tenang, badai tetap badai.
Keeleganan model ini terletak pada rekursinya. Karena itu sendiri mengandung istilah , ekspansi ke belakang menunjukkan bahwa GARCH(1,1) adalah ARCH() dengan bobot yang meluruh secara geometris pada shock kuadrat masa lalu:
Jadi satu saja memberi Anda memori tak terhingga dan berbobot eksponensial dari shock masa lalu. Inilah mengapa GARCH(1,1) yang hanya memiliki tiga parameter secara rutin mengalahkan model ARCH dengan sepuluh parameter, dan mengapa model ini menjadi kuda beban dalam pemodelan volatilitas terapan. Model ini sebenarnya adalah kerabat dekat dari estimator variance RiskMetrics EWMA, yang merupakan kasus khusus , dengan tetap pada 0.94. GARCH menggeneralisasinya dengan membiarkan data memilih , , dan tingkat mean-reversion yang sesungguhnya.
Sifat-Sifat: Stasioneritas, Variance Jangka Panjang, dan Half-Life
Rekursi GARCH(1,1) memiliki beberapa sifat yang layak diturunkan, karena inilah yang memungkinkan Anda menalar tentang model, bukan sekadar melakukan fitting secara membabi buta.
Variance tak bersyarat (jangka panjang). Asumsikan proses tersebut kovarian-stasioner sehingga variance tak bersyarat ada dan konstan sepanjang waktu. Ambil ekspektasi dari kedua sisi rekursi. Karena :
Inilah tingkat yang menjadi tujuan mean-reversion volatilitas. Nilai ini hanya ada — dan hanya positif — ketika .
Kondisi stasioneritas. Ketidaksamaan yang sama,
adalah kondisi stasioneritas kovarian untuk GARCH(1,1). Besaran adalah persistensi dari proses variance: ini adalah koefisien AR(1) yang mengatur seberapa cepat shock variance meluruh kembali menuju . Jika , variance tak bersyarat menjadi tak terhingga (atau tidak terdefinisi) dan shock tidak pernah benar-benar hilang.
Kita bisa melihat mean-reversion secara eksplisit. Definisikan deviasi variance . Sedikit aljabar pada rekursi (dengan mensubstitusikan ) menghasilkan, secara ekspektasi:
Jarak antara variance saat ini dan tingkat jangka panjangnya menyusut dengan faktor pada setiap langkah. Inilah tepatnya prakiraan multi-langkah yang kita gunakan nanti.
Half-life volatilitas. Berapa lama waktu yang dibutuhkan agar shock variance meluruh setengah kembali ke normal? Tetapkan dan selesaikan:
Untuk , half-life-nya sekitar 13.5 hari; untuk sekitar 34 hari; untuk sekitar 69 hari. Angka tunggal ini seringkali lebih intuitif daripada parameter mentahnya — ia memberi tahu Anda, dalam satuan bar Anda, seberapa lengket volatilitas itu.
Masalah near-IGARCH pada crypto. Inilah keunikan spesifik crypto. Ketika Anda melakukan fitting GARCH(1,1) pada return BTC atau ETH, Anda hampir selalu menemukan sangat mendekati 1 — nilai 0.98, 0.99, kadang 0.995 adalah hal yang rutin. Ini adalah rezim near-IGARCH (Integrated GARCH). Ini memiliki konsekuensi nyata:
- Half-life menjadi sangat besar (minggu hingga bulan), sehingga model memperlakukan volatilitas sebagai sesuatu yang sangat persisten dan nyaris tidak mean-reverting.
- Estimasi menjadi sangat sensitif: perubahan kecil pada dari 0.99 ke 0.995 menggandakan implied long-run variance. Jangan pernah percaya begitu saja pada estimasi titik long-run vol dalam rezim ini tanpa confidence interval.
- Prakiraan multi-langkah mean-revert begitu lambat sehingga, untuk horizon praktis di bawah beberapa minggu, GARCH berperilaku hampir seperti random-walk-in-variance (yang merupakan asumsi EWMA).
Apakah integrasi mendekati sempurna ini genuine atau artefak dari structural break (pergeseran permanen pada tingkat volatilitas yang dibaca oleh model sebagai satu episode persisten panjang) adalah perdebatan yang nyata. Ini adalah satu alasan lagi untuk melakukan refit pada rolling window daripada fitting sekali untuk seluruh riwayat, sebuah poin yang kita kembali bahas di bagian jebakan. Struktur rezim secara spesifik lebih baik ditangani oleh model switching eksplisit — lihat deteksi rezim dengan hidden Markov models, yang bersifat komplementer terhadap GARCH, bukan penggantinya.
Estimasi dengan Maximum Likelihood
Parameter GARCH diestimasi dengan maximum likelihood. Logikanya langsung: dengan , rekursi tersebut menghasilkan jalur lengkap conditional variance , dan dengan asumsi distribusi tertentu untuk inovasi kita bisa menuliskan seberapa mungkin return yang teramati itu terjadi. Kita kemudian memilih untuk memaksimalkan likelihood tersebut.
Asumsikan inovasi Gaussian , sehingga . Densitas bersyarat dari satu observasi adalah
Karena model ditulis secara bersyarat, likelihood gabungan terfaktorisasi menjadi produk densitas satu-langkah-ke-depan, dan log-likelihood-nya adalah jumlah sederhana:
Ada dua fakta struktural yang perlu diperhatikan. Pertama, muncul baik sebagai penalti ( — model dihukum karena mengklaim variance tinggi) maupun dalam residual terstandardisasi ( — model dihukum karena terkejut). Titik optimum menyeimbangkan keduanya, dan itulah yang membuat variance dapat dilacak. Kedua, rekursi membutuhkan seed ; pilihan umum adalah sample variance dari return, dan dengan beberapa ribu observasi seed tersebut nyaris tidak berpengaruh.
Tidak ada bentuk tertutup untuk maksimizer-nya, jadi kita mengoptimasi secara numerik (arch menggunakan metode quasi-Newton dengan gradien analitik atau numerik). Permukaan likelihood umumnya cukup baik untuk GARCH(1,1), tetapi ada dua hal yang bisa jadi masalah dalam praktiknya: batasan positivitas () dan perilaku dekat-batas ketika , di mana optimizer bisa merayap lambat. Keduanya ditangani untuk Anda oleh library yang baik — dan Anda sebaiknya menggunakannya. Membuat GARCH MLE sendiri dari awal adalah latihan belajar yang baik tetapi pilihan produksi yang buruk.
Library arch
Paket arch oleh Kevin Sheppard adalah alat standar di Python. Seluruh proses fitting hanya empat baris.
from arch import arch_model
r = ret * 100.0
model = arch_model(r, mean="Constant", vol="Garch", p=1, q=1, dist="normal")
res = model.fit(disp="off")
print(res.summary())
Sepatah kata tentang nama argumen, karena ini merupakan sumber kebingungan yang umum. Dalam arch, p adalah jumlah lag variance (istilah , orde GARCH) dan q adalah jumlah lag residual kuadrat (istilah , orde ARCH). Jadi p=1, q=1 adalah GARCH(1,1) yang kita turunkan. (Notasi asli Bollerslev menuliskannya sebagai GARCH() dengan untuk orde ARCH — kedua konvensi ini tertukar. Percayai dokumentasi library-nya sendiri, bukan ingatan Anda.)
Saat membaca ringkasan (summary), tabel koefisiennya kira-kira terlihat seperti ini (nilai ilustratif untuk return harian BTC, bukan eksperimen sungguhan):
Volatility Model
==========================================================
coef std err t P>|t|
----------------------------------------------------------
omega 0.4821 0.201 2.40 0.016
alpha[1] 0.0912 0.021 4.34 0.000
beta[1] 0.8994 0.024 37.5 0.000
==========================================================
Cara membacanya:
alpha[1] + beta[1]= 0.0912 + 0.8994 = 0.9906. Persistensi tepat di bawah 1 — rezim near-IGARCH, persis seperti yang diperingatkan. Half-life hari.omega= 0.4821, sehingga long-run variance-nya adalah dalam satuan persen-kuadrat, yaitu long-run daily volatility , atau kira-kira teranualisasi. Itu adalah angka BTC yang masuk akal.- Baik
alphamaupunbetasama-sama sangat signifikan.alphayang kecil relatif terhadapbetaadalah hal yang tipikal: variance crypto sebagian besar adalah persistensi (memori), dengan reaksi terhadap shock baru yang cukup nyata namun sedang.
Jebakan skala ×100
Ini adalah cara paling umum untuk mendapatkan hasil yang tidak masuk akal dari arch, sehingga layak mendapat subbagian tersendiri. Optimizer bekerja paling baik ketika angka yang dilihatnya berorde hingga . Log-return harian berorde , sehingga kuadratnya berorde dan harus berada di sekitar — turun ke rentang di mana gradien numerik kehilangan presisi dan fitting bisa diam-diam gagal konvergen atau mengembalikan standard error yang salah.
Solusinya adalah melakukan fitting pada return yang diskalakan dengan 100 (yaitu dalam satuan persen), seperti di atas. arch bahkan akan memunculkan DataScaleWarning jika Anda lupa. Semua yang Anda baca dari model kemudian berada dalam satuan persen atau persen-kuadrat, dan Anda harus menskalakan ulang secara konsisten:
sigma_pct = np.sqrt(res.forecast(horizon=1).variance.iloc[-1, 0])
sigma_decimal = sigma_pct / 100.0
print(f"1-day-ahead conditional vol: {sigma_decimal:.2%}")
Mencampur besaran yang sudah diskalakan dengan yang belum — misalnya memasukkan volatilitas dalam persen ke dalam formula position-sizing yang mengharapkan desimal — menghasilkan kesalahan tepat 100x, yang mudah terlewat karena kodenya tetap berjalan tanpa error. Pilih satu konvensi (saya menyimpan semuanya dalam desimal di luar proses fitting dan hanya menskalakan pada batas arch) dan jangan pernah melanggarnya.
Memprediksi Conditional Variance
Model yang sudah di-fit hanya berguna jika ia bisa memprediksi. GARCH memberikan prakiraan analitik yang bersih pada horizon berapa pun.
Satu langkah ke depan. Pada waktu (akhir sampel) kita mengetahui dan , sehingga variance berikutnya bersifat deterministik:
Tidak perlu ekspektasi — semua yang ada di ruas kanan sudah teramati.
Multi-langkah ke depan. Untuk kita belum mengetahui shock di antaranya, jadi kita mengambil ekspektasi bersyarat. Dengan menggunakan (karena ), rekursi tersebut runtuh menjadi AR(1) sederhana dalam variance yang diprediksi:
Mengiterasi ini dari prakiraan satu-langkah menghasilkan bentuk tertutup, yang merupakan hasil mean-reversion yang kita turunkan sebelumnya, dituliskan secara eksplisit:
Bacalah ini dengan saksama, karena inilah geometri dari setiap prakiraan GARCH. Struktur term dari variance dimulai pada conditional variance hari ini dan meluruh secara geometris menuju tingkat jangka panjang . Jika hari ini lebih tenang dari rata-rata, kurva prakiraan naik menuju ; jika hari ini adalah krisis, kurva itu turun menujunya. Kecepatan peluruhan itu sepenuhnya ditentukan oleh — dan dalam rezim near-IGARCH crypto, di mana , peluruhannya begitu lambat sehingga untuk horizon di bawah dua minggu prakiraan hampir tidak bergeser dari tingkat hari ini. Ini patut diresapi: untuk periode holding yang pendek, prakiraan GARCH crypto pada dasarnya adalah "besok terlihat seperti hari ini, hanya mean-revert sangat lambat."
Mengagregasi ke horizon holding. Trader jarang peduli dengan variance dari satu hari di masa depan saja. Jika Anda menahan posisi selama hari dan return tidak berkorelasi secara bersyarat (fakta terpola dari awal), variance dari return kumulatif -hari adalah jumlah dari prakiraan variance satu-hari:
Ini adalah angka yang sebenarnya Anda gunakan untuk sizing — volatilitas dari P&L selama periode holding Anda. Perhatikan bahwa ini tegas bukan skala naif , yang hanya benar jika variance konstan. Ketika variance hari ini di atas , prakiraan yang mean-reverting membuat vol -hari yang sebenarnya lebih rendah daripada aturan akar kuadrat; ketika hari ini tenang, itu lebih tinggi. Mendapatkan hal ini dengan benar adalah perbedaan antara stop yang menghormati struktur term dan yang tidak.
Dalam kode:
H = 10
fc = res.forecast(horizon=H, reindex=False)
var_path_pct2 = fc.variance.iloc[-1].values # [E_T sigma^2_{T+1}, ..., T+H]
var_path = var_path_pct2 / (100.0 ** 2) # back to decimal variance
daily_vol = np.sqrt(var_path)
print("Forecast daily vol path:", np.round(daily_vol * 100, 2), "%")
H_day_var = var_path.sum()
H_day_vol = np.sqrt(H_day_var)
print(f"{H}-day holding-period vol: {H_day_vol:.2%}")
naive = np.sqrt(var_path[0] * H)
print(f"Naive sqrt(H) * sigma_1: {naive:.2%}")
Untuk horizon yang lebih panjang, GARCH juga mendukung prakiraan simulasi (method="simulation"), yang memproyeksikan distribusi inovasi ke depan dan memberi Anda densitas prakiraan penuh, bukan hanya variance-nya — berguna ketika inovasi bersifat non-Gaussian, seperti yang akan terjadi begitu kita beralih ke distribusi Student-t dan skewed di Bagian 2. Untuk besaran yang linear-dalam-variance di atas, jalur analitik bersifat eksak dan tanpa biaya komputasi tambahan.
Diagnostik: Apakah Model Benar-Benar Bekerja?
Melakukan fitting model tidak sama dengan memvalidasinya. Inti dari GARCH adalah menyerap conditional heteroskedasticity — volatility clustering — sehingga yang tersisa (mendekati) i.i.d. Pemeriksaan yang tepat karenanya adalah melihat pada residual terstandardisasi
dan bertanya: apakah clustering-nya sudah hilang? Jika model berhasil menangkap dinamika variance, seharusnya memiliki variance satuan dan, yang penting, kuadrat-nya seharusnya tidak menunjukkan autokorelasi yang tersisa. Kita menjalankan tiga uji.
1. Ljung-Box pada residual terstandardisasi. Memeriksa bahwa tidak ada autokorelasi linear yang tersisa pada level (ini sebenarnya menguji model mean, bukan model variance). Seharusnya tidak menolak.
2. Ljung-Box pada residual terstandardisasi kuadrat. Ini adalah yang penting. Jika masih memiliki autokorelasi signifikan, model variance gagal menghilangkan clustering — ada struktur yang tidak ditangkap GARCH(1,1), dan Anda mungkin memerlukan orde yang lebih tinggi, varian asimetris, atau distribusi inovasi yang berbeda. Seharusnya tidak menolak.
3. Uji ARCH-LM (uji Lagrange-multiplier milik Engle). Meregresikan pada lag-nya sendiri dan menguji signifikansi bersama. Ini pada dasarnya adalah versi formal dari uji 2 dan langsung bertanya "apakah masih ada efek ARCH yang tersisa?" Hasil yang tidak signifikan mengonfirmasi bahwa conditional heteroskedasticity telah dimodelkan dengan baik.
from statsmodels.stats.diagnostic import acorr_ljungbox
from arch.unitroot.cointegration import engle_granger # (unrelated; shown for import clarity)
z = res.std_resid.dropna() # standardized residuals
z2 = z ** 2
lb_z = acorr_ljungbox(z, lags=[10, 20], return_df=True)
lb_z2 = acorr_ljungbox(z2, lags=[10, 20], return_df=True)
print("Ljung-Box on standardized residuals:\n", lb_z, "\n")
print("Ljung-Box on SQUARED standardized residuals:\n", lb_z2, "\n")
lm = res.arch_lm_test(lags=10, standardized=True)
print(lm)
print(f"\nStd-resid excess kurtosis: {stats.kurtosis(z):.2f}")
Seperti apa output yang baik: p-value Ljung-Box pada melompat dari mendekati nol (pada return kuadrat mentah) menjadi cukup nyaman di atas 0.05, dan uji ARCH-LM gagal menolak. Itulah bukti Anda bahwa model berhasil bekerja pada momen kedua.
Seperti apa output yang tidak sempurna — dan yang seharusnya Anda perkirakan dengan GARCH(1,1) Gaussian biasa pada crypto — adalah bahwa uji clustering lolos tetapi kurtosis residual terstandardisasi masih tinggi (katakanlah 4-6, bukan 0). GARCH menghilangkan clustering tetapi distribusi tak bersyarat berekor tebal tunggal tetap ada, karena inovasi Gaussian tidak bisa mereproduksi ekor tersebut. Ekor tebal residual yang tersisa itu bukan bug yang harus diperbaiki di sini; itu adalah motivasi untuk Bagian 2, GARCH asimetris dan efek leverage pada crypto, di mana inovasi Student-t dan skewed-t serta istilah asimetri GJR/EGARCH menangani hal ini secara tepat.
Aplikasi: Sizing dan Stop yang Diskalakan dengan Volatilitas
Kita sekarang memiliki prakiraan volatilitas besok (dan hari berikutnya). Apa yang kita lakukan dengan itu? Dua penggunaan tersederhana dan bernilai tertinggi adalah position sizing dan penempatan stop. Kita sengaja menjaga keduanya tetap dasar di sini — strategi vol-targeting lengkap dengan seluruh mekanisme praktisnya ada di Bagian 4.
Position sizing yang ditargetkan volatilitas
Idenya adalah menahan posisi yang kontribusi risikonya kira-kira konstan sepanjang waktu, bukan posisi yang nominalnya konstan. Jika Anda selalu menempatkan ukuran dolar yang sama, risiko Anda membengkak pada rezim vol tinggi dan menyusut pada rezim tenang — kebalikan dari yang Anda inginkan. Volatility targeting membalik ini: bidik target volatilitas P&L yang tetap, dan biarkan prakiraan yang menentukan ukurannya.
Untuk target volatilitas teranualisasi (katakanlah 20%) dan volatilitas teranualisasi yang diprediksi , bobot posisinya adalah
Ketika vol prakiraan tinggi, Anda mengecilkan skala; ketika rendah, Anda memperbesarnya. Itulah seluruh mekanismenya. Karena adalah prakiraan — diketahui pada sebelum return pada terealisasi — tidak ada look-ahead, asalkan Anda disiplin soal timing (lebih lanjut tentang ini di bagian jebakan).
def vol_target_weight(sigma_forecast_annual, sigma_target_annual=0.20,
w_max=3.0):
"""Volatility-scaled position weight. Inputs/outputs in decimals.
w_max caps leverage so a tiny forecast vol can't demand insane size."""
w = sigma_target_annual / sigma_forecast_annual
return float(np.clip(w, 0.0, w_max))
sigma_1d = np.sqrt(res.forecast(horizon=1).variance.iloc[-1, 0]) / 100.0
sigma_ann = sigma_1d * np.sqrt(365)
w = vol_target_weight(sigma_ann, sigma_target_annual=0.20)
print(f"Forecast annual vol: {sigma_ann:.1%} -> position weight: {w:.2f}x")
Ini adalah sepupu dekat dari aturan alokasi modal yang tepat. Volatility targeting menjawab "seberapa besar risiko seharusnya berskala dengan volatilitas," sementara kriteria Kelly menjawab "seberapa besar risiko seharusnya berskala dengan edge" — dan keduanya dikalikan bersama dalam susunan sizing yang lengkap: ukuran edge / variance. Perhatikan bahwa istilah variance dari Kelly persis merupakan prakiraan GARCH yang baru saja Anda hitung, itulah mengapa model volatilitas hidup secara material mempertajam sizing Kelly dibanding estimasi historis statis. Jika estimasi edge Anda sendiri membawa ketidakpastian yang terkuantifikasi, conformal prediction memberikan cara bebas-distribusi untuk memperlebar atau mengecilkan ukuran agar sesuai, dan ini berpadu rapi dengan vol targeting.
Batas atas w_max bukan opsional. Dalam rezim near-IGARCH, periode tenang bisa mendorong vol prakiraan menjadi cukup rendah, dan akan menuntut leverage yang terlihat bagus di atas kertas dan menghancurkan ketika ketenangan itu pecah — yang, sesuai volatility clustering, pada akhirnya memang terjadi, sering kali secara mendadak. Membatasi leverage adalah pengakuan kasar-tapi-efektif bahwa prakiraan Anda adalah mean bersyarat, bukan jaminan, dan bahwa payoff dari kesalahan bersifat asimetris. Asimetri itu — akun yang bangkrut tidak bisa dipulihkan oleh kemenangan simetris — persis merupakan asimetri loss-vs-profit yang seharusnya membuat Anda secara sistematis lebih konservatif daripada yang disarankan oleh aturan yang hanya berbasis variance.
Stop yang diskalakan dengan volatilitas
Stop persentase tetap memiliki penyakit yang sama dengan ukuran posisi tetap: stop 3% adalah pemicu yang sangat sensitif di pasar tenang dan kesalahan pembulatan di pasar yang liar. Ini membuat Anda tersingkir dari posisi yang bagus oleh noise biasa selama rezim vol tinggi dan memberikan kembali terlalu banyak selama transisi. Solusinya adalah menetapkan jarak stop dalam satuan volatilitas prakiraan.
di mana adalah volatilitas prakiraan selama horizon holding yang diharapkan (besaran teragregasi dari bagian prakiraan) dan adalah kelipatan — biasanya 1.5 hingga 3 — yang dipilih agar stop berada di luar fluktuasi normal tetapi di dalam pergerakan adverse yang genuine.
def vol_scaled_stop(entry_price, side, sigma_H, k=2.0):
"""
entry_price : fill price
side : +1 long, -1 short
sigma_H : forecast volatility over the holding horizon (decimal)
k : stop width in vol units
Returns the stop price.
"""
stop_frac = k * sigma_H
return entry_price * (1.0 - side * stop_frac)
var_path = res.forecast(horizon=10, reindex=False).variance.iloc[-1].values / (100.0 ** 2)
sigma_H = np.sqrt(var_path.sum())
entry = float(px.iloc[-1])
stop = vol_scaled_stop(entry, side=+1, sigma_H=sigma_H, k=2.0)
print(f"Entry {entry:,.0f} | 10-day vol {sigma_H:.2%} | 2-sigma stop {stop:,.0f}")
Karena menggunakan prakiraan struktur term yang mean-reverting alih-alih angka historis yang datar, stop secara otomatis melebar menjelang rezim yang bergejolak dan menyempit ketika volatilitas mereda — struktur term itu sendiri yang melakukan penyesuaian untuk Anda. Ini adalah prakiraan yang sama yang memberi makan baik ukuran maupun stop, yang merupakan fitur: dalam rezim vol tinggi Anda secara bersamaan menahan lebih sedikit dan memberi posisi lebih banyak ruang, dan kedua efek itu bergabung menjadi risiko ekor yang secara material lebih rendah. Sizing dan stop adalah dua proyeksi dari satu pandangan volatilitas, bukan dua kenop yang independen.
Sejauh itulah kita membawa aplikasi ini di Bagian 1. Strategi nyata harus menangani biaya transaksi dari rebalancing yang konstan, timing kapan prakiraan dihitung versus kapan trade ditempatkan, kontrol turnover, dan — di atas segalanya — evaluasi out-of-sample yang jujur. Semua itu ada di Bagian 4: strategi GARCH volatility-targeting, di mana kita membangun dan menguji walk-forward seluruh strategi tersebut.
Jebakan
GARCH mudah di-fit dan mudah membuat Anda menipu diri sendiri. Mode kegagalannya konsisten.
Skala return. Sudah dibahas di atas, tetapi ini adalah bug nomor satu, jadi layak diulang: lakukan fitting arch pada return × 100, dan skalakan ulang setiap output (variance dengan , volatilitas dengan ). Kesalahan 100x yang diam-diam terjadi di sini meracuni setiap perhitungan sizing dan stop hilir.
Look-ahead dalam fitting. Pembunuh yang halus. Jika Anda melakukan fitting model pada seluruh riwayat lalu menghitung "prakiraan" pada riwayat yang sama itu, setiap prakiraan itu diam-diam telah melihat masa depan — parameter diestimasi menggunakan data dari setelah tanggal prakiraan. Fitting in-sample akan terlihat luar biasa dan performa live tidak akan menyerupainya sama sekali. Setiap prakiraan yang di-backtest harus berasal dari model yang di-fit hanya pada data yang tersedia pada saat itu: refit pada expanding atau rolling window, prakirakan satu langkah, gulirkan ke depan. Ini tidak bisa ditawar dan menjadi topik utuh dari walk-forward optimization. Kesenjangan antara GARCH in-sample dan yang benar-benar walk-forward adalah kesenjangan antara demo dan sistem yang bertahan hidup dalam kontak dengan pasar live — lihat juga paritas backtest-live.
Timing prakiraan. Terkait tetapi berbeda. Prakiraan untuk hari harus dihitung dari informasi yang tersedia pada penutupan hari (atau kapan pun bar Anda ditutup), dan posisinya harus dapat dieksekusi pada harga yang benar-benar bisa Anda dapatkan. Menghitung prakiraan menggunakan penutupan hari lalu "memperdagangkannya" pada pembukaan hari adalah look-ahead yang diam-diam menggelembungkan setiap hasil.
Overfitting orde tinggi. GARCH(1,1) hampir selalu cukup. Godaan untuk melakukan fitting GARCH(2,2) atau GARCH(3,1) karena itu sedikit menaikkan log-likelihood in-sample biasanya adalah noise-fitting; parameter tambahan jarang meningkatkan prakiraan out-of-sample dan sering membuat optimizer tidak stabil dekat batas. Utamakan model yang parsimonious, dan jika Anda harus membandingkan orde, bandingkan dengan loss prakiraan out-of-sample pada split walk-forward, bukan dengan AIC in-sample. Ketika diagnostik residual masih menunjukkan masalah, solusinya biasanya adalah distribusi inovasi yang lebih baik atau istilah asimetri (Bagian 2), bukan orde yang lebih tinggi.
Structural break yang terbaca sebagai persistensi. Seperti yang telah dicatat, pergeseran permanen pada tingkat volatilitas (rezim pasar baru, perubahan pada mikrostruktur pasar) bisa diserap oleh GARCH sebagai persistensi yang secara palsu tinggi, mendorong menuju 1. Jika estimasi long-run vol Anda terlihat tidak stabil di seluruh jendela, curigai adanya break, bukan mempercayai estimasi titik near-IGARCH begitu saja. Refit yang bergulir dan, di mana sesuai, model rezim yang eksplisit menjaga terhadap hal ini.
Memperlakukan prakiraan volatilitas sebagai prakiraan return. GARCH memprediksi besaran pergerakan, bukan arahnya. Ia memberi tahu Anda seberapa besar swing besok kemungkinan terjadi, bukan ke arah mana. Inilah tepatnya mengapa habitat aslinya adalah manajemen risiko — sizing, stop, VaR — bukan pembangkitan sinyal. Jangan salah mengira prakiraan variance yang baik sebagai sebuah edge.
Ke Mana Ini Berlanjut
GARCH(1,1) adalah fondasinya, dan sengaja dibuat tidak lengkap. Seri ini membangun di atasnya dalam tiga arah:
- Asimetri dan ekor tebal — volatilitas crypto yang sesungguhnya merespons lebih kuat terhadap pergerakan turun dibanding naik (efek leverage), dan inovasi Gaussian tidak dapat mereproduksi ekornya. GJR-GARCH, EGARCH, dan inovasi Student-t / skewed-t ada di Bagian 2.
- Volatilitas multivariat — korelasi antar aset crypto sendiri berubah seiring waktu dan melonjak saat crash. Memodelkan seluruh matriks kovarian secara dinamis ada di Bagian 3: DCC-GARCH, yang terhubung langsung dengan Markowitz mean-variance dan alokasi berbasis CVaR begitu kovarian menjadi dinamis.
- Strategi lengkap — sizing, stop, biaya, turnover, dan evaluasi walk-forward yang jujur bersatu di Bagian 4.
Dan di mana marginal GARCH memberi makan risiko gabungan: model conditional-variance univariat di sini persis merupakan tahap pertama dari pipeline GARCH-EVT-copula untuk VaR/CVaR portofolio. Begitu Anda memiliki residual terstandardisasi dari fitting GARCH per aset, Anda mentransformasikannya dan merekatkannya bersama dengan copula — marginalnya adalah GARCH, ketergantungannya adalah copula. Konstruksi itu, termasuk tail dependence dan penanganan ekor EVT, dibahas secara mendalam dalam model copula untuk risiko crypto gabungan; artikel ini adalah mesin univariat yang berada di bawahnya.
Ringkasan
- Return crypto menunjukkan volatility clustering, ekor tebal, dan tidak ada autokorelasi return tetapi autokorelasi return kuadrat yang kuat. Alat apa pun yang mengasumsikan volatilitas konstan — Black-Scholes dengan satu , VaR statis, stop persentase tetap — salah spesifikasi terhadap fakta-fakta ini.
- GARCH(1,1), , memodelkan conditional variance yang berubah seiring waktu dengan tiga parameter: baseline , reaksi shock , dan persistensi . Ini adalah ARCH() dengan memori yang meluruh secara geometris, itulah mengapa ia mengalahkan ARCH orde tinggi.
- Stasioneritas membutuhkan ; variance jangka panjang adalah , persistensi adalah , dan half-life volatilitas adalah . Crypto berada dalam rezim near-IGARCH (): sangat persisten, lambat mean-revert, dan dengan estimasi long-run-variance yang rapuh.
- Estimasi dengan maximum likelihood. Log-likelihood Gaussian adalah jumlah dari densitas satu-langkah; lakukan fitting dengan
arch_model(r*100, vol="Garch", p=1, q=1). Ingat skala ×100 dan skalakan ulang setiap output secara konsisten. - Prakiraan mean-revert secara geometris menuju long-run variance dengan laju . Agregasi prakiraan variance harian untuk mendapatkan volatilitas horizon holding — bukan aturan naif .
- Validasi dengan Ljung-Box pada residual terstandardisasi kuadrat dan uji ARCH-LM. Melewati keduanya mengonfirmasi clustering telah berhasil dimodelkan; ekor tebal residual yang tersisa memotivasi Bagian 2.
- Terapkan pada sizing yang ditargetkan volatilitas (, dibatasi) dan stop yang diskalakan volatilitas (). Satu prakiraan mendorong keduanya, sehingga rezim vol tinggi mendapatkan ukuran lebih kecil dan stop lebih lebar secara bersamaan.
- Jebakan yang penting: skala return, look-ahead dalam fitting (fit hanya pada data masa lalu, selalu walk-forward), timing prakiraan, over-ordering, dan jangan pernah salah mengira prakiraan variance sebagai prakiraan arah.
References:
- Engle, R. F. (1982). Autoregressive Conditional Heteroscedasticity with Estimates of the Variance of United Kingdom Inflation. Econometrica, 50(4), 987-1007. DOI
- Bollerslev, T. (1986). Generalized Autoregressive Conditional Heteroskedasticity. Journal of Econometrics, 31(3), 307-327. DOI
- Mandelbrot, B. (1963). The Variation of Certain Speculative Prices. The Journal of Business, 36(4), 394-419. DOI
- Nelson, D. B. (1991). Conditional Heteroskedasticity in Asset Returns: A New Approach. Econometrica, 59(2), 347-370. DOI
- Katsiampa, P. (2017). Volatility estimation for Bitcoin: A comparison of GARCH models. Economics Letters, 158, 3-6. DOI
- Chu, J., Chan, S., Nadarajah, S., & Osterrieder, J. (2017). GARCH Modelling of Cryptocurrencies. Journal of Risk and Financial Management, 10(4), 17. DOI
- Sheppard, K. (2023). arch: Autoregressive Conditional Heteroskedasticity (ARCH) and other tools for financial econometrics in Python. GitHub.
MarketMaker.cc Team
Riset & Strategi Kuantitatif