Copulamodellen voor gezamenlijke risicomodellering in cryptoportefeuilles

Correlatie is het eerste instrument waar de meeste portefeuillebeheerders naar grijpen bij het beoordelen van diversificatie. Maar in cryptomarkten is correlatie gevaarlijk misleidend. Twee tokens kunnen tijdens rustige markten een Pearson-correlatie van 0,3 vertonen en tijdens een crash plotseling naar 0,95 stijgen. Lineaire correlatie gaat uit van elliptische verdelingen — een aanname die instort onder de zware staarten en asymmetrische afhankelijkheidsstructuren die inherent zijn aan cryptocurrency-rendementen.
Copulamodellen lossen dit op door marginaal gedrag (hoe elk actief individueel presteert) te scheiden van afhankelijkheidsstructuur (hoe activa samen bewegen). Deze scheiding, geworteld in de stelling van Sklar, geeft ons een flexibel raamwerk om de volledige gezamenlijke verdeling van portefeuillerendementen te modelleren — inclusief de staarten waar het risico daadwerkelijk zit.
Waarom lineaire correlatie faalt voor crypto
Beschouw een portefeuille van BTC, ETH, SOL en AVAX. Tijdens de instorting van Terra/Luna in mei 2022 convergeerden de correlaties tussen deze activa naar 1,0, precies op het moment dat diversificatie het meest nodig was. Een mean-variance-optimalisator die stabiele correlaties veronderstelde, zou het portefeuillerisico drastisch hebben onderschat.
De kernproblemen met Pearson-correlatie voor crypto:
- Niet-elliptische verdelingen. Crypto-rendementen vertonen aanzienlijke scheefheid en kurtosis. Dagelijkse BTC-rendementen vertonen regelmatig kurtosiswaarden boven 10 (normale verdeling: 3).
- Asymmetrische afhankelijkheid. Activa zijn tijdens neergangen doorgaans sterker gecorreleerd dan tijdens rally's. Dit "correlatie-instortings"-fenomeen is goed gedocumenteerd in aandelenmarkten en is nog uitgesprokener in crypto.
- Staartafhankelijkheid. De kans dat twee activa gelijktijdig extreme verliezen ondervinden, wordt niet vastgelegd door lineaire correlatie. Je kunt twee activa hebben met identieke correlatie maar sterk verschillende staartafhankelijkheid.
De stelling van Sklar: de basis
De stelling van Sklar (1959) stelt dat elke multivariate gezamenlijke verdeling kan worden ontbonden in:
waarbij de marginale verdelingsfuncties zijn en de copula is — een functie die de volledige afhankelijkheidsstructuur tussen variabelen codeert.
Omgekeerd geldt: als de marginalen continu zijn, is de copula uniek.
Deze ontbinding is krachtig omdat ze ons in staat stelt om:
- De marginale verdeling van elk actief afzonderlijk te modelleren (met GARCH, EVT, of elke andere geschikte verdeling)
- De afhankelijkheidsstructuur onafhankelijk te modelleren via de copula
- Ze te combineren om de volledige gezamenlijke verdeling te verkrijgen
De dichtheid van de gezamenlijke verdeling ontbindt als volgt:
waarbij de copuladichtheid is en de marginale dichtheden.
Copulafamilies en hun eigenschappen

Gaussische copula
De Gaussische copula wordt geparametriseerd door een correlatiematrix :
waarbij de multivariate normale CDF is en de univariate normale kwantielfunctie.
Staartafhankelijkheid: (voor ).
De Gaussische copula heeft geen staartafhankelijkheid — ze onderschat systematisch de kans op gezamenlijke extreme gebeurtenissen. Dit was een belangrijke factor bij de verkeerde prijsstelling van CDO's vóór 2008, en het is even gevaarlijk voor crypto-risicomodellering.
Student's t-copula
De t-copula introduceert symmetrische staartafhankelijkheid via een vrijheidsgraden-parameter :
Staartafhankelijkheid:
Voor en geeft dit — een kans van 18% dat beide activa zich tegelijkertijd in hun slechtste kwantiel bevinden. Lagere (zwaardere staarten) verhoogt deze kans. Cryptomarkten, met hun dikstaartige rendementen, vereisen doorgaans een in het bereik van 3-8.
De t-copula is een aanzienlijke verbetering ten opzichte van Gaussisch, maar legt symmetrische staartafhankelijkheid op (). In de praktijk vertonen crypto-activa vaak sterkere afhankelijkheid in de onderste staart (samen crashen) dan in de bovenste staart (samen stijgen).
Clayton-copula
De Clayton-copula legt afhankelijkheid in de onderste staart vast — precies het soort asymmetrisch crash-clusteringgedrag dat we in crypto zien:
Staartafhankelijkheid: , .
Naarmate toeneemt, wordt de afhankelijkheid in de onderste staart sterker. Voor is — een zeer hoge kans op gezamenlijke extreme verliezen.
Gumbel-copula
De Gumbel-copula is het spiegelbeeld — ze legt afhankelijkheid in de bovenste staart vast:
Staartafhankelijkheid: , .
Frank-copula
De Frank-copula heeft geen staartafhankelijkheid in beide staarten (), wat haar geschikt maakt voor het modelleren van afhankelijkheid in het centrale gedeelte van de verdeling zonder staarteffecten:
De juiste copula kiezen voor crypto
Voor cryptoportefeuilles wijst het empirisch bewijs op:
- Clayton of geroteerde Gumbel (survival Gumbel) voor afhankelijkheid in de onderste staart — het vastleggen van crash-besmetting
- t-copula als een robuuste algemene keuze wanneer symmetrische staartafhankelijkheid aanvaardbaar is
- Joe-copula voor het vastleggen van sterke afhankelijkheid in de bovenste staart tijdens rallyfases
Onderzoek van Bruhn en Jeleskovic (2024) toonde aan dat GARCH-copulamodellen, met name die welke Student's t-marginalen met t-copula's gebruiken, consistent beter presteerden dan mean-variance- en historische CVaR-benaderingen tijdens neergang (2022), herstel (2023) en stabiliteit (2024) marktomstandigheden in crypto.
De vloek van de dimensionaliteit: vine-copula's komen in beeld

Standaard multivariate copula's (Gaussisch, t-copula) schalen naar hoge dimensies maar leggen restrictieve aannames op. Archimedische copula's (Clayton, Gumbel, Frank) zijn van nature bivariaat — ze uitbreiden naar dimensies vereist dat alle paren dezelfde afhankelijkheidsparameter delen, wat onrealistisch is.
Vine-copula's lossen dit op door een -dimensionale copula te ontbinden in een cascade van bivariate copula's gerangschikt in een boomstructuur. Elk paar variabelen (voorwaardelijk op andere) krijgt zijn eigen bivariate copulafamilie en parameter.
De pair-copulaconstructie
Voor een -dimensionale dichtheid is de vine-copulafactorisatie:
waarbij een bivariate copuladichtheid is voor variabelen en voorwaardelijk op de verzameling .
Een -dimensionale vine-copula vereist bivariate copula's. Voor een cryptoportefeuille met 10 activa zijn dat 45 paarcopula's — elk mogelijk uit een andere familie.
Vine-structuren: C-vine, D-vine, R-vine
C-vine (canonieke vine): Elke boom heeft een enkele wortelknoop verbonden met alle andere knopen. Het beste wanneer één variabele domineert — bijv. BTC als de marktdrijver.
Tree 1: BTC --- ETH
BTC --- SOL
BTC --- AVAX
BTC --- DOT
Tree 2: ETH|BTC --- SOL|BTC
ETH|BTC --- AVAX|BTC
ETH|BTC --- DOT|BTC
D-vine (tekenbare vine): Een sequentiële padstructuur. Het beste wanneer variabelen een natuurlijke ordening hebben (bijv. naar marktkapitalisatie of sector).
R-vine (reguliere vine): De meest algemene structuur — elke geldige boomvolgorde. R-vines omvatten zowel C-vines als D-vines.
Onderzoek naar cryptocurrency-portefeuilles suggereert dat D-vine-structuren vaak superieure VaR-voorspellingen opleveren in vergelijking met C-vine en R-vine voor crypto-activa, hoewel dit afhangt van de specifieke portefeuillesamenstelling.
Waarom vine-copula's belangrijk zijn voor crypto
Een portefeuille van 8 crypto-activa gemodelleerd met één enkele Clayton-copula dwingt alle 28 paren om dezelfde te delen. Maar BTC-ETH zou (sterke crashafhankelijkheid) kunnen hebben, terwijl SOL-AVAX (gematigd) zou kunnen hebben. Vine-copula's laten elk paar zijn eigen afhankelijkheidsstructuur uitdrukken:
- BTC-ETH: t-copula (, )
- BTC-SOL: Clayton ()
- ETH-AVAX: Frank ()
- SOL-DOT | BTC: Gumbel ()
Deze flexibiliteit is cruciaal voor nauwkeurige portefeuillerisicoschatting.
De marginalen modelleren: GARCH-EVT
Voordat we de copula fitten, moeten we de rendementsreeks van elk actief transformeren naar uniforme variabelen (de "probability integral transform"). De standaardpijplijn:
- Fit een GARCH-model op de rendementsreeks van elk actief om tijdsvariërende volatiliteit vast te leggen
- Extraheer gestandaardiseerde residuen
- Fit de staarten met behulp van Extreme Value Theory (EVT) — specifiek, de Generalized Pareto Distribution (GPD) voor de bovenste en onderste staarten voorbij een drempel (doorgaans het 5e en 95e percentiel)
- Gebruik de empirische CDF voor het centrale gedeelte van de verdeling
- Pas de probability integral transform toe om pseudo-uniforme observaties te verkrijgen
Deze GARCH-EVT-aanpak wordt vaak de "semi-parametrische" methode genoemd. Ze legt correct vast:
- Volatiliteitsclustering (GARCH)
- Zware staarten (GPD van EVT)
- De algehele vorm van de verdeling (empirische CDF voor het centrale gedeelte)
Voor crypto-activa werkt een EGARCH(1,1)- of GJR-GARCH(1,1)-model met Student's t-innovaties doorgaans goed, omdat het de asymmetrische volatiliteitsrespons vastlegt (slecht nieuws verhoogt de volatiliteit meer dan goed nieuws).
Portefeuille-VaR en -CVaR met copula's
Value-at-Risk (VaR)
Portefeuille-VaR op betrouwbaarheidsniveau is:
waarbij het portefeuilleverlies is. Met copula's schatten we VaR via Monte Carlo:
- Simuleer steekproeven uit de gefitte vine-copula (in uniforme ruimte)
- Transformeer terug naar rendementsruimte met behulp van de inverse marginale CDF's
- Bereken portefeuillerendementen:
- VaR is het -kwantiel van de gesimuleerde portefeuilleverliesverdeling
Conditional Value-at-Risk (CVaR / Expected Shortfall)
CVaR is het verwachte verlies gegeven dat het verlies groter is dan VaR:
CVaR is coherent (voldoet aan subadditiviteit), waardoor het superieur is aan VaR voor portefeuille-optimalisatie. Monte Carlo-schatting is eenvoudig — bereken het gemiddelde van de verliezen die VaR overschrijden.
Waarom copula-gebaseerd risico beter is dan correlatie-gebaseerd risico
Beschouw twee portefeuilles met identieke paarsgewijze correlaties van 0,5:
- Portefeuille A: Gaussische copula-afhankelijkheid (geen staartafhankelijkheid)
- Portefeuille B: Clayton copula-afhankelijkheid (, )
Op het 99%-betrouwbaarheidsniveau zal portefeuille B een aanzienlijk hogere VaR en CVaR hebben omdat de Clayton-copula de neiging van activa om samen te crashen correct modelleert. De Gaussische copula onderschat dit risico door aan te nemen dat extreme gezamenlijke bewegingen verwaarloosbaar zeldzaam zijn.
In empirische studies naar cryptoportefeuilles kan het verschil in 99%-CVaR tussen Gaussische en vine-copulamodellen meer dan 30-40% bedragen, wat betekent dat correlatie-gebaseerde modellen het staartrisico met een derde of meer kunnen onderschatten.
Implementatie: Python met pyvinecopulib
Hier is een volledige pijplijn voor het fitten van een vine-copula op crypto-rendementen en het schatten van portefeuille-VaR/CVaR.
Stap 1: Datavoorbereiding en marginale fitting
import numpy as np
import pandas as pd
from arch import arch_model
from scipy import stats
import pyvinecopulib as pv
def fetch_crypto_returns(symbols, start="2023-01-01", end="2025-12-31"):
"""
Fetch daily returns for a list of crypto symbols.
Replace with your data source (ccxt, yfinance, etc.)
"""
import yfinance as yf
prices = yf.download(
[f"{s}-USD" for s in symbols],
start=start, end=end
)["Close"]
prices.columns = symbols
returns = np.log(prices / prices.shift(1)).dropna()
return returns
symbols = ["BTC", "ETH", "SOL", "AVAX", "DOT", "LINK", "MATIC", "ATOM"]
returns = fetch_crypto_returns(symbols)
def fit_garch_marginal(series, dist="t"):
"""
Fit GJR-GARCH(1,1) with Student-t innovations.
Returns standardized residuals and the fitted model.
"""
model = arch_model(
series * 100, # scale for numerical stability
vol="GARCH",
p=1, o=1, q=1, # GJR-GARCH
dist=dist,
mean="AR",
lags=1
)
result = model.fit(disp="off")
std_resid = result.std_resid.dropna()
return std_resid, result
residuals = {}
garch_models = {}
for sym in symbols:
std_resid, model = fit_garch_marginal(returns[sym])
residuals[sym] = std_resid
garch_models[sym] = model
residuals_df = pd.DataFrame(residuals).dropna()
Stap 2: Probability integral transform
def semi_parametric_pit(residuals, tail_threshold=0.05):
"""
Semi-parametric probability integral transform:
- GPD for tails beyond threshold
- Empirical CDF for the body
Returns pseudo-uniform observations in [0, 1].
"""
n = len(residuals)
u = np.zeros(n)
sorted_resid = np.sort(residuals)
lower_thresh = np.quantile(residuals, tail_threshold)
upper_thresh = np.quantile(residuals, 1 - tail_threshold)
for i, x in enumerate(residuals):
if x <= lower_thresh:
lower_exceedances = -(residuals[residuals <= lower_thresh] - lower_thresh)
shape, _, scale = stats.genpareto.fit(lower_exceedances, floc=0)
u[i] = tail_threshold * (
1 - stats.genpareto.cdf(-(x - lower_thresh), shape, scale=scale)
)
elif x >= upper_thresh:
upper_exceedances = residuals[residuals >= upper_thresh] - upper_thresh
shape, _, scale = stats.genpareto.fit(upper_exceedances, floc=0)
u[i] = 1 - tail_threshold * (
1 - stats.genpareto.cdf(x - upper_thresh, shape, scale=scale)
)
else:
u[i] = np.mean(residuals <= x)
u = np.clip(u, 1e-6, 1 - 1e-6)
return u
U = np.column_stack([
semi_parametric_pit(residuals_df[sym].values)
for sym in symbols
])
Stap 3: Fit de vine-copula
controls = pv.FitControlsVinecop(
family_set=[
pv.BicopFamily.student,
pv.BicopFamily.clayton,
pv.BicopFamily.gumbel,
pv.BicopFamily.frank,
pv.BicopFamily.joe,
pv.BicopFamily.bb1, # Clayton-Gumbel mixture
pv.BicopFamily.bb7, # Joe-Clayton mixture
pv.BicopFamily.gaussian,
],
selection_criterion="bic", # BIC for model selection
tree_criterion="tau", # Kendall's tau for tree structure
nonparametric_method="constant",
trunc_lvl=5, # Truncate after 5 trees
)
vine = pv.Vinecop(U, controls=controls)
print(f"Log-likelihood: {vine.loglik(U):.2f}")
print(f"AIC: {vine.aic(U):.2f}")
print(f"BIC: {vine.bic(U):.2f}")
for i in range(vine.order.shape[0] - 1):
pair = vine.get_pair_copula(0, i)
print(f"Tree 1, Edge {i}: {pair.family} "
f"(params: {pair.parameters})")
Stap 4: Monte Carlo VaR en CVaR
def estimate_var_cvar(vine, garch_models, symbols, weights,
n_sim=50_000, alpha=0.99, seed=42):
"""
Estimate portfolio VaR and CVaR using Monte Carlo simulation
from the fitted vine copula.
"""
U_sim = vine.simulate(n=n_sim, seeds=[seed])
returns_sim = np.zeros((n_sim, len(symbols)))
for j, sym in enumerate(symbols):
model = garch_models[sym]
forecasts = model.forecast(horizon=1)
mu = forecasts.mean.iloc[-1, 0] / 100 # unscale
sigma = np.sqrt(forecasts.variance.iloc[-1, 0]) / 100
nu = model.params.get("nu", 5)
z_sim = stats.t.ppf(U_sim[:, j], df=nu)
returns_sim[:, j] = mu + sigma * z_sim
weights = np.array(weights)
portfolio_returns = returns_sim @ weights
losses = -portfolio_returns
var = np.quantile(losses, alpha)
cvar = np.mean(losses[losses >= var])
return var, cvar, portfolio_returns
weights = [1.0 / len(symbols)] * len(symbols)
var_99, cvar_99, sim_returns = estimate_var_cvar(
vine, garch_models, symbols, weights,
n_sim=100_000, alpha=0.99
)
print(f"1-day 99% VaR: {var_99*100:.2f}%")
print(f"1-day 99% CVaR: {cvar_99*100:.2f}%")
from scipy.stats import norm
mu_p = sim_returns.mean()
sigma_p = sim_returns.std()
var_gauss = -(mu_p + sigma_p * norm.ppf(0.01))
print(f"\nGaussian VaR: {var_gauss*100:.2f}%")
print(f"Copula/Gaussian ratio: {var_99/var_gauss:.2f}x")
Stap 5: Staartafhankelijkheidsanalyse
def compute_tail_dependence(vine, symbols):
"""
Extract lower and upper tail dependence coefficients
from the first tree of the vine copula.
"""
results = []
order = vine.order
n_edges = order.shape[0] - 1
for i in range(n_edges):
pair = vine.get_pair_copula(0, i)
u_pair = pair.simulate(n=100_000, seeds=[42])
q = 0.01 # 1st percentile
mask_lower = (u_pair[:, 0] <= q)
lambda_L = np.mean(u_pair[mask_lower, 1] <= q) if mask_lower.sum() > 0 else 0
mask_upper = (u_pair[:, 0] >= 1 - q)
lambda_U = np.mean(u_pair[mask_upper, 1] >= 1 - q) if mask_upper.sum() > 0 else 0
i_idx = order[0]
j_idx = order[i + 1]
results.append({
"pair": f"{symbols[i_idx]}-{symbols[j_idx]}",
"family": str(pair.family),
"lambda_L": round(lambda_L, 4),
"lambda_U": round(lambda_U, 4),
})
return pd.DataFrame(results)
tail_dep = compute_tail_dependence(vine, symbols)
print(tail_dep.to_string(index=False))
Een typische output voor een cryptoportefeuille zou er zo uit kunnen zien:
| Pair | Family | ||
|---|---|---|---|
| BTC-ETH | student | 0.22 | 0.22 |
| BTC-SOL | clayton | 0.35 | 0.00 |
| BTC-AVAX | bb7 | 0.28 | 0.12 |
| BTC-DOT | student | 0.18 | 0.18 |
| BTC-LINK | clayton | 0.31 | 0.00 |
| BTC-MATIC | frank | 0.00 | 0.00 |
| BTC-ATOM | gumbel | 0.00 | 0.15 |
Merk op hoe elk paar een compleet andere afhankelijkheidsstructuur kan hebben. BTC-SOL vertoont sterke afhankelijkheid in de onderste staart (Clayton) met nul afhankelijkheid in de bovenste staart — ze crashen samen maar stijgen niet noodzakelijkerwijs samen. BTC-MATIC vertoont helemaal geen staartafhankelijkheid (Frank), wat wijst op enig diversificatievoordeel zelfs in extreme situaties.
Backtesten van het copula-VaR-model
Een VaR-model is alleen bruikbaar als het goed gekalibreerd is. De standaard backtest berekent VaR-overschrijdingen — dagen waarop het werkelijke verlies groter was dan de voorspelde VaR — en test of het overschrijdingspercentage overeenkomt met het verwachte percentage.
def backtest_var(returns, symbols, weights, window=500,
alpha=0.99, n_sim=20_000):
"""
Rolling-window VaR backtest using vine copula.
"""
violations = []
var_series = []
T = len(returns)
for t in range(window, T):
window_returns = returns.iloc[t-window:t]
U_window = np.zeros((window, len(symbols)))
models_t = {}
for j, sym in enumerate(symbols):
std_resid, model = fit_garch_marginal(window_returns[sym])
models_t[sym] = model
u = pv.to_pseudo_obs(std_resid.values.reshape(-1, 1))
U_window[:len(u), j] = u.ravel()
U_clean = U_window[~np.any(U_window == 0, axis=1)]
vine_t = pv.Vinecop(U_clean, controls=controls)
var_t, _, _ = estimate_var_cvar(
vine_t, models_t, symbols, weights,
n_sim=n_sim, alpha=alpha
)
var_series.append(var_t)
actual_return = (returns.iloc[t][symbols].values
* np.array(weights)).sum()
violations.append(-actual_return > var_t)
violation_rate = np.mean(violations)
expected_rate = 1 - alpha
print(f"Expected violation rate: {expected_rate:.4f}")
print(f"Actual violation rate: {violation_rate:.4f}")
print(f"Number of violations: {sum(violations)} / {len(violations)}")
return violations, var_series
Een goed gekalibreerd 99%-VaR-model zou een overschrijdingspercentage dicht bij 1% moeten hebben. Als het percentage aanzienlijk hoger is, onderschat het model het risico. Als het aanzienlijk lager is, is het te conservatief.
Praktische overwegingen
Rekenkosten
Het fitten van vine-copula's is per boomniveau. Voor een portefeuille met 10 activa met een rollend venster van 500 dagen kan een volledige backtest met 50.000 Monte Carlo-simulaties per stap uren duren. Strategieën om dit te beheersen:
- Afgekapte vines: Stel
trunc_lvl=3oftrunc_lvl=4in — hogere bomen leggen zwakkere voorwaardelijke afhankelijkheden vast die minder bijdragen aan het risico - Verminderd aantal simulaties: 10.000-20.000 simulaties volstaan vaak voor 99% VaR
- Parallelle berekening: De GARCH-fits voor elk actief zijn onafhankelijk en kunnen parallel worden uitgevoerd
- Modelcaching: Fit de copula wekelijks opnieuw in plaats van dagelijks, en werk alleen de GARCH-voorspellingen bij
Regimebewustzijn
Cryptomarkten vertonen duidelijke regimes (bull, bear, zijwaarts, hoge-volatiliteitsgebeurtenissen). Een enkele vine-copula gefit over de hele steekproef legt mogelijk geen regime-afhankelijke afhankelijkheid vast. Overweeg:
- Rollende vensters van 250-500 dagen
- Regime-switching copula's waarbij de copulaparameters afhangen van een verborgen Markov-toestand
- Exponentieel gewogen observaties die meer gewicht geven aan recente data
Veelvoorkomende valkuilen
- De PIT vergeten. Ruwe rendementen rechtstreeks in de copula invoeren in plaats van pseudo-uniforme observaties levert zinloze resultaten op. Transformeer altijd eerst naar uniforme marginalen.
- Overfitting met te veel families. Het opnemen van elke mogelijke bivariate familie in de selectieset kan tot overfitting leiden, vooral bij korte steekproeven. Gebruik BIC voor modelselectie en overweeg beperking tot 4-5 families.
- Seriële afhankelijkheid negeren. Copula's modelleren cross-sectionele afhankelijkheid op één enkel tijdstip. Als je de GARCH-stap overslaat en autogecorreleerde rendementen in de copula invoert, wordt de geschatte afhankelijkheid vervuild door seriële effecten.
- Statische copula's in dynamische markten. Een copula gefit op bullmarktdata uit 2021 zal slecht gekalibreerd zijn voor een crash in 2022. Gebruik altijd rollende of uitbreidende vensters.
Conclusie
Copulamodellen — met name vine-copula's — bieden een wiskundig rigoureus raamwerk voor het modelleren van het gezamenlijke risico van cryptoportefeuilles dat veel verder gaat dan wat lineaire correlatie kan vastleggen. De belangrijkste voordelen:
- Gescheiden marginale en afhankelijkheidsmodellering via de stelling van Sklar
- Flexibele staartafhankelijkheid door geschikte copulafamilie-selectie (Clayton voor crashbesmetting, Gumbel voor gezamenlijke rallybewegingen, t-copula voor symmetrische staarten)
- Hoogdimensionale schaalbaarheid door vine-copuladecompositie, waarbij elk paar activa zijn eigen bivariate copula krijgt
- Nauwkeurige VaR/CVaR-schatting die rekening houdt met niet-lineaire, asymmetrische afhankelijkheid — cruciaal voor risicobeheer in een markt waar "alles crasht samen" de norm is, niet de uitzondering
De GARCH-EVT-copula-pijplijn is nu de standaardaanpak bij kwantitatieve hedgefondsen en op crypto gerichte risicodesks. Met bibliotheken zoals pyvinecopulib is de implementatiedrempel laag genoeg dat elke systematische trader copula-gebaseerde risicomodellering kan integreren in zijn portefeuillebeheerworkflow.
De code in dit artikel biedt een werkend startpunt. Voor productiegebruik zou je correcte kruisvalidatie voor de GARCH-ordeselectie toevoegen, geavanceerdere marginale modellen (bijv. EGARCH met hefboomeffecten, of realized-volatility-maatstaven met intraday-data), en stresstesten onder hypothetische copulaparameters gekalibreerd op historische crisisepisodes.
Referenties
- Sklar, A. (1959). Fonctions de repartition a n dimensions et leurs marges. Publications de l'Institut de Statistique de l'Universite de Paris, 8, 229-231.
- Joe, H. (2014). Dependence Modeling with Copulas. Chapman and Hall/CRC.
- Aas, K., Czado, C., Frigessi, A., & Bakken, H. (2009). Pair-copula constructions of multiple dependence. Insurance: Mathematics and Economics, 44(2), 182-198.
- Jeleskovic, V. & Bruhn, L. (2024). Cryptocurrency portfolio optimization: Utilizing a GARCH-Copula model within the Markowitz framework. Journal of Corporate Accounting & Finance.
- Nagler, T. & Vatter, T. (2023). pyvinecopulib: A Python library for vine copula models. GitHub.
- Tiwari, A. K., et al. (2020). Modeling risk dependence and portfolio VaR forecast through vine copula for cryptocurrencies. PLOS ONE, 15(1), e0242102.
Auteurs
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.