失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【Python量化】VaR在险价值的计算

【Python量化】VaR在险价值的计算

时间:2019-09-29 16:52:38

相关推荐

【Python量化】VaR在险价值的计算

文章目录

一、VaR的定义二、计算单一资产的VaR2.1 数据概况2.2 方差-协方差法2.3 历史模拟法2.4 蒙特卡罗模拟法 三、计算资产组合的VaR3.1 数据概况3.2 方差-协方差法3.3 历史模拟法3.4 蒙特卡罗模拟法 四、全套代码4.1 计算单一资产的VaR4.2 计算资产组合的VaR

此文章首发于微信公众号:Python for Finance

链接:https://mp./s/uaDEnSzoalTaRmZ9GNvR0A

一、VaR的定义

假设有一投资组合,考虑如下问题:

在95%或99%的置信水平下,预计在未来一个月内损失的金额最大是多少?在95%或99%的置信水平下,预计在未来一年内损失的最大百分比是多少?

VaR (Value at Risk),在险价值,其含义为:在一定概率水平 (置信度) 下,某一金融资产在未来特定时期内的最大可能损失。

VaR 有三个要素:

置信水平:通常是95%或99%时间段:一天、一个月或一年最大可能损失:可以是绝对值(损失金额),也可以是相对值(损失百分比)。

用公式表示为:

P r o b ( Δ V ⩽ − V a R ) = 1 − α Prob(\Delta V \leqslant -VaR)=1-\alpha Prob(ΔV⩽−VaR)=1−α

字母含义如下:

P r o b Prob Prob —— 资产价值损失小于可能损失上限的概率,即英文的Probability。 Δ V \Delta V ΔV—— 某一金融资产在一定持有期的价值损失额。 V a R VaR VaR—— 给定置信水平下的在险价值,即可能的损失上限,可以是绝对值,也可以是相对值。 α \alpha α—— 给定的置信水平

假设基金经理管理的证券组合在未来1天内,置信度为95%的情况下,VaR值为520万元。可以将其写作:

P r o b ( Δ V ⩽ − 520 ) = 1 − 95 % = 5 % Prob(\Delta V \leqslant -520)=1-95\%=5\% Prob(ΔV⩽−520)=1−95%=5%

含义:

在未来24小时内,存在95%的概率,基金经理所管理的证券组合价值损失不超过520万元;有 95% 的把握判断该证券组合在下一个交易日内的损失在 520 万元以内;证券组合在一天内 ,由于市场价格变化而带来的最大损失超过 520 万元的概率为 5%;95%置信度的含意是我们预期100天中只有5天的损失会超过对应的VaR值。但VaR并没有指出在可能超过VaR损失的时间内(如95%置信度的5/100天中;或99%的1/100 天中)的实际损失会是多少。

根据巴塞尔协议的明确规定:银行需要计算持有期10天、置信水平99%的VaR。在实际计算中,通常先计算 N=1 时的VaR,在计算相同置信水平下 N>1 时的 VaR,其表达式如下:

N 天 V a R = 1 天 V a R ∗ n N天VaR=1天VaR*\sqrt n N天VaR=1天VaR∗n ​

二、计算单一资产的VaR

VaR 的度量主要有方差-协方差法 (Variance-Covariance Approach) 、历史模拟法 (Historical Simulation Method) 和蒙特卡罗模拟法 (Monte-Carlo Simulation) 三种方法。

2.1 数据概况

我们以中国平安 (000001) 股票为例,使用方差-协方差法、历史模拟、蒙特卡洛模拟法来计算它的 VaR 值。

在计算之前,首先需要获取到中国平安的历史股价数据,这里我们使用AKShare包。它是一个免费、开源的 Python 财经数据接口包。AKShare返回的绝大部分的数据格式都是 pandas DataFrame 类型,非常便于用 pandas/ NumPy/ Matplotlib 进行数据分析和可视化。

import pandas as pdimport numpy as npimport akshare as akimport scipy.stats as st# 读入中国平安 「000001」 -01-01 到 -12-31 日收盘价数据data = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="0101", end_date='1231', adjust="")data.index = pd.to_datetime(data['日期'],format='%Y-%m-%d') #设置日期索引close = data['收盘'] #日收盘价ret = np.log(close/close.shift(1)) #日收益率ret = ret.dropna()

获取的数据如下:

>>>ret日期-01-06 -0.015095-01-07 -0.019194-01-08 -0.034169-01-09 0.007989-01-12 -0.020771-12-27 -0.005213-12-28 -0.002908-12-29 -0.024765-12-30 0.004170-12-31 -0.020421Name: 收盘, Length: 1704, dtype: float64

2.2 方差-协方差法

方差-协方差法度量风险值(VAR)的前提条件是假设风险因子的变化服从多元正态分布。

以单一资产中国平安 (000001) 股票为例,使用方差-协方差法来计算它的 VaR 值。假设持有中国平安股票的价值为100万元。

value = 1000000 #中国平安股票价值为100万元R_mean = ret.mean() #计算均值R_vol = ret.std() #计算标准差def VaR_VCM(value,mu,sig,X,T):'''Parameters----------value : 资产的价值mu : 资产的日均收益率sig : 资产的日均波动率(标准差)X : 置信水平T : 持有天数 ''' z = abs(st.norm.ppf(q=1-X)) return np.sqrt(T)*value*(z*sig-mu)VaR99_1day_VCM = VaR_VCM(value,R_mean,R_vol, 0.99, 1)VaR99_10day_VCM = VaR_VCM(value,R_mean,R_vol, 0.99, 10)VaR95_1day_VCM = VaR_VCM(value,R_mean,R_vol, 0.95, 1)VaR95_10day_VCM = VaR_VCM(value,R_mean,R_vol,0.95, 10)print(f'方差-协方差法1天、99%的VaR:{VaR99_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、99%的VaR:{VaR99_10day_VCM/10000:.2f}万元') print(f'方差-协方差法1天、95%的VaR:{VaR95_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、95%的VaR:{VaR95_10day_VCM/10000:.2f}万元')

结果为:

方差-协方差法1天、99%的VaR:5.16万元方差-协方差法10天、99%的VaR:16.32万元方差-协方差法1天、95%的VaR:3.65万元方差-协方差法10天、95%的VaR:11.54万元

2.3 历史模拟法

基本假设:资产收益的过去变化状况会在未来完全重现。

基本思想:利用过去一段时间历史收益资料,估算投资组合变化的统计分布(经验分布),再根据不同的分位数求得相对应的置信水平的风险值。和协方差矩阵估算方法不同,历史模拟法对收益的分布不做任何假设,只用到历史经验分布,统计上用的是非参数方法。

具体方法:将历史收益由小到大排序,并给出经验分布函数,由此可以估算不同置信水平下的VaR值。例如,收益经验分布由1000笔收益数据的频率构成,则在置信水平为95%的条件下,应选取从小到大排序的第51笔收益金额

为VaR值的估计,即收益经验分布的第5%分位数;置信水平为99%则选择第1%分位数,置信水平为90%则选择第10%分位数

以单一资产中国平安 (000001) 股票为例,使用历史模拟法来计算它的 VaR 值。假设持有中国平安股票的价值为100万元。

value = 1000000 #中国平安股票价值为100万元def VaR_history(value,ret,X,T):'''Parameters----------value : 资产的价值ret : 资产的日收益率序列X : 置信水平T : 持有天数 ''' # Numpy 的 percentile 函数,可以直接返回序列相应的分位数return value*np.sqrt(T)*abs(np.percentile(ret,(1-X)*100))VaR99_1day_history = VaR_history(value,ret,0.99,1)VaR99_10day_history = VaR_history(value,ret,0.99,10)VaR95_1day_history = VaR_history(value,ret,0.95,1)VaR95_10day_history = VaR_history(value,ret,0.95,10)print(f'历史模拟法1天、99%的VaR:{VaR99_1day_history/10000:.2f}万元')print(f'历史模拟法10天、99%的VaR:{VaR99_10day_history/10000:.2f}万元') print(f'历史模拟法1天、95%的VaR:{VaR95_1day_history/10000:.2f}万元')print(f'历史模拟法10天、95%的VaR:{VaR95_10day_history/10000:.2f}万元')

结果为:

历史模拟法1天、99%的VaR:6.13万元历史模拟法10天、99%的VaR:19.37万元历史模拟法1天、95%的VaR:3.17万元历史模拟法10天、95%的VaR:10.02万元

2.4 蒙特卡罗模拟法

基本思想:蒙特卡罗模拟法(Monte Carlo Simulation, MCS)是在一定的统计分布假设下模拟风险因子的变化情况。首先假设资产收益为某一随机过程,并根据所设定的价格变动过程,大量模拟未来各种可能发生的情境,然后将某一情境下投资组合变化值排序,给出投资组合变化的分布,据此就可以估算不同置信水平下的VaR值。

基本步骤

每一次蒙特卡洛模拟,对资产组合中的每一资产按照随机过程公式模拟出下一个交易日的价格,公式中的ε可以假定服从t分布或正态分布(即资产收益率服从的分布),然后可以得到每一资产的收益率,乘以各自的权重和市值就能得到每一资产在下一个交易日的收益,全部相加就是该资产组合在下一个交易日的模拟收益。

比如蒙特卡罗模拟法的抽样次数是10000次,通过重复以上的步骤可以得到组合收益的10000个不同的样本值,持有期1天、置信水平95%的投资组合风险价值就对应于样本数值中排在第500位最大损失的取值。

假设股票价格符合几何布朗运动,即

d S t = μ t S t d t + σ t S t d W t dS_t=\mu_tS_tdt+\sigma_tS_tdW_t dSt​=μt​St​dt+σt​St​dWt​

简化处理,得到特定时期(0,T)资产价格变化过程:

Δ S t = S t ( μ Δ t + σ ε t Δ t ) , t = 1 , 2 , . . . , N , N Δ t = T \Delta S_t=S_t(\mu\Delta t+\sigma\varepsilon_t\sqrt{\Delta t}),t=1,2,...,N,N\Delta t=T ΔSt​=St​(μΔt+σεt​Δt ​),t=1,2,...,N,NΔt=T

于是得到:

S t + 1 = S t + S t ( μ Δ t + σ ε t Δ t ) , t = 1 , 2 , . . . , N , N Δ t = T S_{t+1}=S_t+S_t(\mu\Delta t+\sigma\varepsilon_t\sqrt{\Delta t}),t=1,2,...,N,N\Delta t=T St+1​=St​+St​(μΔt+σεt​Δt ​),t=1,2,...,N,NΔt=T

也可表示为:

S t + 1 = S t e ( μ − σ 2 2 ) Δ t + σ ε t Δ t ) S_{t+1}=S_te^{(\mu-\frac{\sigma^2}2)\Delta t+\sigma\varepsilon_t\sqrt{\Delta t})} St+1​=St​e(μ−2σ2​)Δt+σεt​Δt ​)

其中 μ \mu μ为收益率均值, σ 2 \sigma^2 σ2为收益率方差, ε \varepsilon ε服从t分布或正态分布。

以单一资产中国平安 (000001) 股票为例,使用蒙特卡罗模拟法来计算它的 VaR 值。假设持有中国平安股票的价值为100万元。

value = 1000000 #中国平安股票价值为100万元m = 10000 #模拟次数e1 = np.random.standard_t(df=len(ret),size=m) #自由度为收益率数据长度的t分布#e1 = np.random.standard_normal(size=m) #若服从正态分布,则此代码代替上行代码R_mean_year = ret.mean()*252 #计算每一资产的年化平均收益率R_vol_year = ret.std()*np.sqrt(252) #计算每一资产的年化波动率dt=1/252 #时间间隔S0=1S=np.zeros(m) #存放模拟次数个模拟价格数据#代入随机过程S=S0*(np.exp((R_mean_year-0.5*R_vol_year**2)*dt+R_vol_year*e1*np.sqrt(dt)))F_ret=S/S0-1 #模拟未来收益率#蒙特卡洛模拟法计算VaRVaR99_1day_MS = value*abs(np.percentile(F_ret,1)) VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MSVaR95_1day_MS = value*abs(np.percentile(F_ret,5))VaR95_10day_MS = np.sqrt(10)*VaR95_1day_MS#由于抽样随机数的原因,结果可能会有不同print(f'蒙特卡罗模拟法1天、99%的VaR:{VaR99_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、99%的VaR:{VaR99_10day_MS/10000:.2f}万元') print(f'蒙特卡罗模拟法1天、95%的VaR:{VaR95_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、95%的VaR:{VaR95_10day_MS/10000:.2f}万元')

由于是随机模拟,每次估算的VaR不一致,某次运行的结果为:

蒙特卡罗模拟法1天、99%的VaR:5.06万元蒙特卡罗模拟法10天、99%的VaR:15.99万元蒙特卡罗模拟法1天、95%的VaR:3.58万元蒙特卡罗模拟法10天、95%的VaR:11.31万元

三、计算资产组合的VaR

3.1 数据概况

假设有一投资组合,含有5支股票:中国平安(000001)、格力电器(000651)、爱尔眼科(300015)、贵州茅台(600519)、长安汽车(000625),权重占比如下:

使用方差-协方差法、历史模拟、蒙特卡洛模拟法来计算组合的 VaR 值。

在计算之前,首先需要获取到中国平安的历史股价数据,这里我们使用AKShare包。它是一个免费、开源的 Python 财经数据接口包。AKShare返回的绝大部分的数据格式都是 pandas DataFrame 类型,非常便于用 pandas/ NumPy/ Matplotlib 进行数据分析和可视化。

import pandas as pdimport numpy as npimport akshare as akimport scipy.stats as st# 读入5支股票 -01-01 到 -12-31 日收盘价数据def get_ret(code):data = ak.stock_zh_a_hist(symbol=code, period="daily", start_date="0101", end_date='1231', adjust="")data.index = pd.to_datetime(data['日期'],format='%Y-%m-%d') #设置日期索引close = data['收盘'] #日收盘价close.name = coderet = np.log(close/close.shift(1)) #日收益率return retcodes=['000001','000651','300015','600519','000625']ret = pd.DataFrame()for code in codes:ret_ = get_ret(code)ret = pd.concat([ret,ret_],axis=1)ret = ret.dropna()

获取数据如下:

>>>ret000001 000651 300015 600519 000625-01-06 -0.015095 0.021099 0.083902 -0.023431 0.068956-01-07 -0.019194 -0.001681 -0.029017 -0.025029 0.007205-01-08 -0.034169 0.003360 -0.000342 -0.006135 0.010204-01-09 0.007989 -0.017888 0.000342 -0.007590 -0.044106-01-12 -0.020771 0.028848 0.042888 -0.020598 0.074108... ... ... ... ...-12-27 -0.005213 0.054392 0.018817 -0.028791 -0.017700-12-28 -0.002908 0.005571 -0.008905 0.002979 0.024176-12-29 -0.024765 -0.026268 -0.002526 -0.046515 -0.018899-12-30 0.004170 0.000272 0.003672 0.016521 -0.002635-12-31 -0.020421 0.005416 -0.031889 -0.012121 0.001977[1497 rows x 5 columns]

3.2 方差-协方差法

该方法假设资产组合的收益是呈正态分布,只预估预期(或平均)收益和标准差两个因素,从而画出正态分布曲线,将正态曲线与相同的实际收益数据作对比。方差-协方差背后逻辑与历史模拟法相似,只是使用的是正态分布曲线而不是实际历史数据。

value = 100000000 #投资组合市值为1亿元R_mean = ret.mean() #计算均值R_cov = ret.cov() #计算协方差R_vol = ret.std() #计算标准差#投资组合各资产权重weights = np.array([0.15,0.20,0.5,0.05,0.1])#计算投资组合的期望收益率Rp_daily = np.sum(weights*R_mean)#计算投资组合的日波动率Vp_daily = np.sqrt(np.dot(weights,np.dot(R_cov,weights.T)))def VaR_VCM(value,mu,sig,X,T): '''Parameters----------value : 资产的价值mu : 资产的日均收益率sig : 资产的日均波动率(标准差)X : 置信水平T : 持有天数 ''' z = abs(st.norm.ppf(q=1-X)) return np.sqrt(T)*value*(z*sig-mu)VaR99_1day_VCM = VaR_VCM(value,Rp_daily,Vp_daily, 0.99, 1)VaR99_10day_VCM = VaR_VCM(value,Rp_daily,Vp_daily, 0.99, 10)VaR95_1day_VCM = VaR_VCM(value,Rp_daily,Vp_daily, 0.95, 1)VaR95_10day_VCM = VaR_VCM(value,Rp_daily,Vp_daily,0.95, 10)print(f'方差-协方差法1天、99%的VaR:{VaR99_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、99%的VaR:{VaR99_10day_VCM/10000:.2f}万元') print(f'方差-协方差法1天、95%的VaR:{VaR95_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、95%的VaR:{VaR95_10day_VCM/10000:.2f}万元')

结果为:

方差-协方差法1天、99%的VaR:544.65万元方差-协方差法10天、99%的VaR:1722.32万元方差-协方差法1天、95%的VaR:385.20万元方差-协方差法10天、95%的VaR:1218.12万元

3.3 历史模拟法

value = 100000000 #投资组合市值为1亿元#投资组合各资产权重weights = np.array([0.15,0.20,0.5,0.05,0.1])#历史交易日投资组合的收益率序列Rp = np.dot(ret,weights)Rp = pd.DataFrame(Rp,index=ret.index,columns=['投资组合日收益'])def VaR_history(value,ret,X,T):'''Parameters----------value : 资产的价值ret : 资产的日收益率序列X : 置信水平T : 持有天数 ''' # Numpy 的 percentile 函数,可以直接返回序列相应的分位数return value*np.sqrt(T)*abs(np.percentile(ret,(1-X)*100))VaR99_1day_history = VaR_history(value,Rp,0.99,1)VaR99_10day_history = VaR_history(value,Rp,0.99,10)VaR95_1day_history = VaR_history(value,Rp,0.95,1)VaR95_10day_history = VaR_history(value,Rp,0.95,10)print(f'历史模拟法1天、99%的VaR:{VaR99_1day_history/10000:.2f}万元')print(f'历史模拟法10天、99%的VaR:{VaR99_10day_history/10000:.2f}万元') print(f'历史模拟法1天、95%的VaR:{VaR95_1day_history/10000:.2f}万元')print(f'历史模拟法10天、95%的VaR:{VaR95_10day_history/10000:.2f}万元')

结果为:

历史模拟法1天、99%的VaR:725.59万元历史模拟法10天、99%的VaR:2294.51万元历史模拟法1天、95%的VaR:333.50万元历史模拟法10天、95%的VaR:1054.62万元

3.4 蒙特卡罗模拟法

其服从 t分布的 Python 程序如下:

value = 100000000 #投资组合市值为1亿元#投资组合各资产权重weights = np.array([0.15,0.20,0.5,0.05,0.1])m = 10000 #模拟次数e1 = np.random.standard_t(df=len(ret),size=m) #自由度为收益率数据长度的t分布#e1 = np.random.standard_normal(size=m) #若服从正态分布,则此代码代替上行代码R_mean_year = ret.mean()*252 #计算每一资产的年化平均收益率R_vol_year = ret.std()*np.sqrt(252) #计算每一资产的年化波动率dt=1/252 #时间间隔S0=np.ones(len(weights))S=np.zeros(shape=(m,len(weights))) #存放(模拟次数×资产数量)个模拟价格数据for i in range(len(weights)):#代入随机过程S[:,i]=S0[i]*(np.exp((R_mean_year[i]-0.5*R_vol_year[i]**2)*dt+R_vol_year[i]*e1*np.sqrt(dt)))#每一行∑资产收益率×相应权重就得到资产组合的收益率,一共10000行Sp_ret=(np.dot(S/S0-1,weights)) #资产组合收益率#蒙特卡洛模拟法计算VaRVaR99_1day_MS = value*abs(np.percentile(Sp_ret,1)) VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MSVaR95_1day_MS = value*abs(np.percentile(Sp_ret,5))VaR95_10day_MS = np.sqrt(10)*VaR95_1day_MS#由于抽样随机数的原因,结果可能会有不同print(f'蒙特卡罗模拟法1天、99%的VaR:{VaR99_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、99%的VaR:{VaR99_10day_MS/10000:.2f}万元') print(f'蒙特卡罗模拟法1天、95%的VaR:{VaR95_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、95%的VaR:{VaR95_10day_MS/10000:.2f}万元')

由于是随机模拟,每次估算的VaR不一致,某次运行的结果为:

蒙特卡罗模拟法1天、99%的VaR:701.11万元蒙特卡罗模拟法10天、99%的VaR:2217.12万元蒙特卡罗模拟法1天、95%的VaR:508.27万元蒙特卡罗模拟法10天、95%的VaR:1607.30万元

四、全套代码

4.1 计算单一资产的VaR

import pandas as pdimport numpy as npimport akshare as akimport scipy.stats as st# 读入中国平安 「000001」 -01-01 到 -12-31 日收盘价数据data = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="0101", end_date='1231', adjust="")data.index = pd.to_datetime(data['日期'],format='%Y-%m-%d') #设置日期索引close = data['收盘'] #日收盘价ret = np.log(close/close.shift(1)) #日收益率ret = ret.dropna()value = 1000000 #中国平安股票价值为100万元R_mean = ret.mean() #计算均值R_vol = ret.std() #计算标准差#方差协方差法def VaR_VCM(value,mu,sig,X,T):'''Parameters----------value : 资产的价值mu : 资产的日均收益率sig : 资产的日均波动率(标准差)X : 置信水平T : 持有天数 ''' z = abs(st.norm.ppf(q=1-X)) return np.sqrt(T)*value*(z*sig-mu)VaR99_1day_VCM = VaR_VCM(value,R_mean,R_vol, 0.99, 1)VaR99_10day_VCM = VaR_VCM(value,R_mean,R_vol, 0.99, 10)VaR95_1day_VCM = VaR_VCM(value,R_mean,R_vol, 0.95, 1)VaR95_10day_VCM = VaR_VCM(value,R_mean,R_vol,0.95, 10)print(f'方差-协方差法1天、99%的VaR:{VaR99_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、99%的VaR:{VaR99_10day_VCM/10000:.2f}万元') print(f'方差-协方差法1天、95%的VaR:{VaR95_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、95%的VaR:{VaR95_10day_VCM/10000:.2f}万元') #历史模拟法def VaR_history(value,ret,X,T):'''Parameters----------value : 资产的价值ret : 资产的日收益率序列X : 置信水平T : 持有天数 ''' # Numpy 的 percentile 函数,可以直接返回序列相应的分位数return value*np.sqrt(T)*abs(np.percentile(ret,(1-X)*100))VaR99_1day_history = VaR_history(value,ret,0.99,1)VaR99_10day_history = VaR_history(value,ret,0.99,10)VaR95_1day_history = VaR_history(value,ret,0.95,1)VaR95_10day_history = VaR_history(value,ret,0.95,10)print(f'历史模拟法1天、99%的VaR:{VaR99_1day_history/10000:.2f}万元')print(f'历史模拟法10天、99%的VaR:{VaR99_10day_history/10000:.2f}万元') print(f'历史模拟法1天、95%的VaR:{VaR95_1day_history/10000:.2f}万元')print(f'历史模拟法10天、95%的VaR:{VaR95_10day_history/10000:.2f}万元') #蒙特卡洛模拟法m = 10000 #模拟次数e1 = np.random.standard_t(df=len(ret),size=m) #自由度为收益率数据长度的t分布#e1 = np.random.standard_normal(size=m) #若服从正态分布,则此代码代替上行代码R_mean_year = ret.mean()*252 #计算每一资产的年化平均收益率R_vol_year = ret.std()*np.sqrt(252) #计算每一资产的年化波动率dt=1/252 #时间间隔S0=1S=np.zeros(m) #存放模拟次数个模拟价格数据#代入随机过程S=S0*(np.exp((R_mean_year-0.5*R_vol_year**2)*dt+R_vol_year*e1*np.sqrt(dt)))F_ret=S/S0-1 #模拟未来收益率#蒙特卡洛模拟法计算VaRVaR99_1day_MS = value*abs(np.percentile(F_ret,1)) VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MSVaR95_1day_MS = value*abs(np.percentile(F_ret,5))VaR95_10day_MS = np.sqrt(10)*VaR95_1day_MS#由于抽样随机数的原因,结果可能会有不同print(f'蒙特卡罗模拟法1天、99%的VaR:{VaR99_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、99%的VaR:{VaR99_10day_MS/10000:.2f}万元') print(f'蒙特卡罗模拟法1天、95%的VaR:{VaR95_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、95%的VaR:{VaR95_10day_MS/10000:.2f}万元')

4.2 计算资产组合的VaR

import pandas as pdimport numpy as npimport akshare as akimport scipy.stats as st# 读入5支股票 -01-01 到 -12-31 日收盘价数据def get_ret(code):data = ak.stock_zh_a_hist(symbol=code, period="daily", start_date="0101", end_date='1231', adjust="")data.index = pd.to_datetime(data['日期'],format='%Y-%m-%d') #设置日期索引close = data['收盘'] #日收盘价close.name = coderet = np.log(close/close.shift(1)) #日收益率return retcodes=['000001','000651','300015','600519','000625']ret = pd.DataFrame()for code in codes:ret_ = get_ret(code)ret = pd.concat([ret,ret_],axis=1)ret = ret.dropna()value = 100000000 #投资组合市值为1亿元R_mean = ret.mean() #计算均值R_cov = ret.cov() #计算协方差R_vol = ret.std() #计算标准差#投资组合各资产权重weights = np.array([0.15,0.20,0.5,0.05,0.1])#方差协方差法#计算投资组合的期望收益率Rp_daily = np.sum(weights*R_mean)#计算投资组合的日波动率Vp_daily = np.sqrt(np.dot(weights,np.dot(R_cov,weights.T)))def VaR_VCM(value,mu,sig,X,T): '''Parameters----------value : 资产的价值mu : 资产的日均收益率sig : 资产的日均波动率(标准差)X : 置信水平T : 持有天数 ''' z = abs(st.norm.ppf(q=1-X)) return np.sqrt(T)*value*(z*sig-mu)VaR99_1day_VCM = VaR_VCM(value,Rp_daily,Vp_daily, 0.99, 1)VaR99_10day_VCM = VaR_VCM(value,Rp_daily,Vp_daily, 0.99, 10)VaR95_1day_VCM = VaR_VCM(value,Rp_daily,Vp_daily, 0.95, 1)VaR95_10day_VCM = VaR_VCM(value,Rp_daily,Vp_daily,0.95, 10)print(f'方差-协方差法1天、99%的VaR:{VaR99_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、99%的VaR:{VaR99_10day_VCM/10000:.2f}万元') print(f'方差-协方差法1天、95%的VaR:{VaR95_1day_VCM/10000:.2f}万元')print(f'方差-协方差法10天、95%的VaR:{VaR95_10day_VCM/10000:.2f}万元') #历史模拟法#历史交易日投资组合的收益率序列Rp = np.dot(ret,weights)Rp = pd.DataFrame(Rp,index=ret.index,columns=['投资组合日收益'])def VaR_history(value,ret,X,T):'''Parameters----------value : 资产的价值ret : 资产的日收益率序列X : 置信水平T : 持有天数 ''' # Numpy 的 percentile 函数,可以直接返回序列相应的分位数return value*np.sqrt(T)*abs(np.percentile(ret,(1-X)*100))VaR99_1day_history = VaR_history(value,Rp,0.99,1)VaR99_10day_history = VaR_history(value,Rp,0.99,10)VaR95_1day_history = VaR_history(value,Rp,0.95,1)VaR95_10day_history = VaR_history(value,Rp,0.95,10)print(f'历史模拟法1天、99%的VaR:{VaR99_1day_history/10000:.2f}万元')print(f'历史模拟法10天、99%的VaR:{VaR99_10day_history/10000:.2f}万元') print(f'历史模拟法1天、95%的VaR:{VaR95_1day_history/10000:.2f}万元')print(f'历史模拟法10天、95%的VaR:{VaR95_10day_history/10000:.2f}万元') #蒙特卡罗模拟法m = 10000 #模拟次数e1 = np.random.standard_t(df=len(ret),size=m) #自由度为收益率数据长度的t分布#e1 = np.random.standard_normal(size=m) #若服从正态分布,则此代码代替上行代码R_mean_year = ret.mean()*252 #计算每一资产的年化平均收益率R_vol_year = ret.std()*np.sqrt(252) #计算每一资产的年化波动率dt=1/252 #时间间隔S0=np.ones(len(weights))S=np.zeros(shape=(m,len(weights))) #存放(模拟次数×资产数量)个模拟价格数据for i in range(len(weights)):#代入随机过程S[:,i]=S0[i]*(np.exp((R_mean_year[i]-0.5*R_vol_year[i]**2)*dt+R_vol_year[i]*e1*np.sqrt(dt)))#每一行∑资产收益率×相应权重就得到资产组合的收益率,一共10000行Sp_ret=(np.dot(S/S0-1,weights)) #资产组合收益率#蒙特卡洛模拟法计算VaRVaR99_1day_MS = value*abs(np.percentile(Sp_ret,1)) VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MSVaR95_1day_MS = value*abs(np.percentile(Sp_ret,5))VaR95_10day_MS = np.sqrt(10)*VaR95_1day_MS#由于抽样随机数的原因,结果可能会有不同print(f'蒙特卡罗模拟法1天、99%的VaR:{VaR99_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、99%的VaR:{VaR99_10day_MS/10000:.2f}万元') print(f'蒙特卡罗模拟法1天、95%的VaR:{VaR95_1day_MS/10000:.2f}万元')print(f'蒙特卡罗模拟法10天、95%的VaR:{VaR95_10day_MS/10000:.2f}万元')

参考资料:

/hzk427/article/details/104940735

/qq_18822147/article/details/108303843

/wxw_csdn/article/details/16787?spm=1001..3001.5506

如果觉得《【Python量化】VaR在险价值的计算》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。