VaR和CVaR的计算是金融基础建设的作业,不过VaR和CVaR在风险管理课上都有讲过,难度也不大。需要注意的是CVaR就是Expected Shortfall,两个是一样的东西,只是说法不同而已。接下来我将主要展现的是代码的实现,至于原理我就不过多解释了,网上资料都有很多(后面有时间我再完善)。由于作业还没有截止,数据我也不提供了,自己去找吧,避免结果都是一样的,如果真的有需要,可以给我留言,我再考虑考虑给不给你
针对①HSI index futures ② 其他任意一个Index futures ③其他任意一个Stock futures
VaR和CVaR是可以用来衡量金融资产的风险,包括股票和期货等等。VaR和CVaR的计算公式如下:
VaR : V a R α ( x ) = m i n { z ∈ R : P { f ( x , r ) ≤ z } ≥ 1 − α } VaR_\alpha(x)=min\{z \in R:P\{ f(x,r)\le z\}\ge 1-\alpha\} VaRα(x)=min{z∈R:P{f(x,r)≤z}≥1−α}
CVaR : C V a R α ( x ) = E [ f ( x , r ) ∣ f ( x , r ) ≤ V a R α ( x ) ] CVaR_\alpha(x)=E[f(x,r) | f(x,r)\le VaR_\alpha(x)] CVaRα(x)=E[f(x,r)∣f(x,r)≤VaRα(x)]
CVaR能更好地测度极端风险情况,使用 CVaR 进行风险度量可以更加稳健地估计可能发生的风险。
这题要求我们计算期货商品的VaR和CVaR,关键就是拿什么数据来计算,收盘价和结算价还是保证金?先说结论:都可以。不过需要注意的是收盘价和结算价是有些不一样的,具体的可以自己百度下(后面再完善)。这里主要讲下为什么保证金也可以,因为保证金是按照收盘价的一定比例来进行计算的,所以你无论你用保证金还是收盘价结果都是一样的,不过不一样的是你用保证金来计算的时候要将保证金转换为保证金的变换来进行VaR和CVaR的计算。而且对于香港市场来说,它的保证金是按月来进行调整的,这时候你算1个月的VaR和CVaR就还可以,但想算1-day的VaR和CVaR的话就不太合适了。下面主要展示的是HSI index futures的相关计算,其他期货商品处理过程都一样,数据不一样而已,用的是结算价来进行计算。最后还想提醒下,下面计算的VaR和CVaR都是负的,但我们知道VaR和CVaR都应该为正的,所以你得加个负号将其变正。
先导入一些基本库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn
import math
#设置字体为楷体
plt.rcParams['font.sans-serif'] = ['KaiTi']
%matplotlib inline
导入提前收集好的数据,包括日期和结算价(⚠️ 只需要日期和结算价就行,其他都可以不用)
#倒入恒生指数期货数据
HSIF= pd.read_excel('恒生指数期货结算价.xlsx')
HSIF.head()
数据是长这样的:
接下来还需要对结算价进行处理,收集到的结算价可能为0,所以需要先将其剔除,然后计算它的每日收益率,这里采用python自带的函数pct_change()便可以处理
#剔除结算价为0的数据
HSIF=HSIF[HSIF.settle!=0]
#计算恒生指数期货的每日收益率
HSIF['d_return'] = HSIF['settle'].pct_change()
下面的参数法是基于分布是正态分布才是成立的,如果数据不是正态分布可能就会有问题,具体的可以看看这一篇文章:https://blog.csdn.net/hzk427/article/details/104858021
###利用参数法计算1天的VaR
HSIF_mean_return = HSIF['d_return'].mean()
HSIF_std = HSIF['d_return'].std()
HSIF_VaR1 = HSIF_mean_return-1.96*HSIF_std
HSIF_VaR1
⚠️ 由于下面的蒙特卡洛法是基于最后一天的结算价去生成的,所以你得确保你最后一天的结算价不能为0,否则会报错。
###利用蒙特卡洛法
# 定义一个函数,用于计算一次几何布朗运动的价格数据,single simualtion;
def GBM(s_0, mu, sigma, T ,n):
"""计算几何布朗运动的价格数据
parameters:
s_0: 开始价格
mu: 观察期日收益率的均值
sigma: 观察期日收益率的标准差
T: 预测价格的周期长度,如预测下一天,T=1,预测后10天,T=10;
n: 单次模拟的步数,步数越大,模拟得越精确;
"""
# 计算delta_t
delta_t = T/n
# 创建一个空的列表用于储存价格数据
simulated_price = [s_0]
# 模拟价格走势
for i in range(n):
# 获取期初价格
start_price = simulated_price[i]
# 按照标准正态分布产生一个随机数
epsilon = np.random.normal()
# 根据几何布朗运动公式计算期末价格
end_price = start_price + start_price * (mu*delta_t + sigma*epsilon*np.sqrt(delta_t))
# 价格应大于0
#print(end_price)
#end_price = max(0, end_price)
# 将算的的结果存入列表
simulated_price.append(end_price)
return simulated_price
# 产生10000个1天的模拟价格,取出它们的最终价格,并保存在simulated_prices_1空列表中
simulated_prices_HSIF = []
s_HSIF=HSIF['settle'].iloc[-1]
mu_HSIF=HSIF['d_return'].mean()
sigma_HSIF=HSIF['d_return'].std()
for i in range(10000):
# 模拟一次几何布朗运动
simulated_price = GBM(s_HSIF, mu_HSIF, sigma_HSIF, 1,100)
#print(simulated_price)
# 取出最终价格
final_price = simulated_price[-1]
simulated_prices_HSIF.append(final_price)
simulated_return_HSIF = simulated_prices_HSIF/s_HSIF-1
HSIF_VaR2 = np.percentile(simulated_return_HSIF, 1)
HSIF_VaR2
### 利用历史模拟法计算VaR
# np.percentile方法计算分位数,前提是不能有空值;
HSIF_VaR3= np.percentile(HSIF.d_return.dropna(), 5)
HSIF_VaR3
#恒生指数期货的VaR绘图
plt.figure(figsize= (8,6))
HSIF.d_return.hist(bins=50, alpha=0.6, color='steelblue')
plt.axvline(HSIF_VaR1, color='y', linewidth=1,label = 'parametric method')
plt.axvline(HSIF_VaR2, color='b', linewidth=1,label = 'Monte Carlo method')
plt.axvline(HSIF_VaR3, color='r', linewidth=1,label = 'historical simulation method')
plt.title("The VaR of HSIF(95%)")
plt.legend()
plt.xlabel('return')
plt.ylabel('count')
先封装好ES_daily()函数来方便后续CVaR的计算
# 开始计算 ES 值
'''
输入:
a:每日收益率
x:置信度
输出:
ES
'''
def ES_Daily(a,x):
VaR=np.percentile(a,(1-x)*100)
ES=a[a<=VaR].mean()
return ES
#print('99%置信水平下的ES为{:.2f}'.format(\
#ES_daily(df1.rev_rate,0.99)))
接下来就直接调用ES_daily函数即可
#计算恒生指数期货的CVaR
CVaR_HSIF=ES_Daily(HSIF.d_return.dropna(),0.95)
CVaR_HSIF
这里我就用历史模拟法计算得到的VaR来和CVaR进行比较
#用历史模拟法来对比恒生指数期货的VaR和CVaR
plt.figure(figsize= (8,6))
HSIF.d_return.hist(bins=50, alpha=0.6, color='steelblue')
plt.axvline(HSIF_VaR3, color='b', linewidth=1,label = 'VaR')
plt.axvline(CVaR_HSIF, color='r', linewidth=1,label = 'CVaR')
#plt.xlim(-0.3,0.3)
plt.title("VaR Vs CVaR(HSIF)")
plt.legend()
plt.xlabel('return')
plt.ylabel('count')
严格意义上来说,我上面计算的VaR和CVaR是有一点问题的,因为VaR和CVaR算的是预期的最大损失,应该算出具体的数值,但我上面计算的VaR和CVaR都是百分比,没有乘以初始资金(乘以初始资金才是正确的),不过转念一想,如果你把初始资金当作1,也是可以说得通的,比如你有1元,算出的VaR是5%,也就是说你预期的最大损失就是1*5%=0.05,也就是5%。
至此就基本完成了所有的问题,美中不足的是matplotlib绘画的图实在是太丑了,所以我还对数据展示的图进行优化。不过这部分是收费环节了,你得帮我点个赞我才发代码给你(明示)
下面附上代码和相关数据集,包括恒生指数期货、恒生国企指数期货以及腾讯控股期货
https://download.csdn.net/download/weixin_46366341/85853065
代码主要参考以下文章
https://blog.csdn.net/leige_2020/article/details/104405116
https://www.pythonheidong.com/blog/article/498331/acba1f875635a1c52fd9/
https://www.lianxh.cn/news/5001362259713.html
https://blog.csdn.net/hzk427/article/details/104858021