copula函數及其Var計算的Python實現


Copula函數思想

Copula函數能夠把隨機變量之間的相關關系與變量的邊際分布分開進行研究,這種思想方法在多元統計分析中非常重要。直觀來看,可以將任意維的聯合分布H(x1,...,xn)=P(X1<=x1,...,Xn<=xn)分成兩步來處理。第一步是,對所有的單隨機變量Xi通過累積分布函數Fi,我們可以得到Ui=Fi(Xi),這是一個均勻隨機變量;第二步是,隨機變量間的關聯可以通過直接連接這些均勻變量的n元Copula函數C(u1,...,un)來描述。

Copula函數是定義域為[0,1]均勻分布的多維聯合分布函數,其核心概念是以Copula函數將多個隨機變量的邊緣分布耦合起來。Copula函數的基本思想就是,通過把邊緣變量轉化為均勻分布變量而不需要考察很多不同的邊緣分布以簡化問題,然后再把相關性定義為一個在均勻分布上的聯合分布。

 

Copula函數種類

常用的Copula函數有高斯Copula函數,Gumbel Copula函數, Clayton Copula函數, Frank Copula函數。

 

在風險管理中,我們常常用Copula函數來估計VAR,其過程如下:

選擇Copula函數,估計參數(詳情可參照Copula理論及其在金融分析中的應用)

第一步:分別選擇能夠較好地描述資產收益邊緣分布Fi和相關結構的Copula函數;

第二步:根據所有的邊緣分布函數F和Copula函數,最大化對數似然函數估計邊緣分布函數Fi和Copula函數的相應參數;

蒙特卡洛模擬估計VAR

第一步:生成兩個獨立的服從(0,1)均勻分布的隨機數u和w,u即為要模擬的第一個偽隨機數,令Cu(v)=w,通過Cu(v)的逆函數可以計算得到另一個偽隨機數v=Cu^{-1}(w),從而得到符合Copula函數的隨機數對(u, v);

第二步:通過隨機數(u, v)和邊緣分布函數累計概率函數的逆函數得到各資產收益率的模擬序列;

第三步:根據各資產權重得到組合收益序列,取q分位數作為VAR的估計值。

 

Copula函數計算Var的Python實現

在這里我們使用Python的pycopula包來實現

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
from pycopula.copula import ArchimedeanCopula
from pycopula.visualization import pdf_2d, cdf_2d
from scipy import stats

# 讀取facebook、apple公司14-19年收盤數據,計算日收益率
data_fb = pd.read_csv('FB.csv', header=0, index_col=0, engine='python')
data_apl = pd.read_csv('AAPL.csv', header=0, index_col=0, engine='python')
data = np.array([data_fb['close'].pct_change().dropna(), 
                 data_apl['close'].pct_change().dropna()]).T 

# 使用t分布擬合其分布
t = stats.t
dt1 = t.fit(data[:, 0])
dt2 = t.fit(data[:, 1])

分布如下圖所示

# 擬合Copula函數clayton,由於全部擬合邊緣t分布參數不理想,這里直接采用t分布之前擬合的自由度參數,只優化loc和scale以及clayton函數的theta
paramX1 = {'df': 3.34, 'loc': None, 'scale': None}
paramX2 = {'df': 3.32, 'loc': None, 'scale': None}
hyperParams = [paramX1, paramX2]
param = clayton.fit(data, method='mle', marginals=[t, t], 
                    hyper_param=hyperParams, 
                    hyper_param_bounds=[[-1, 1], [0, 1], [-1, 1], [0, 1]])

# 蒙特卡洛模擬
# 首先生成服從[0, 1]均勻分布的兩組隨機數(u, w)
u = np.random.uniform(0, 1, size=10000)
w = np.random.uniform(0, 1, size=10000)

# w = C_u(v), 其中C_u(v)為C(u, v)對u求偏導結果,
# v = C_u^{-1}(w)通過反函數法得到服從C(u, v)的(u, v)
# C(u, v) = (u^{-theta} + v^{-theta} - 1)^{-1/theta}
# C_u(v) = (u^{-theta} + v^{-theta} - 1)^{-(1+theta)/theta} * u^{-theta-1}
# C_u^{-1}(w) = [(w^{-theta/(1+theta)}-1)*u^{-theta}+1]^{-theta}
theta = param[0]
v = ((w**(-theta/(1+theta))-1)*u**(-theta)+1)**(-theta)

# 利用u,v對應邊緣分布函數的累計概率函數的逆函數
x = t.ppf(u, df=param[1][0]['df'], loc=param[1][0]['loc'], scale=param[1][0]['scale'])
y = t.ppf(v, df=param[1][1]['df'], loc=param[1][1]['loc'], scale=param[1][1]['scale'])

# 假設兩個公司資金投資權重分別為0.3和0.7,得到對應1分位、5分位、10分位的損失 z
= 0.3 * x + 0.7 * y
p = np.percentile(z, (1, 5, 10), interpolation='midpoint')

 

# 最后查看擬合得到的Copula函數的CDF和PDF分布圖
u, v, C = cdf_2d(clayton)
u, v, c = pdf_2d(clayton)

fig = plt.figure()
ax = fig.add_subplot(121, projection='3d', title="Clayton copula CDF")
X, Y = np.meshgrid(u, v)

ax.set_zlim(0, 1)
ax.plot_surface(X, Y, C, cmap=cm.Blues)
ax.plot_wireframe(X, Y, C, color='black', alpha=0.3)

ax = fig.add_subplot(122, projection='3d', title="Clayton copula PDF")
ax.set_zlim(0, 5)
ax.plot_surface(X, Y, c, cmap=cm.Blues)
ax.plot_wireframe(X, Y, c, color='black', alpha=0.3)

plt.show()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM