天天看點

【Python金融量化】VaR系列(五):Copula模型估計組合VaR

1. 資産組合VaR模組化方法回顧 文章

中總結了通過DCC模型估計組合向前一日VaR的方法,整體思路如下:

 ●  通過Garch族模型估計各資産的波動率

 ●  通過DCC模型估計各資産間的相關系數,結合1得到資産組合的協方差矩陣

 ●  在各資産正态性假設的前提下,可以知道資産組合也服從正态分布,并且均值與協方差陣已在1,2中計算得到

 ●  在已知組合中各但資産權重w的情況下,根據下式計算組合VaR

【Python金融量化】VaR系列(五):Copula模型估計組合VaR

中總結了通過蒙特卡洛方法估計組合向前K日VaR的方法,也可以僅計算組合向前一日VaR(本文隻考慮向前1日的情況),文章中也對比了蒙特卡洛方法與DCC方法得到的結果,差異并不大。蒙特卡洛方法的思路如下:

 ●  根據Garch族模型估計資産的波動率

 ●  根據DCC模型估計組合的相關系數

 ●  在1,2的基礎上,在正态性假設前提下,得到組合的分布函數,對組合收益率進行模拟,在給定各資産權重w的情況下,可以得到組合的總收益

 ●  重複1-3若幹次,可以得到組合總收益的模拟序列,類似HS方法,取p分位數即可

可以看出不論是DCC模型還是蒙特卡洛方法,都是在正态性假設的前提下,得到組合的分布函數再進行求解。事實上,也可以類比多元正态的概念建構多元t分布和多元漸進t分布,假設組合服從這樣的分布,求出分布的參數後,再用蒙特卡洛方法進行模拟,這些理論依據已經很成熟,推導過程見文獻[1],這裡不再贅述。

但需要說明的是,多元t分布和多元漸近t分布都沒有邊際分布和線性組合依然多元t或者多元漸近t的性質。回憶多元正态的情況下,為了生成多元正态随機數,實際上是先産生不相關的n組一進制正态随機數向量,然後通過cholesky分解轉換為符合給定相關系數矩陣的組合收益率模拟序列。如果組合的分布不具有類似多元正态的性質,要根據分布函數模拟組合收益就比較困難,必須直接通過多元分布函數産生随機數,不能分解成單個資産去做,雖然也有相關的方法可以生成給定分布函數下随機數,但都比較麻煩,這是之前方法的一個局限性。

此外,多元正态假設所有的單個資産都是正态分布,多元t分布和多元漸近t分布的邊際分布并非t分布或者漸近t分布,而不同的資産可能服從不同的分布,需要用不同方法去模組化,已有的多元分布都不能滿足這一條件,這是之前方法的另一局限性。

比較理想的狀态是,我們可以用不同的方法對不同的單資産進行模組化,最終n各資産具有不同的分布函數

【Python金融量化】VaR系列(五):Copula模型估計組合VaR
這種情況下,如果可以找到一個連接配接函數G,通過這n個邊際分布得到組合的分布F,就可以解決上面所說的兩種局限。
【Python金融量化】VaR系列(五):Copula模型估計組合VaR

這也正是本文總結的Copula模型的邏輯。

2.Copula模型

Sklar定理

Copula模型整體來說比較複雜,這裡隻對關鍵的部分加以說明,模型中最重要的定理是Sklar定理,也就是上面所說的理想情況,具體叙述如下

【Python金融量化】VaR系列(五):Copula模型估計組合VaR

G稱為copula CDF,在sklar定義的假設下,如果我們已經通過一些單變量模型得到了單資産的分布函數,隻需要确定出copula函數G,就相當于知道了組合的分布函數,進而把估計組合分布函數的問題轉化為估計copula函數的問題。當然copula函數也不是靠猜,有一些常用的copula函數可以選擇,在确定了copula函數之後,可以通過MLE等方法估計參數。

參數估計(MLE)

【Python金融量化】VaR系列(五):Copula模型估計組合VaR
這裡的C就是上文的G,見參考文獻[2],二進制情況下,可以細分為
【Python金融量化】VaR系列(五):Copula模型估計組合VaR

其中,序号1稱為Gumbel Copula函數,序号2稱為Clayton Copula函數,序号3稱為Frank Copula函數,之是以說明這三個,是因為這三個實際應用中比較多,python的copulalib包中也隻提供這三種方法,不過本文并未嘗試這幾種方法,有興趣的可以自己嘗試下。

VaR估計思路

從之前的叙述中可以看出,通過copula函數得到的組合分布函數沒有非常好的解析表達式,是以直接通過定義計算VaR的方法行不通,一般采取與蒙特卡洛方法相結合的方式,生成給定copula函數下的随機數,模拟資産組合的收益序列,再根據組合權重得到組合總收益,重複若幹次,取p分位數。

随機數構造

使用蒙特卡洛方法的難點在于生成給定copula函數下的随機數,需要用到Nelsen定理,詳見參考文獻[2]

【Python金融量化】VaR系列(五):Copula模型估計組合VaR
用Nelson定理構造随機數的方法如下
【Python金融量化】VaR系列(五):Copula模型估計組合VaR
看了下copulib的源碼,就是用這種方法構造的。而如果是多元正态copula或者多元t-copula的話, 有更簡便的方法。以二進制為例,可以往更高維推廣
【Python金融量化】VaR系列(五):Copula模型估計組合VaR
【Python金融量化】VaR系列(五):Copula模型估計組合VaR

服從二進制正态,可以直接模拟,然後再用标準正态分布函數作用,就可以得到符合給定多元正态copula的随機數,多元t-copula分布類似。

在得到符合給定copula分布的随機數u後,根據單個資産的分布F,可以得到單資産對應的随機數z

【Python金融量化】VaR系列(五):Copula模型估計組合VaR

随後可以根據權重計算組合收益進而估計VaR。

綜上,可以将Copula函數估計VaR的過程總結如下

選擇copula函數,估計參數

第一步:根據單變量模型對所有單資産進行模組化,估計分布函數F;

第二步:根據所有的分布函數F和給定copula函數,最大化對數似然函數估計參數;

蒙特卡洛模拟估計VaR

第一步:生成符合copula函數的随機數;

第二步:通過随機數得到各資産收益的模拟序列;

第三步:根據各資産權重得到組合收益序列,取p分位數作為VaR估計值

3.實證分析

資料:S&P500、US 10yr T-Note Fixed Term(同上一篇)

區間:2001-2010

蒙特卡洛模拟次數:10000次

資料和代碼在背景回複“VaR5”擷取

僅估計最後一天的VaR。代碼中未給出太多注釋,可以參見文獻[1]第九章習題。

前兩道題首先通過threshold correlation說明正态性假設并不符合實際,threshold correlation定義如下,r(p)表示r的p分位數

【Python金融量化】VaR系列(五):Copula模型估計組合VaR
結果如下
【Python金融量化】VaR系列(五):Copula模型估計組合VaR
藍色線為真實收益序列的threshold correlation,紅色為标準正态的,如果将真實收益序列轉化為标準收益,結果如下
【Python金融量化】VaR系列(五):Copula模型估計組合VaR
可以看出,二者相差很大,說明用多元正态進行模組化并不符合實際。

1def getThre_cor(data,column1,column2,p):

2 cor = pd.DataFrame(p,columns = ['p'])

3 cor['thre_cor'] = 0

4 for i in range(cor.shape[0]):

5 if p[i] <=0.5:

6 condition1 = (data[column1] <= np.percentile(data[column1],p[i]*100))

7 condition2 = (data[column2] <= np.percentile(data[column2],p[i]*100))

8 else:

9 condition1 = (data[column1] > np.percentile(data[column1],p[i]*100))

10 condition2 = (data[column2] > np.percentile(data[column2],p[i]*100))

11 datas = data.loc[condition1 & condition2,:]

12 cor.loc[i,'thre_cor'] = np.corrcoef(datas[column1],datas[column2])[0,1]

13 return cor

14

15def Thre_cor_norm(num,rou):

16 np.random.seed(52)

17 data = pd.DataFrame(index = range(num))

18 data['r1'] = np.random.normal(size=(num,1))

19 data['r2'] = np.random.normal(size=(num,1))

20

21 data['r1_c'] = data['r1']

22 data['r2_c'] = data.r1*rou + data.r2*(1 - rou**2)**0.5

23 return data

24

25p = np.arange(0.15,0.90,0.05)

26rou = np.corrcoef(data1.Log_Return_SP,data1.Log_Return_US)[0,1]

27data_norm = Thre_cor_norm(30000,rou)

28cor_norm = getThre_cor(data_norm,'r1_c','r2_c',p)

29

30p = np.arange(0.15,0.86,0.01)

31cor = getThre_cor(data1,'Log_Return_SP','Log_Return_US',p)

32ax = plt.figure(figsize=(10,5))

33plt.plot(cor.p,cor.thre_cor,linewidth = 2)

34plt.plot(cor_norm.p,cor_norm.thre_cor,linewidth = 2,color = 'red')

35plt.grid()

36plt.show()

第三道題為用t-garch分别對兩個單資産進行模組化,估計參數d,不再說明;

第四道題為用第三問的結果建立二進制正态copula模型,估計組合VaR,過程前面已經說明,代碼如下

估計copula函數的參數

1def getNegativeLoglikelihood_copula(rou,r):

2 LogLikeLihood = -r.shape[0]*np.log(1 - rou**2)/2 - ((r.norm1**2 +r.norm2**2 - 2*rou*r.norm1*r.norm2)/(2*(1 - rou**2)) -

3 0.5*(r.norm1**2 + r.norm2**2)).sum()

4 return -LogLikeLihood

5

6rou_best = optimize.fmin(getNegativeLoglikelihood_copula,rou0, \

7 args=(copula_data,),ftol = 0.000000001)

8print('估計結果為:',rou_best)

模拟

1data4['u1c'] = data4['u1']

2data4['u2c'] = data4.u1*rou + data4.u2*(1 - rou**2)**0.5

3data4['F1'] = norm(0,1).cdf(data4['u1c'])

4data4['F2'] = norm(0,1).cdf(data4['u2c'])

5data4['z1'] = t(d_SP).ppf(data4.F1)*((d_SP-2)/d_SP)**0.5

6data4['z2'] = t(d_US).ppf(data4.F2)*((d_US-2)/d_US)**0.5

7data4['R1'] = data4.z1*sigma_SP**0.5

8data4['R2'] = data4.z2*sigma_US**0.5

9data4['R'] = 0.5*data4.R1 +0.5* data4.R2

10VaR = -np.percentile(data4.R,1)

最終估計結果為VaR = 0.0101,可以與上篇文章最後一日的結果相對比,基本上是一緻的。

原文釋出時間為:2018-10-1

本文作者:量化小白H

本文來自雲栖社群合作夥伴“

Python愛好者社群

”,了解相關資訊可以關注“

”。