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

简介:

1. 资产组合VaR建模方法回顾

文章中总结了通过DCC模型估计组合向前一日VaR的方法,整体思路如下:

 ●  通过Garch族模型估计各资产的波动率
 ●  通过DCC模型估计各资产间的相关系数,结合1得到资产组合的协方差矩阵
 ●  在各资产正态性假设的前提下,可以知道资产组合也服从正态分布,并且均值与协方差阵已在1,2中计算得到
 ●  在已知组合中各但资产权重w的情况下,根据下式计算组合VaR
0150800a13c188abf52fe51b015e044a4c425b12

文章中总结了通过蒙特卡洛方法估计组合向前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各资产具有不同的分布函数

47e0946acba7708f8c62f97e7b8021d40517c581

这种情况下,如果可以找到一个连接函数G,通过这n个边际分布得到组合的分布F,就可以解决上面所说的两种局限。

cdb6fed04c385d6aa44cf656f9df2000a24e7d28

这也正是本文总结的Copula模型的逻辑。

2.Copula模型

Sklar定理

Copula模型整体来说比较复杂,这里只对关键的部分加以说明,模型中最重要的定理是Sklar定理,也就是上面所说的理想情况,具体叙述如下

8002b25e06a60471bb006162ad5a8b9cb1d4bc86

G称为copula CDF,在sklar定义的假设下,如果我们已经通过一些单变量模型得到了单资产的分布函数,只需要确定出copula函数G,就相当于知道了组合的分布函数,从而把估计组合分布函数的问题转化为估计copula函数的问题。当然copula函数也不是靠猜,有一些常用的copula函数可以选择,在确定了copula函数之后,可以通过MLE等方法估计参数。

参数估计(MLE)

366afce825052135e0e738f86e7fe04da57b30a7

这里的C就是上文的G,见参考文献[2],二元情况下,可以细分为

b8c4fe455cbc06bde4d95b6e0e31fc40906cb7be

其中,序号1称为Gumbel Copula函数,序号2称为Clayton Copula函数,序号3称为Frank Copula函数,之所以说明这三个,是因为这三个实际应用中比较多,python的copulalib包中也只提供这三种方法,不过本文并未尝试这几种方法,有兴趣的可以自己尝试下。

VaR估计思路

从之前的叙述中可以看出,通过copula函数得到的组合分布函数没有非常好的解析表达式,所以直接通过定义计算VaR的方法行不通,一般采取与蒙特卡洛方法相结合的方式,生成给定copula函数下的随机数,模拟资产组合的收益序列,再根据组合权重得到组合总收益,重复若干次,取p分位数。

随机数构造

使用蒙特卡洛方法的难点在于生成给定copula函数下的随机数,需要用到Nelsen定理,详见参考文献[2]

dc2dd27c1315bcde38a64c2e913a8efa5699db18

用Nelson定理构造随机数的方法如下

0bf2283db033d87b50d4ad90378388fb309bb2c4

看了下copulib的源码,就是用这种方法构造的。而如果是多元正态copula或者多元t-copula的话, 有更简便的方法。以二元为例,可以往更高维推广

cf9894f177a7f76b9b26dfaa5f585a005e2d7333 bd9900dd22690daf30cd1be320ba5f2840a10733
服从二元正态,可以直接模拟,然后再用标准正态分布函数作用,就可以得到符合给定多元正态copula的随机数,多元t-copula分布类似。

在得到符合给定copula分布的随机数u后,根据单个资产的分布F,可以得到单资产对应的随机数z

2a1a9d498b808bd8811c565429bb6959581c7a95

随后可以根据权重计算组合收益进而估计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分位数

0757a77e93bfd805275dd9d9c2420882914c9ee2

结果如下

02ad6f1e851ca91646d2896f08e751c0257dc860

蓝色线为真实收益序列的threshold correlation,红色为标准正态的,如果将真实收益序列转化为标准收益,结果如下

da2d27bc1f1c743c9dffb85cca348a8d154bb7d9

可以看出,二者相差很大,说明用多元正态进行建模并不符合实际。

 

1 def 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
15 def 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
25 p = np.arange( 0.15 , 0.90 , 0.05 )
26 rou = np.corrcoef(data1.Log_Return_SP,data1.Log_Return_US)[ 0 , 1 ]
27 data_norm = Thre_cor_norm( 30000 ,rou)
28 cor_norm = getThre_cor(data_norm, 'r1_c' , 'r2_c' ,p)
29
30 p = np.arange( 0.15 , 0.86 , 0.01 )
31 cor = getThre_cor(data1, 'Log_Return_SP' , 'Log_Return_US' ,p)
32 ax = plt.figure(figsize=( 10 , 5 ))
33 plt.plot(cor.p,cor.thre_cor,linewidth = 2 )
34 plt.plot(cor_norm.p,cor_norm.thre_cor,linewidth = 2 ,color = 'red' )
35 plt.grid()
36 plt.show()

第三道题为用t-garch分别对两个单资产进行建模,估计参数d,不再说明;

第四道题为用第三问的结果建立二元正态copula模型,估计组合VaR,过程前面已经说明,代码如下

估计copula函数的参数

 

1 def 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
6 rou_best = optimize.fmin(getNegativeLoglikelihood_copula,rou0, \
7 args=(copula_data,),ftol = 0.000000001 )
8 print( '估计结果为:' ,rou_best)

模拟

 

1 data4[ 'u1c' ] = data4[ 'u1' ]
2 data4[ 'u2c' ] = data4.u1*rou + data4.u2*( 1 - rou** 2 )** 0.5
3 data4[ 'F1' ] = norm( 0 , 1 ).cdf(data4[ 'u1c' ])
4 data4[ 'F2' ] = norm( 0 , 1 ).cdf(data4[ 'u2c' ])
5 data4[ 'z1' ] = t(d_SP).ppf(data4.F1)*((d_SP -2 )/d_SP)** 0.5
6 data4[ 'z2' ] = t(d_US).ppf(data4.F2)*((d_US -2 )/d_US)** 0.5
7 data4[ 'R1' ] = data4.z1*sigma_SP** 0.5
8 data4[ 'R2' ] = data4.z2*sigma_US** 0.5
9 data4[ 'R' ] = 0.5 *data4.R1 + 0.5 * data4.R2
10 VaR = -np.percentile(data4.R, 1 )

最终估计结果为VaR = 0.0101,可以与上篇文章最后一日的结果相对比,基本上是一致的。


原文发布时间为:2018-10-1

本文作者:量化小白H

本文来自云栖社区合作伙伴“Python爱好者社区”,了解相关信息可以关注“Python爱好者社区”。

相关文章
|
1天前
|
机器学习/深度学习 人工智能 大数据
AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀
AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀
|
3天前
|
机器学习/深度学习 自然语言处理 算法
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
|
3天前
|
数据可视化 Python
python中Copula在多元联合分布建模可视化2实例合集|附数据代码
python中Copula在多元联合分布建模可视化2实例合集|附数据代码
|
9天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习专栏】金融数据分析中的机器学习应用
【4月更文挑战第30天】本文探讨了机器学习在金融数据分析中的应用,如股价预测、信用评分、欺诈检测、算法交易和风险管理,并以Python为例展示了如何进行股价预测。通过使用机器学习模型,金融机构能更准确地评估风险、识别欺诈行为并优化交易策略。Python结合scikit-learn库简化了数据分析过程,助力金融从业者提高决策效率。随着技术发展,机器学习在金融领域的影响力将持续增强。
|
9天前
|
机器学习/深度学习 数据采集 前端开发
【Python机器学习专栏】模型泛化能力与交叉验证
【4月更文挑战第30天】本文探讨了机器学习中模型泛化能力的重要性,它是衡量模型对未知数据预测能力的关键。过拟合和欠拟合影响泛化能力,而交叉验证是评估和提升泛化能力的有效工具。通过K折交叉验证等方法,可以发现并优化模型,如调整参数、选择合适模型、数据预处理、特征选择和集成学习。Python中可利用scikit-learn的cross_val_score函数进行交叉验证。
|
9天前
|
机器学习/深度学习 数据可视化 前端开发
【Python机器学习专栏】机器学习模型评估的实用方法
【4月更文挑战第30天】本文介绍了机器学习模型评估的关键方法,包括评估指标(如准确率、精确率、召回率、F1分数、MSE、RMSE、MAE及ROC曲线)和交叉验证技术(如K折交叉验证、留一交叉验证、自助法)。混淆矩阵提供了一种可视化分类模型性能的方式,而Python的scikit-learn库则方便实现这些评估。选择适合的指标和验证方法能有效优化模型性能。
|
9天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】机器学习中的模型融合技术
【4月更文挑战第30天】模型融合,即集成学习,通过结合多个模型提升预测性能。常见方法包括:Bagging(如Random Forest)、Boosting(如AdaBoost、XGBoost)和Stacking。Python中可使用`scikit-learn`实现,例如BaggingClassifier示例。模型融合是机器学习中的强大工具,能提高整体性能并适应复杂问题。
|
9天前
|
机器学习/深度学习 Python
【Python 机器学习专栏】模型选择中的交叉验证与网格搜索
【4月更文挑战第30天】交叉验证和网格搜索是机器学习中优化模型的关键技术。交叉验证通过划分数据集进行多次评估,如K折和留一法,确保模型性能的稳定性。网格搜索遍历预定义参数组合,寻找最佳参数设置。两者结合能全面评估模型并避免过拟合。Python中可使用`sklearn`库实现这一过程,但需注意计算成本、过拟合风险及数据适应性。理解并熟练应用这些方法能提升模型性能和泛化能力。
|
9天前
|
机器学习/深度学习 数据可视化 TensorFlow
【Python 机器学习专栏】使用 TensorFlow 构建深度学习模型
【4月更文挑战第30天】本文介绍了如何使用 TensorFlow 构建深度学习模型。TensorFlow 是谷歌的开源深度学习框架,具备强大计算能力和灵活编程接口。构建模型涉及数据准备、模型定义、选择损失函数和优化器、训练、评估及模型保存部署。文中以全连接神经网络为例,展示了从数据预处理到模型训练和评估的完整流程。此外,还提到了 TensorFlow 的自动微分、模型可视化和分布式训练等高级特性。通过本文,读者可掌握 TensorFlow 基本用法,为构建高效深度学习模型打下基础。
|
9天前
|
算法 数据挖掘 Python
Python贝叶斯MCMC:Metropolis-Hastings、Gibbs抽样、分层模型、收敛性评估
Python贝叶斯MCMC:Metropolis-Hastings、Gibbs抽样、分层模型、收敛性评估