← Quay lại danh sách bài viết
March 30, 2026
5 phút đọc

Mô Hình Copula cho Mô Hình Hóa Rủi Ro Kết Hợp trong Danh Mục Crypto

Mô Hình Copula cho Mô Hình Hóa Rủi Ro Kết Hợp trong Danh Mục Crypto
#rủi ro
#copula
#danh mục
#phụ thuộc-đuôi
#VaR

Mô hình copula — phân phối rủi ro kết hợp

Tương quan là công cụ đầu tiên mà hầu hết các nhà quản lý danh mục sử dụng khi đánh giá sự đa dạng hóa. Nhưng trong thị trường crypto, tương quan lại cực kỳ dễ gây nhầm lẫn. Hai token có thể có hệ số tương quan Pearson là 0,3 trong thời kỳ thị trường bình lặng, rồi tăng vọt lên 0,95 trong một đợt sụp đổ. Tương quan tuyến tính giả định phân phối elip — một giả định sụp đổ trước đuôi nặng và cấu trúc phụ thuộc bất đối xứng vốn có của lợi suất tiền điện tử.

Mô hình copula giải quyết vấn đề này bằng cách tách biệt hành vi biên (cách mỗi tài sản hoạt động riêng lẻ) khỏi cấu trúc phụ thuộc (cách các tài sản vận động cùng nhau). Sự tách biệt này, bắt nguồn từ định lý Sklar, mang lại cho chúng ta một khung linh hoạt để mô hình hóa toàn bộ phân phối kết hợp của lợi suất danh mục — bao gồm cả đuôi, nơi rủi ro thực sự tồn tại.

Tại Sao Tương Quan Tuyến Tính Thất Bại với Crypto

Hãy xem xét một danh mục gồm BTC, ETH, SOL và AVAX. Trong đợt sụp đổ Terra/Luna vào tháng 5 năm 2022, các hệ số tương quan giữa các tài sản này hội tụ về 1,0, đúng vào lúc cần đa dạng hóa nhất. Một bộ tối ưu hóa trung bình-phương sai giả định tương quan ổn định sẽ đánh giá thấp đáng kể rủi ro danh mục.

Các vấn đề cốt lõi với tương quan Pearson cho crypto:

  1. Phân phối không elip. Lợi suất crypto thể hiện độ nghiêng và độ nhọn đáng kể. Lợi suất hàng ngày của BTC thường xuyên cho thấy các giá trị kurtosis trên 10 (phân phối chuẩn: 3).
  2. Phụ thuộc bất đối xứng. Các tài sản có xu hướng tương quan mạnh hơn trong các đợt giảm so với các đợt tăng. Hiện tượng "phá vỡ tương quan" này được ghi nhận rõ ràng trong thị trường cổ phiếu và còn rõ ràng hơn trong crypto.
  3. Phụ thuộc đuôi. Xác suất hai tài sản đồng thời chịu tổn thất cực đoan không được nắm bắt bởi tương quan tuyến tính. Bạn có thể có hai tài sản có tương quan giống hệt nhau nhưng phụ thuộc đuôi hoàn toàn khác nhau.

Định Lý Sklar: Nền Tảng

Định lý Sklar (1959) phát biểu rằng bất kỳ phân phối kết hợp đa chiều nào F(x1,x2,,xd)F(x_1, x_2, \ldots, x_d) đều có thể được phân tách thành:

F(x1,x2,,xd)=C(F1(x1),F2(x2),,Fd(xd))F(x_1, x_2, \ldots, x_d) = C\bigl(F_1(x_1), F_2(x_2), \ldots, F_d(x_d)\bigr)

trong đó FiF_i là các hàm phân phối biên và C:[0,1]d[0,1]C: [0,1]^d \to [0,1]copula — một hàm mã hóa toàn bộ cấu trúc phụ thuộc giữa các biến.

Ngược lại, nếu các biên là liên tục, copula CC là duy nhất.

Sự phân tách này rất mạnh mẽ vì nó cho phép chúng ta:

  • Mô hình hóa phân phối biên của từng tài sản riêng biệt (sử dụng GARCH, EVT, hoặc bất kỳ phân phối nào phù hợp)
  • Mô hình hóa cấu trúc phụ thuộc một cách độc lập thông qua copula
  • Kết hợp chúng để có được phân phối kết hợp đầy đủ

Mật độ của phân phối kết hợp phân tích như:

f(x1,,xd)=c(F1(x1),,Fd(xd))i=1dfi(xi)f(x_1, \ldots, x_d) = c\bigl(F_1(x_1), \ldots, F_d(x_d)\bigr) \cdot \prod_{i=1}^{d} f_i(x_i)

trong đó cc là mật độ copula và fif_i là các mật độ biên.

Các Họ Copula và Tính Chất của Chúng

So sánh phụ thuộc đuôi giữa các họ copula

Copula Gaussian

Copula Gaussian được tham số hóa bởi ma trận tương quan Σ\Sigma:

CΣGauss(u1,,ud)=ΦΣ(Φ1(u1),,Φ1(ud))C_{\Sigma}^{\text{Gauss}}(u_1, \ldots, u_d) = \Phi_{\Sigma}\bigl(\Phi^{-1}(u_1), \ldots, \Phi^{-1}(u_d)\bigr)

trong đó ΦΣ\Phi_{\Sigma} là CDF chuẩn đa biến và Φ1\Phi^{-1} là hàm phân vị chuẩn đơn biến.

Phụ thuộc đuôi: λL=λU=0\lambda_L = \lambda_U = 0 (với ρ<1\rho < 1).

Copula Gaussian có phụ thuộc đuôi bằng không — nó hệ thống đánh giá thấp xác suất các sự kiện cực đoan kết hợp. Đây là yếu tố chính dẫn đến định giá sai CDO trước năm 2008, và nó cũng nguy hiểm tương tự cho mô hình hóa rủi ro crypto.

Copula t của Student

Copula t giới thiệu phụ thuộc đuôi đối xứng thông qua tham số bậc tự do ν\nu:

Cν,Σt(u1,,ud)=tν,Σ(tν1(u1),,tν1(ud))C_{\nu, \Sigma}^{t}(u_1, \ldots, u_d) = t_{\nu, \Sigma}\bigl(t_{\nu}^{-1}(u_1), \ldots, t_{\nu}^{-1}(u_d)\bigr)

Phụ thuộc đuôi:

λL=λU=2tν+1((ν+1)(1ρ)1+ρ)\lambda_L = \lambda_U = 2 \cdot t_{\nu+1}\left(-\sqrt{\frac{(\nu+1)(1-\rho)}{1+\rho}}\right)

Với ν=4\nu = 4ρ=0.5\rho = 0.5, giá trị này cho λ0.18\lambda \approx 0.18 — xác suất 18% rằng cả hai tài sản đều ở phân vị tệ nhất của chúng đồng thời. ν\nu thấp hơn (đuôi nặng hơn) tăng xác suất này. Thị trường crypto, với lợi suất đuôi béo, thường yêu cầu ν\nu trong khoảng 3-8.

Copula t là một cải tiến đáng kể so với Gaussian, nhưng nó áp đặt phụ thuộc đuôi đối xứng (λL=λU\lambda_L = \lambda_U). Trên thực tế, các tài sản crypto thường thể hiện phụ thuộc đuôi dưới mạnh hơn (sụp đổ cùng nhau) so với phụ thuộc đuôi trên (tăng cùng nhau).

Copula Clayton

Copula Clayton nắm bắt phụ thuộc đuôi dưới — chính xác là loại hành vi phân cụm sụp đổ bất đối xứng mà chúng ta thấy trong crypto:

CθClayton(u1,u2)=(u1θ+u2θ1)1/θ,θ>0C_{\theta}^{\text{Clayton}}(u_1, u_2) = \left(u_1^{-\theta} + u_2^{-\theta} - 1\right)^{-1/\theta}, \quad \theta > 0

Phụ thuộc đuôi: λL=21/θ\lambda_L = 2^{-1/\theta}, λU=0\lambda_U = 0.

Khi θ\theta tăng, phụ thuộc đuôi dưới tăng mạnh. Với θ=2\theta = 2, λL0.71\lambda_L \approx 0.71 — xác suất rất cao xảy ra tổn thất cực đoan kết hợp.

Copula Gumbel

Copula Gumbel là hình ảnh phản chiếu — nó nắm bắt phụ thuộc đuôi trên:

CθGumbel(u1,u2)=exp([(lnu1)θ+(lnu2)θ]1/θ),θ1C_{\theta}^{\text{Gumbel}}(u_1, u_2) = \exp\left(-\left[(-\ln u_1)^{\theta} + (-\ln u_2)^{\theta}\right]^{1/\theta}\right), \quad \theta \geq 1

Phụ thuộc đuôi: λL=0\lambda_L = 0, λU=221/θ\lambda_U = 2 - 2^{1/\theta}.

Copula Frank

Copula Frank có phụ thuộc đuôi bằng không ở cả hai đuôi (λL=λU=0\lambda_L = \lambda_U = 0), khiến nó phù hợp để mô hình hóa phụ thuộc trong phần thân của phân phối mà không có tác động đuôi:

CθFrank(u1,u2)=1θln(1+(eθu11)(eθu21)eθ1)C_{\theta}^{\text{Frank}}(u_1, u_2) = -\frac{1}{\theta}\ln\left(1 + \frac{(e^{-\theta u_1}-1)(e^{-\theta u_2}-1)}{e^{-\theta}-1}\right)

Chọn Copula Phù Hợp cho Crypto

Đối với danh mục crypto, bằng chứng thực nghiệm chỉ ra:

  • Clayton hoặc Gumbel xoay (survival Gumbel) cho phụ thuộc đuôi dưới — nắm bắt lây lan sụp đổ
  • Copula t như một lựa chọn đa năng mạnh mẽ khi phụ thuộc đuôi đối xứng là chấp nhận được
  • Copula Joe để nắm bắt phụ thuộc đuôi trên mạnh trong các giai đoạn tăng giá

Nghiên cứu của Bruhn và Jeleskovic (2024) cho thấy các mô hình GARCH-copula, đặc biệt là những mô hình sử dụng biên t của Student với copula t, liên tục vượt trội so với phương pháp trung bình-phương sai và CVaR lịch sử trong các điều kiện thị trường giảm (2022), phục hồi (2023) và ổn định (2024) trong crypto.

Lời Nguyền Chiều: Nhập Vine Copula

Cấu trúc cây vine copula cho danh mục crypto

Các copula đa biến tiêu chuẩn (Gaussian, copula t) mở rộng đến số chiều cao nhưng áp đặt các giả định hạn chế. Các copula Archimedean (Clayton, Gumbel, Frank) vốn là hai biến — mở rộng chúng sang d>2d > 2 chiều đòi hỏi tất cả các cặp chia sẻ cùng tham số phụ thuộc, điều này không thực tế.

Vine copula giải quyết vấn đề này bằng cách phân tách một copula dd-chiều thành một loạt các copula hai biến được sắp xếp trong một cấu trúc cây. Mỗi cặp biến (có điều kiện trên các biến khác) có họ copula hai biến và tham số riêng của nó.

Xây Dựng Copula Cặp

Đối với mật độ dd-chiều, sự phân tích vine copula là:

f(x1,,xd)=i=1dfi(xi)j=1d1i=1djci,i+ji+1,,i+j1f(x_1, \ldots, x_d) = \prod_{i=1}^{d} f_i(x_i) \cdot \prod_{j=1}^{d-1}\prod_{i=1}^{d-j} c_{i,i+j|i+1,\ldots,i+j-1}

trong đó ci,jSc_{i,j|S} là mật độ copula hai biến cho các biến iijj có điều kiện trên tập SS.

Một vine copula dd-chiều yêu cầu (d2)=d(d1)/2\binom{d}{2} = d(d-1)/2 copula hai biến. Đối với danh mục crypto 10 tài sản, đó là 45 copula cặp — mỗi cái có thể từ một họ khác nhau.

Cấu Trúc Vine: C-Vine, D-Vine, R-Vine

C-vine (Vine chính tắc): Mỗi cây có một nút gốc duy nhất được kết nối với tất cả các nút khác. Tốt nhất khi một biến chiếm ưu thế — ví dụ: BTC là động lực thị trường.

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 (Vine có thể vẽ): Cấu trúc đường dẫn tuần tự. Tốt nhất khi các biến có thứ tự tự nhiên (ví dụ: theo vốn hóa thị trường hoặc lĩnh vực).

R-vine (Vine thông thường): Cấu trúc tổng quát nhất — bất kỳ chuỗi cây hợp lệ nào. R-vine bao hàm cả C-vine và D-vine.

Nghiên cứu về danh mục tiền điện tử cho thấy rằng các cấu trúc D-vine thường tạo ra dự báo VaR vượt trội so với C-vine và R-vine cho tài sản crypto, mặc dù điều này phụ thuộc vào thành phần danh mục cụ thể.

Tại Sao Vine Copula Quan Trọng cho Crypto

Một danh mục gồm 8 tài sản crypto được mô hình hóa với một copula Clayton đơn buộc tất cả 28 cặp chia sẻ cùng θ\theta. Nhưng BTC-ETH có thể có θClayton=3.5\theta_{\text{Clayton}} = 3.5 (phụ thuộc sụp đổ mạnh) trong khi SOL-AVAX có thể có θ=1.2\theta = 1.2 (vừa phải). Vine copula cho phép mỗi cặp thể hiện cấu trúc phụ thuộc riêng của nó:

  • BTC-ETH: copula t (ν=4\nu=4, ρ=0.72\rho=0.72)
  • BTC-SOL: Clayton (θ=2.1\theta=2.1)
  • ETH-AVAX: Frank (θ=5.3\theta=5.3)
  • SOL-DOT | BTC: Gumbel (θ=1.8\theta=1.8)

Sự linh hoạt này rất quan trọng để ước tính rủi ro danh mục chính xác.

Mô Hình Hóa Biên: GARCH-EVT

Trước khi khớp copula, chúng ta cần chuyển đổi chuỗi lợi suất của từng tài sản thành các biến đồng nhất [0,1][0,1] ("biến đổi tích phân xác suất"). Quy trình chuẩn:

  1. Khớp mô hình GARCH với chuỗi lợi suất của từng tài sản để nắm bắt biến động thay đổi theo thời gian
  2. Trích xuất phần dư chuẩn hóa zt=(rtμt)/σtz_t = (r_t - \mu_t) / \sigma_t
  3. Khớp đuôi bằng Lý thuyết Giá trị Cực đoan (EVT) — cụ thể là Phân phối Pareto Tổng quát (GPD) cho đuôi trên và dưới vượt quá ngưỡng (thường là phân vị thứ 5 và 95)
  4. Sử dụng CDF thực nghiệm cho phần thân của phân phối
  5. Áp dụng biến đổi tích phân xác suất để có các quan sát giả đồng nhất ui,t=F^i(zi,t)u_{i,t} = \hat{F}_i(z_{i,t})

Phương pháp GARCH-EVT này thường được gọi là phương pháp "bán tham số". Nó nắm bắt đúng:

  • Cụm biến động (GARCH)
  • Đuôi nặng (GPD từ EVT)
  • Hình dạng tổng thể của phân phối (CDF thực nghiệm cho phần thân)

Đối với tài sản crypto, mô hình EGARCH(1,1) hoặc GJR-GARCH(1,1) với biến động t của Student có xu hướng hoạt động tốt, vì nó nắm bắt phản ứng biến động bất đối xứng (tin xấu làm tăng biến động nhiều hơn tin tốt).

VaR và CVaR Danh Mục với Copula

Value-at-Risk (VaR)

VaR danh mục ở mức độ tin cậy α\alpha là:

VaRα=inf{l:P(Ll)α}\text{VaR}_\alpha = \inf\{ l : P(L \leq l) \geq \alpha \}

trong đó LL là tổn thất danh mục. Với copula, chúng ta ước tính VaR qua Monte Carlo:

  1. Mô phỏng NN mẫu từ vine copula đã khớp (trong không gian đồng nhất)
  2. Chuyển đổi ngược lại thành không gian lợi suất bằng CDF biên nghịch đảo
  3. Tính lợi suất danh mục: rp=iwirir_p = \sum_i w_i \cdot r_i
  4. VaR là phân vị α\alpha của phân phối tổn thất danh mục mô phỏng

Conditional Value-at-Risk (CVaR / Expected Shortfall)

CVaR là tổn thất kỳ vọng khi tổn thất vượt quá VaR:

CVaRα=E[LLVaRα]=11αα1VaRudu\text{CVaR}_\alpha = E[L \mid L \geq \text{VaR}_\alpha] = \frac{1}{1-\alpha}\int_{\alpha}^{1}\text{VaR}_u\, du

CVaR nhất quán (thỏa mãn tính phụ gia), khiến nó vượt trội VaR cho tối ưu hóa danh mục. Ước tính Monte Carlo đơn giản — lấy trung bình các tổn thất vượt quá VaR.

Tại Sao Rủi Ro Dựa trên Copula Vượt Trội Rủi Ro Dựa trên Tương Quan

Xem xét hai danh mục có các hệ số tương quan cặp giống nhau là 0,5:

  • Danh mục A: Phụ thuộc copula Gaussian (không có phụ thuộc đuôi)
  • Danh mục B: Phụ thuộc copula Clayton (θ=2\theta = 2, λL=0.71\lambda_L = 0.71)

Ở mức độ tin cậy 99%, Danh mục B sẽ có VaR và CVaR cao hơn đáng kể vì copula Clayton mô hình hóa chính xác xu hướng các tài sản sụp đổ cùng nhau. Copula Gaussian đánh giá thấp rủi ro này bằng cách giả định rằng các chuyển động cùng cực đoan là cực kỳ hiếm.

Trong các nghiên cứu thực nghiệm về danh mục crypto, sự chênh lệch về CVaR 99% giữa các mô hình Gaussian và vine copula có thể vượt quá 30-40%, có nghĩa là các mô hình dựa trên tương quan có thể đánh giá thấp rủi ro đuôi đến một phần ba hoặc hơn.

Triển Khai: Python với pyvinecopulib

Đây là quy trình hoàn chỉnh để khớp vine copula với lợi suất crypto và ước tính VaR/CVaR danh mục.

Bước 1: Chuẩn Bị Dữ Liệu và Khớp Biên

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

Bước 2: Biến Đổi Tích Phân Xác Suất

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

Bước 3: Khớp 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})")

Bước 4: VaR và CVaR Monte Carlo

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

Bước 5: Phân Tích Phụ Thuộc Đuôi

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

Đầu ra thông thường cho danh mục crypto có thể trông như thế này:

Pair Family λL\lambda_L λU\lambda_U
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

Lưu ý cách mỗi cặp có thể có cấu trúc phụ thuộc hoàn toàn khác nhau. BTC-SOL cho thấy phụ thuộc đuôi dưới mạnh (Clayton) với phụ thuộc đuôi trên bằng không — chúng sụp đổ cùng nhau nhưng không nhất thiết tăng cùng nhau. BTC-MATIC không có phụ thuộc đuôi nào cả (Frank), cho thấy một số lợi ích đa dạng hóa ngay cả trong các trường hợp cực đoan.

Kiểm Tra Lại Mô Hình VaR Copula

Một mô hình VaR chỉ hữu ích khi được hiệu chỉnh tốt. Kiểm tra lại tiêu chuẩn tính toán vi phạm VaR — những ngày khi tổn thất thực tế vượt quá VaR dự đoán — và kiểm tra xem tỷ lệ vi phạm có khớp với tỷ lệ kỳ vọng không.

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

Một mô hình VaR 99% được hiệu chỉnh tốt nên có tỷ lệ vi phạm gần 1%. Nếu tỷ lệ cao hơn đáng kể, mô hình đánh giá thấp rủi ro. Nếu thấp hơn đáng kể, mô hình quá thận trọng.

Những Cân Nhắc Thực Tế

Chi Phí Tính Toán

Khớp vine copula là O(d2n)O(d^2 \cdot n) mỗi cấp độ cây. Đối với danh mục 10 tài sản với cửa sổ cuộn 500 ngày, một kiểm tra lại đầy đủ với 50.000 mô phỏng Monte Carlo mỗi bước có thể mất hàng giờ. Các chiến lược để quản lý điều này:

  • Vine cắt ngắn: Đặt trunc_lvl=3 hoặc trunc_lvl=4 — các cây cao hơn nắm bắt các phụ thuộc điều kiện yếu hơn đóng góp ít hơn vào rủi ro
  • Giảm số lượng mô phỏng: 10.000-20.000 mô phỏng thường đủ cho VaR 99%
  • Tính toán song song: Các lần khớp GARCH cho mỗi tài sản là độc lập và có thể được song song hóa
  • Bộ nhớ đệm mô hình: Tái khớp copula hàng tuần thay vì hàng ngày, chỉ cập nhật dự báo GARCH

Nhận Thức về Chế Độ

Thị trường crypto thể hiện các chế độ riêng biệt (tăng, giảm, đi ngang, sự kiện biến động cao). Một vine copula duy nhất được khớp trên toàn bộ mẫu có thể không nắm bắt được sự phụ thuộc phụ thuộc vào chế độ. Hãy xem xét:

  • Cửa sổ cuộn 250-500 ngày
  • Copula chuyển đổi chế độ trong đó các tham số copula phụ thuộc vào trạng thái Markov ẩn
  • Quan sát có trọng số theo hàm mũ cho trọng số nhiều hơn cho dữ liệu gần đây

Những Bẫy Thường Gặp

  1. Quên PIT. Đưa lợi suất thô trực tiếp vào copula thay vì các quan sát giả đồng nhất sẽ tạo ra kết quả vô nghĩa. Luôn chuyển đổi sang biên đồng nhất trước.
  2. Khớp quá mức với quá nhiều họ. Bao gồm mọi họ hai biến có thể trong tập lựa chọn có thể dẫn đến khớp quá mức, đặc biệt với các mẫu ngắn. Sử dụng BIC để lựa chọn mô hình và xem xét giới hạn ở 4-5 họ.
  3. Bỏ qua phụ thuộc tuần tự. Copula mô hình hóa phụ thuộc mặt cắt ngang tại một thời điểm. Nếu bạn bỏ qua bước GARCH và đưa lợi suất có tự tương quan vào copula, phụ thuộc ước tính sẽ bị nhiễm bởi các hiệu ứng tuần tự.
  4. Copula tĩnh trong thị trường động. Một copula được khớp trên dữ liệu thị trường tăng năm 2021 sẽ được hiệu chỉnh kém cho đợt sụp đổ năm 2022. Luôn sử dụng cửa sổ cuộn hoặc mở rộng.

Kết Luận

Các mô hình copula — đặc biệt là vine copula — cung cấp một khung toán học nghiêm ngặt để mô hình hóa rủi ro kết hợp của danh mục crypto vượt xa những gì tương quan tuyến tính có thể nắm bắt. Các ưu điểm chính:

  • Mô hình hóa biên và phụ thuộc tách biệt qua định lý Sklar
  • Phụ thuộc đuôi linh hoạt thông qua lựa chọn họ copula phù hợp (Clayton cho lây lan sụp đổ, Gumbel cho đồng vận động tăng giá, copula t cho đuôi đối xứng)
  • Khả năng mở rộng chiều cao thông qua phân tách vine copula, trong đó mỗi cặp tài sản có copula hai biến riêng
  • Ước tính VaR/CVaR chính xác tính đến sự phụ thuộc phi tuyến, bất đối xứng — quan trọng cho quản lý rủi ro trong thị trường mà "mọi thứ sụp đổ cùng nhau" là quy tắc, không phải ngoại lệ

Quy trình GARCH-EVT-Copula hiện là phương pháp tiêu chuẩn tại các quỹ phòng hộ định lượng và bàn rủi ro tập trung vào crypto. Với các thư viện như pyvinecopulib, rào cản triển khai đủ thấp để bất kỳ nhà giao dịch hệ thống nào cũng có thể tích hợp mô hình rủi ro dựa trên copula vào quy trình quản lý danh mục của họ.

Mã trong bài viết này cung cấp điểm khởi đầu hoạt động. Để sử dụng trong sản xuất, bạn cần thêm xác thực chéo đúng đắn cho việc lựa chọn bậc GARCH, các mô hình biên tinh vi hơn (ví dụ: EGARCH với hiệu ứng đòn bẩy, hoặc các đo lường biến động thực nghiệm sử dụng dữ liệu trong ngày), và kiểm tra stress dưới các tham số copula giả thuyết được hiệu chỉnh theo các đợt khủng hoảng lịch sử.


Tài Liệu Tham Khảo

  • 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.
Tuyên bố miễn trừ trách nhiệm: Thông tin được cung cấp trong bài viết này chỉ nhằm mục đích giáo dục và thông tin, không cấu thành lời khuyên về tài chính, đầu tư hoặc giao dịch. Giao dịch tiền mã hóa tiềm ẩn rủi ro thua lỗ đáng kể.

Tác Giả

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

Đi Trước Thị Trường

Đăng ký nhận bản tin của chúng tôi để có những thông tin chuyên sâu độc quyền về AI trading, phân tích thị trường và các cập nhật nền tảng.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất kỳ lúc nào.