क्रिप्टो पोर्टफोलियो में संयुक्त जोखिम मॉडलिंग के लिए कोपुला मॉडल

सहसंबंध वह पहला उपकरण है जिसकी ओर अधिकांश पोर्टफोलियो प्रबंधक विविधीकरण का आकलन करते समय रुख करते हैं। लेकिन क्रिप्टो बाज़ारों में, सहसंबंध खतरनाक रूप से भ्रामक होता है। शांत बाज़ारों के दौरान दो टोकन का पियर्सन सहसंबंध 0.3 दिख सकता है, फिर क्रैश के दौरान यह 0.95 तक उछल सकता है। रैखिक सहसंबंध अण्डाकार (elliptical) वितरणों को मानता है — एक धारणा जो क्रिप्टोकरेंसी रिटर्न में व्याप्त भारी टेल और असममित निर्भरता संरचनाओं के तहत ध्वस्त हो जाती है।
कोपुला मॉडल इसे मार्जिनल व्यवहार (प्रत्येक एसेट व्यक्तिगत रूप से कैसा व्यवहार करता है) को निर्भरता संरचना (एसेट एक साथ कैसे चलते हैं) से अलग करके हल करते हैं। स्क्लार के प्रमेय में निहित यह पृथक्करण, पोर्टफोलियो रिटर्न के पूर्ण संयुक्त वितरण को मॉडल करने के लिए एक लचीला ढांचा देता है — जिसमें वे टेल भी शामिल हैं जहां जोखिम वास्तव में रहता है।
रैखिक सहसंबंध क्रिप्टो के लिए क्यों विफल होता है
BTC, ETH, SOL, और AVAX के पोर्टफोलियो पर विचार करें। मई 2022 में Terra/Luna के पतन के दौरान, इन एसेट के बीच सहसंबंध 1.0 की ओर अभिसरित हुए, ठीक तब जब विविधीकरण की सबसे अधिक आवश्यकता थी। एक मीन-वेरिएंस ऑप्टिमाइज़र जिसने स्थिर सहसंबंधों को माना था, पोर्टफोलियो जोखिम को नाटकीय रूप से कम आंकता।
क्रिप्टो के लिए पियर्सन सहसंबंध की मूल समस्याएं:
- गैर-अण्डाकार वितरण। क्रिप्टो रिटर्न महत्वपूर्ण स्क्यूनेस और कर्टोसिस प्रदर्शित करते हैं। BTC के दैनिक रिटर्न नियमित रूप से 10 से ऊपर कर्टोसिस मान दिखाते हैं (सामान्य वितरण: 3)।
- असममित निर्भरता। एसेट रैली की तुलना में गिरावट के दौरान अधिक सहसंबद्ध होते हैं। यह "सहसंबंध टूटना" घटना इक्विटी बाज़ारों में अच्छी तरह प्रलेखित है और क्रिप्टो में और भी अधिक स्पष्ट है।
- टेल डिपेंडेंस। दो एसेट के एक साथ चरम नुकसान अनुभव करने की संभावना रैखिक सहसंबंध द्वारा कैप्चर नहीं होती। समान सहसंबंध वाले लेकिन बहुत भिन्न टेल डिपेंडेंस वाले दो एसेट हो सकते हैं।
स्क्लार का प्रमेय: नींव
स्क्लार का प्रमेय (1959) बताता है कि किसी भी बहुचर संयुक्त वितरण को इस प्रकार विघटित किया जा सकता है:
जहां मार्जिनल वितरण फलन हैं और कोपुला है — एक फलन जो चरों के बीच संपूर्ण निर्भरता संरचना को एनकोड करता है।
इसके विपरीत, यदि मार्जिनल्स सतत हैं, तो कोपुला अद्वितीय है।
यह विघटन शक्तिशाली है क्योंकि यह हमें अनुमति देता है:
- प्रत्येक एसेट के मार्जिनल वितरण को अलग से मॉडल करना (GARCH, EVT, या किसी भी उपयुक्त वितरण का उपयोग करके)
- कोपुला के माध्यम से निर्भरता संरचना को स्वतंत्र रूप से मॉडल करना
- पूर्ण संयुक्त वितरण प्राप्त करने के लिए उन्हें संयोजित करना
संयुक्त वितरण की डेंसिटी इस प्रकार गुणनखंडित होती है:
जहां कोपुला डेंसिटी है और मार्जिनल डेंसिटी हैं।
कोपुला परिवार और उनके गुण

गॉसियन कोपुला
गॉसियन कोपुला एक सहसंबंध मैट्रिक्स द्वारा पैरामीटराइज़ किया जाता है:
जहां बहुचर सामान्य CDF है और एकचर सामान्य क्वांटाइल फलन है।
टेल डिपेंडेंस: (जब )।
गॉसियन कोपुला में शून्य टेल डिपेंडेंस होती है — यह संयुक्त चरम घटनाओं की संभावना को व्यवस्थित रूप से कम आंकता है। यह 2008 से पहले CDO की गलत कीमत निर्धारण में एक प्रमुख कारक था, और यह क्रिप्टो जोखिम मॉडलिंग के लिए समान रूप से खतरनाक है।
स्टूडेंट का t-कोपुला
t-कोपुला डिग्री-ऑफ-फ्रीडम पैरामीटर के माध्यम से सममित टेल डिपेंडेंस प्रस्तुत करता है:
टेल डिपेंडेंस:
और के लिए, यह देता है — दोनों एसेट के एक साथ अपने सबसे खराब क्वांटाइल में होने की 18% संभावना। कम (भारी टेल) इस संभावना को बढ़ाता है। क्रिप्टो बाज़ार, अपने मोटे-टेल रिटर्न के साथ, आमतौर पर को 3-8 की सीमा में आवश्यक करते हैं।
t-कोपुला गॉसियन पर एक महत्वपूर्ण सुधार है, लेकिन यह सममित टेल डिपेंडेंस () लागू करता है। व्यवहार में, क्रिप्टो एसेट अक्सर ऊपरी-टेल डिपेंडेंस (साथ रैली) की तुलना में अधिक मजबूत निचले-टेल डिपेंडेंस (साथ क्रैश) प्रदर्शित करते हैं।
क्लेटन कोपुला
क्लेटन कोपुला निचले टेल डिपेंडेंस को कैप्चर करता है — ठीक उसी प्रकार का असममित क्रैश-क्लस्टरिंग व्यवहार जो हम क्रिप्टो में देखते हैं:
टेल डिपेंडेंस: , ।
जैसे-जैसे बढ़ता है, निचला टेल डिपेंडेंस मजबूत होता है। के लिए, — संयुक्त चरम नुकसान की बहुत उच्च संभावना।
गम्बेल कोपुला
गम्बेल कोपुला दर्पण छवि है — यह ऊपरी टेल डिपेंडेंस को कैप्चर करता है:
टेल डिपेंडेंस: , ।
फ्रैंक कोपुला
फ्रैंक कोपुला में दोनों टेल में शून्य टेल डिपेंडेंस होती है (), जो इसे बिना टेल प्रभाव के वितरण के मुख्य भाग में निर्भरता को मॉडल करने के लिए उपयुक्त बनाता है:
क्रिप्टो के लिए सही कोपुला चुनना
क्रिप्टो पोर्टफोलियो के लिए, अनुभवजन्य साक्ष्य इंगित करता है:
- निचले टेल डिपेंडेंस के लिए क्लेटन या रोटेटेड गम्बेल (सर्वाइवल गम्बेल) — क्रैश संक्रमण को कैप्चर करना
- t-कोपुला एक मजबूत सामान्य-उद्देश्य विकल्प के रूप में जब सममित टेल डिपेंडेंस स्वीकार्य हो
- रैली चरणों में मजबूत ऊपरी टेल डिपेंडेंस को कैप्चर करने के लिए जो कोपुला
Bruhn और Jeleskovic (2024) के शोध में पाया गया कि GARCH-कोपुला मॉडल, विशेष रूप से वे जो स्टूडेंट के t मार्जिनल्स को t-कोपुला के साथ उपयोग करते हैं, क्रिप्टो में गिरावट (2022), रिकवरी (2023), और स्थिरता (2024) बाज़ार स्थितियों में लगातार मीन-वेरिएंस और ऐतिहासिक CVaR दृष्टिकोणों से बेहतर प्रदर्शन करते हैं।
आयामीता का अभिशाप: वाइन कोपुला का प्रवेश

मानक बहुचर कोपुला (गॉसियन, t-कोपुला) उच्च आयामों तक स्केल करते हैं लेकिन प्रतिबंधात्मक धारणाएं लागू करते हैं। आर्किमिडियन कोपुला (क्लेटन, गम्बेल, फ्रैंक) स्वाभाविक रूप से द्विचर होते हैं — उन्हें आयामों तक विस्तारित करने के लिए आवश्यक है कि सभी जोड़े समान निर्भरता पैरामीटर साझा करें, जो अवास्तविक है।
वाइन कोपुला एक -आयामी कोपुला को एक ट्री संरचना में व्यवस्थित द्विचर कोपुला के एक झरने में विघटित करके इसे हल करते हैं। चरों की प्रत्येक जोड़ी (अन्य पर सशर्त) को अपना स्वयं का द्विचर कोपुला परिवार और पैरामीटर मिलता है।
पेयर-कोपुला निर्माण
-आयामी डेंसिटी के लिए, वाइन कोपुला गुणनखंडन है:
जहां चरों और के लिए सेट पर सशर्त एक द्विचर कोपुला डेंसिटी है।
एक -आयामी वाइन कोपुला को द्विचर कोपुला की आवश्यकता होती है। 10-एसेट क्रिप्टो पोर्टफोलियो के लिए, यह 45 पेयर कोपुला हैं — प्रत्येक संभावित रूप से एक अलग परिवार से।
वाइन संरचनाएं: C-वाइन, D-वाइन, R-वाइन
C-वाइन (कैनोनिकल वाइन): प्रत्येक ट्री में एक एकल रूट नोड होता है जो अन्य सभी नोड्स से जुड़ा होता है। सबसे अच्छा तब जब एक चर हावी होता है — जैसे बाज़ार चालक के रूप में BTC।
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-वाइन (ड्रॉएबल वाइन): एक अनुक्रमिक पथ संरचना। सबसे अच्छा तब जब चरों का एक प्राकृतिक क्रम होता है (जैसे मार्केट कैप या सेक्टर द्वारा)।
R-वाइन (रेगुलर वाइन): सबसे सामान्य संरचना — कोई भी वैध ट्री अनुक्रम। R-वाइन दोनों C-वाइन और D-वाइन को समाहित करता है।
क्रिप्टोकरेंसी पोर्टफोलियो पर शोध बताता है कि D-वाइन संरचनाएं अक्सर क्रिप्टो एसेट के लिए C-वाइन और R-वाइन की तुलना में बेहतर VaR पूर्वानुमान उत्पन्न करती हैं, हालांकि यह विशिष्ट पोर्टफोलियो संरचना पर निर्भर करता है।
वाइन कोपुला क्रिप्टो के लिए क्यों महत्वपूर्ण हैं
एक ही क्लेटन कोपुला के साथ मॉडल किए गए 8 क्रिप्टो एसेट के पोर्टफोलियो में सभी 28 जोड़ों को समान साझा करने के लिए मजबूर किया जाता है। लेकिन BTC-ETH में (मजबूत क्रैश निर्भरता) हो सकता है जबकि SOL-AVAX में (मध्यम) हो सकता है। वाइन कोपुला प्रत्येक जोड़ी को अपनी निर्भरता संरचना व्यक्त करने देते हैं:
- BTC-ETH: t-कोपुला (, )
- BTC-SOL: क्लेटन ()
- ETH-AVAX: फ्रैंक ()
- SOL-DOT | BTC: गम्बेल ()
यह लचीलापन सटीक पोर्टफोलियो जोखिम अनुमान के लिए महत्वपूर्ण है।
मार्जिनल्स को मॉडल करना: GARCH-EVT
कोपुला को फिट करने से पहले, हमें प्रत्येक एसेट की रिटर्न श्रृंखला को यूनिफॉर्म चरों में बदलने की आवश्यकता है ("प्रोबेबिलिटी इंटीग्रल ट्रांसफॉर्म")। मानक पाइपलाइन:
- समय-परिवर्ती अस्थिरता को कैप्चर करने के लिए प्रत्येक एसेट की रिटर्न श्रृंखला पर GARCH मॉडल फिट करें
- मानकीकृत अवशेष निकालें
- एक्सट्रीम वैल्यू थ्योरी (EVT) का उपयोग करके टेल फिट करें — विशेष रूप से, थ्रेशोल्ड (आमतौर पर 5वें और 95वें प्रतिशतक) से परे ऊपरी और निचली टेल के लिए जनरलाइज्ड पारेटो डिस्ट्रीब्यूशन (GPD)
- वितरण के मुख्य भाग के लिए अनुभवजन्य CDF का उपयोग करें
- छद्म-यूनिफॉर्म अवलोकन प्राप्त करने के लिए प्रोबेबिलिटी इंटीग्रल ट्रांसफॉर्म लागू करें
इस GARCH-EVT दृष्टिकोण को अक्सर "अर्ध-पैरामीट्रिक" विधि कहा जाता है। यह ठीक से कैप्चर करता है:
- अस्थिरता क्लस्टरिंग (GARCH)
- भारी टेल (EVT से GPD)
- वितरण का समग्र आकार (मुख्य भाग के लिए अनुभवजन्य CDF)
क्रिप्टो एसेट के लिए, स्टूडेंट के t इनोवेशन के साथ EGARCH(1,1) या GJR-GARCH(1,1) मॉडल अच्छी तरह काम करता है, क्योंकि यह असममित अस्थिरता प्रतिक्रिया को कैप्चर करता है (बुरी खबर अच्छी खबर की तुलना में अस्थिरता को अधिक बढ़ाती है)।
कोपुला के साथ पोर्टफोलियो VaR और CVaR
वैल्यू-एट-रिस्क (VaR)
विश्वास स्तर पर पोर्टफोलियो VaR है:
जहां पोर्टफोलियो नुकसान है। कोपुला के साथ, हम मॉन्टे कार्लो के माध्यम से VaR का अनुमान लगाते हैं:
- फिट किए गए वाइन कोपुला से नमूनों का अनुकरण करें (यूनिफॉर्म स्पेस में)
- इनवर्स मार्जिनल CDF का उपयोग करके रिटर्न स्पेस में वापस बदलें
- पोर्टफोलियो रिटर्न की गणना करें:
- VaR सिम्युलेटेड पोर्टफोलियो नुकसान वितरण का -क्वांटाइल है
सशर्त वैल्यू-एट-रिस्क (CVaR / एक्सपेक्टेड शॉर्टफॉल)
CVaR अपेक्षित नुकसान है यह देखते हुए कि नुकसान VaR से अधिक है:
CVaR सुसंगत है (सबएडिटिविटी को संतुष्ट करता है), जो इसे पोर्टफोलियो अनुकूलन के लिए VaR से बेहतर बनाता है। मॉन्टे कार्लो अनुमान सीधा है — उन नुकसानों का औसत लें जो VaR से अधिक हैं।
कोपुला-आधारित जोखिम सहसंबंध-आधारित जोखिम से बेहतर क्यों है
समान जोड़ीवार सहसंबंध 0.5 वाले दो पोर्टफोलियो पर विचार करें:
- पोर्टफोलियो A: गॉसियन कोपुला निर्भरता (कोई टेल डिपेंडेंस नहीं)
- पोर्टफोलियो B: क्लेटन कोपुला निर्भरता (, )
99% विश्वास स्तर पर, पोर्टफोलियो B में काफी अधिक VaR और CVaR होगा क्योंकि क्लेटन कोपुला एसेट के एक साथ क्रैश होने की प्रवृत्ति को सही ढंग से मॉडल करता है। गॉसियन कोपुला यह मानकर इस जोखिम को कम आंकता है कि चरम सह-गतियां लुप्तप्राय रूप से दुर्लभ हैं।
क्रिप्टो पोर्टफोलियो पर अनुभवजन्य अध्ययनों में, गॉसियन और वाइन कोपुला मॉडल के बीच 99% CVaR में अंतर 30-40% से अधिक हो सकता है, जिसका अर्थ है कि सहसंबंध-आधारित मॉडल टेल जोखिम को एक तिहाई या उससे अधिक कम आंक सकते हैं।
कार्यान्वयन: pyvinecopulib के साथ Python
क्रिप्टो रिटर्न पर वाइन कोपुला फिट करने और पोर्टफोलियो VaR/CVaR का अनुमान लगाने के लिए यहां एक पूर्ण पाइपलाइन है।
चरण 1: डेटा तैयारी और मार्जिनल फिटिंग
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()
चरण 2: प्रोबेबिलिटी इंटीग्रल ट्रांसफॉर्म
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
])
चरण 3: वाइन कोपुला फिट करें
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})")
चरण 4: मॉन्टे कार्लो VaR और 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")
चरण 5: टेल डिपेंडेंस विश्लेषण
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))
एक क्रिप्टो पोर्टफोलियो के लिए विशिष्ट आउटपुट कुछ इस तरह दिख सकता है:
| 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 |
ध्यान दें कि प्रत्येक जोड़ी में पूरी तरह से अलग निर्भरता संरचना हो सकती है। BTC-SOL शून्य ऊपरी टेल डिपेंडेंस के साथ मजबूत निचली टेल डिपेंडेंस (क्लेटन) दिखाता है — वे साथ क्रैश होते हैं लेकिन जरूरी नहीं कि साथ रैली करें। BTC-MATIC कोई टेल डिपेंडेंस नहीं दिखाता (फ्रैंक), जो चरम स्थितियों में भी कुछ विविधीकरण लाभ का सुझाव देता है।
कोपुला VaR मॉडल का बैकटेस्टिंग
एक VaR मॉडल तभी उपयोगी है जब वह अच्छी तरह कैलिब्रेटेड हो। मानक बैकटेस्ट VaR उल्लंघनों की गणना करता है — वे दिन जब वास्तविक नुकसान अनुमानित VaR से अधिक हुआ — और परीक्षण करता है कि क्या उल्लंघन दर अपेक्षित दर से मेल खाती है।
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
एक अच्छी तरह कैलिब्रेटेड 99% VaR मॉडल की उल्लंघन दर 1% के करीब होनी चाहिए। यदि दर काफी अधिक है, तो मॉडल जोखिम को कम आंकता है। यदि काफी कम है, तो यह बहुत रूढ़िवादी है।
व्यावहारिक विचार
कम्प्यूटेशनल लागत
वाइन कोपुला फिटिंग प्रति ट्री स्तर है। 500-दिन के रोलिंग विंडो वाले 10-एसेट पोर्टफोलियो के लिए, प्रति चरण 50,000 मॉन्टे कार्लो सिमुलेशन के साथ पूर्ण बैकटेस्ट में घंटों लग सकते हैं। इसे प्रबंधित करने की रणनीतियां:
- ट्रंकेटेड वाइन:
trunc_lvl=3याtrunc_lvl=4सेट करें — उच्च ट्री कमजोर सशर्त निर्भरता को कैप्चर करते हैं जो जोखिम में कम योगदान करती हैं - कम सिमुलेशन गणना: 99% VaR के लिए अक्सर 10,000-20,000 सिमुलेशन पर्याप्त होते हैं
- समानांतर गणना: प्रत्येक एसेट के लिए GARCH फिट स्वतंत्र हैं और समानांतर किए जा सकते हैं
- मॉडल कैशिंग: दैनिक के बजाय साप्ताहिक रूप से कोपुला को फिर से फिट करें, केवल GARCH पूर्वानुमानों को अपडेट करते हुए
रेजीम जागरूकता
क्रिप्टो बाज़ार अलग-अलग रेजीम प्रदर्शित करते हैं (बुल, बियर, साइडवेज, उच्च-अस्थिरता घटनाएं)। पूरे नमूने पर फिट किया गया एक ही वाइन कोपुला रेजीम-निर्भर निर्भरता को कैप्चर नहीं कर सकता। विचार करें:
- 250-500 दिनों की रोलिंग विंडो
- रेजीम-स्विचिंग कोपुला जहां कोपुला पैरामीटर एक छिपे हुए मार्कोव स्टेट पर निर्भर करते हैं
- एक्सपोनेंशियली-वेटेड ऑब्जर्वेशन जो हाल के डेटा को अधिक भार देते हैं
सामान्य गलतियां
- PIT को भूलना। छद्म-यूनिफॉर्म अवलोकनों के बजाय सीधे कच्चे रिटर्न को कोपुला में फीड करने से अर्थहीन परिणाम मिलेंगे। हमेशा पहले यूनिफॉर्म मार्जिन में बदलें।
- बहुत अधिक परिवारों के साथ ओवरफिटिंग। चयन सेट में हर संभव द्विचर परिवार को शामिल करने से ओवरफिटिंग हो सकती है, विशेष रूप से छोटे नमूनों के साथ। मॉडल चयन के लिए BIC का उपयोग करें और 4-5 परिवारों तक सीमित करने पर विचार करें।
- सीरियल डिपेंडेंस को नज़रअंदाज़ करना। कोपुला एक ही समय बिंदु पर क्रॉस-सेक्शनल निर्भरता को मॉडल करते हैं। यदि आप GARCH चरण को छोड़ देते हैं और स्वतःसहसंबद्ध रिटर्न को कोपुला में फीड करते हैं, तो अनुमानित निर्भरता सीरियल प्रभावों से दूषित हो जाएगी।
- गतिशील बाज़ारों में स्थैतिक कोपुला। 2021 बुल मार्केट डेटा पर फिट किया गया कोपुला 2022 क्रैश के लिए खराब रूप से कैलिब्रेटेड होगा। हमेशा रोलिंग या विस्तारित विंडो का उपयोग करें।
निष्कर्ष
कोपुला मॉडल — विशेष रूप से वाइन कोपुला — क्रिप्टो पोर्टफोलियो के संयुक्त जोखिम को मॉडल करने के लिए एक गणितीय रूप से कठोर ढांचा प्रदान करते हैं जो रैखिक सहसंबंध की तुलना में बहुत आगे जाता है। मुख्य लाभ:
- स्क्लार के प्रमेय के माध्यम से अलग मार्जिनल और निर्भरता मॉडलिंग
- उपयुक्त कोपुला परिवार चयन के माध्यम से लचीला टेल डिपेंडेंस (क्रैश संक्रमण के लिए क्लेटन, रैली सह-गति के लिए गम्बेल, सममित टेल के लिए t-कोपुला)
- वाइन कोपुला विघटन के माध्यम से उच्च-आयामी स्केलेबिलिटी, जहां एसेट की प्रत्येक जोड़ी को अपना स्वयं का द्विचर कोपुला मिलता है
- सटीक VaR/CVaR अनुमान जो गैर-रैखिक, असममित निर्भरता को ध्यान में रखता है — एक बाज़ार में जोखिम प्रबंधन के लिए महत्वपूर्ण जहां "सब कुछ एक साथ क्रैश होता है" आदर्श है, अपवाद नहीं
GARCH-EVT-कोपुला पाइपलाइन अब क्वांटिटेटिव हेज फंड और क्रिप्टो-केंद्रित जोखिम डेस्क पर मानक दृष्टिकोण है। pyvinecopulib जैसी लाइब्रेरी के साथ, कार्यान्वयन बाधा इतनी कम है कि कोई भी व्यवस्थित ट्रेडर कोपुला-आधारित जोखिम मॉडलिंग को अपने पोर्टफोलियो प्रबंधन वर्कफ़्लो में एकीकृत कर सकता है।
इस लेख में दिया गया कोड एक कार्यशील प्रारंभिक बिंदु प्रदान करता है। उत्पादन उपयोग के लिए, आप GARCH ऑर्डर चयन के लिए उचित क्रॉस-वैलिडेशन, अधिक परिष्कृत मार्जिनल मॉडल (जैसे लीवरेज प्रभावों के साथ EGARCH, या इंट्राडे डेटा का उपयोग करके रियलाइज्ड वोलैटिलिटी माप), और ऐतिहासिक संकट प्रकरणों पर कैलिब्रेटेड काल्पनिक कोपुला पैरामीटर के तहत स्ट्रेस टेस्टिंग जोड़ेंगे।
संदर्भ
- 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.
Authors
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.