【Python量化】VaR在险价值的计算
文章目录
- 一、VaR的定义
- 二、计算单一资产的VaR
- 2.1 数据概况
- 2.2 方差-协方差法
- 2.3 历史模拟法
- 2.4 蒙特卡罗模拟法
- 三、计算资产组合的VaR
- 3.1 数据概况
- 3.2 方差-协方差法
- 3.3 历史模拟法
- 3.4 蒙特卡罗模拟法
- 四、全套代码
- 4.1 计算单一资产的VaR
- 4.2 计算资产组合的VaR
此文章首发于微信公众号:Python for Finance
链接:https://mp.weixin.qq.com/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 pd
import numpy as np
import akshare as ak
import scipy.stats as st# 读入中国平安 「000001」 2015-01-01 到 2021-12-31 日收盘价数据
data = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="20150101", end_date='20211231', adjust="")
data.index = pd.to_datetime(data['日期'],format='%Y-%m-%d') #设置日期索引
close = data['收盘'] #日收盘价
ret = np.log(close/close.shift(1)) #日收益率
ret = ret.dropna()
获取的数据如下:
>>>ret
日期
2015-01-06 -0.015095
2015-01-07 -0.019194
2015-01-08 -0.034169
2015-01-09 0.007989
2015-01-12 -0.0207712021-12-27 -0.005213
2021-12-28 -0.002908
2021-12-29 -0.024765
2021-12-30 0.004170
2021-12-31 -0.020421
Name: 收盘, 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=μtStdt+σtStdWt
简化处理,得到特定时期(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=Ste(μ−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=1
S=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 #模拟未来收益率#蒙特卡洛模拟法计算VaR
VaR99_1day_MS = value*abs(np.percentile(F_ret,1))
VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MS
VaR95_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),权重占比如下:
资产名称 | 中国平安 | 格力电器 | 爱尔眼科 | 立讯精密 | 长安汽车 |
---|---|---|---|---|---|
权重 | 0.15 | 0.2 | 0.5 | 0.05 | 0.1 |
使用方差-协方差法、历史模拟、蒙特卡洛模拟法来计算组合的 VaR 值。
在计算之前,首先需要获取到中国平安的历史股价数据,这里我们使用 AKShare包。它是一个免费、开源的 Python 财经数据接口包。AKShare返回的绝大部分的数据格式都是 pandas DataFrame 类型,非常便于用 pandas/ NumPy/ Matplotlib 进行数据分析和可视化。
import pandas as pd
import numpy as np
import akshare as ak
import scipy.stats as st# 读入5支股票 2015-01-01 到 2021-12-31 日收盘价数据
def get_ret(code):data = ak.stock_zh_a_hist(symbol=code, period="daily", start_date="20150101", end_date='20211231', 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
2015-01-06 -0.015095 0.021099 0.083902 -0.023431 0.068956
2015-01-07 -0.019194 -0.001681 -0.029017 -0.025029 0.007205
2015-01-08 -0.034169 0.003360 -0.000342 -0.006135 0.010204
2015-01-09 0.007989 -0.017888 0.000342 -0.007590 -0.044106
2015-01-12 -0.020771 0.028848 0.042888 -0.020598 0.074108... ... ... ... ...
2021-12-27 -0.005213 0.054392 0.018817 -0.028791 -0.017700
2021-12-28 -0.002908 0.005571 -0.008905 0.002979 0.024176
2021-12-29 -0.024765 -0.026268 -0.002526 -0.046515 -0.018899
2021-12-30 0.004170 0.000272 0.003672 0.016521 -0.002635
2021-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)) #资产组合收益率#蒙特卡洛模拟法计算VaR
VaR99_1day_MS = value*abs(np.percentile(Sp_ret,1))
VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MS
VaR95_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 pd
import numpy as np
import akshare as ak
import scipy.stats as st# 读入中国平安 「000001」 2015-01-01 到 2021-12-31 日收盘价数据
data = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="20150101", end_date='20211231', 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=1
S=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 #模拟未来收益率#蒙特卡洛模拟法计算VaR
VaR99_1day_MS = value*abs(np.percentile(F_ret,1))
VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MS
VaR95_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 pd
import numpy as np
import akshare as ak
import scipy.stats as st# 读入5支股票 2015-01-01 到 2021-12-31 日收盘价数据
def get_ret(code):data = ak.stock_zh_a_hist(symbol=code, period="daily", start_date="20150101", end_date='20211231', 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)) #资产组合收益率#蒙特卡洛模拟法计算VaR
VaR99_1day_MS = value*abs(np.percentile(Sp_ret,1))
VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MS
VaR95_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}万元')
参考资料:
https://blog.csdn.net/hzk427/article/details/104940735
https://blog.csdn.net/qq_18822147/article/details/108303843
https://blog.csdn.net/wxw_csdn/article/details/120206787?spm=1001.2014.3001.5506
【Python量化】VaR在险价值的计算相关推荐
- 移植 Python 量化交易 TA-Lib 库到函数计算
TA-Lib,全称"Technical Analysis Library", 即技术分析库,是 Python 金融量化的高级库,涵盖了 150 多种股票.期货交易软件中常用的技术分 ...
- python 在险价值_Python计算股票投资组合的风险价值(VaR)
在开始之前,请注意,标准VaR计算假定以下条件: 收益的正态分布 -VaR假设投资组合的收益是正态分布.对于大多数资产而言,这当然是不现实的,但允许我们使用更为简单的计算来制定基准. (可以对VaR进 ...
- 股票python量化交易012-使用shift函数计算涨跌幅
认识shift函数 简单理解就是可以把数据整体进行偏移,如csv中的某列数据整体下移一行 ================> 转换后变为: 转换后就得到一张临时的一张表,然后可以用这张临时表的数 ...
- 【FinE】在险价值(VaR)计算
导航 VaR模型 案例:AAPL 历史模拟法 参数模型分析法 非参数bootstrap Monte-Carlo模拟计算 参考资料 VaR模型 在险价值Value-at-risk的定义为,在一定时期Δt ...
- Python蒙特卡罗(Monte Carlo)模拟计算投资组合的风险价值(VaR)
最近我们被客户要求撰写关于风险价值(VaR)的研究报告,包括一些图形和统计输出. 如何使用Python通过蒙特卡洛模拟自动计算风险值(VaR)来管理投资组合或股票的金融风险. 金融和投资组合风险管理中 ...
- matlab计算 var,matlab 在险价值 VaR 的计算
matlab 在险价值 VaR 的计算 matlab 在险价值 VaR 的计算 VaR 模型 数据获取 历史模拟法 蒙特卡罗模拟法 参数模型法 代码和数据下载 VaR 模型 Value at Risk ...
- matlab 在险价值 VaR 的计算
matlab 在险价值 VaR 的计算 matlab 在险价值 VaR 的计算 VaR 模型 数据获取 历史模拟法 蒙特卡罗模拟法 参数模型法 代码和数据下载 VaR 模型 Value at Risk ...
- R语言用GARCH模型波动率建模和预测、回测风险价值 (VaR)分析股市收益率时间序列...
原文链接:http://tecdat.cn/?p=26897 风险价值 (VaR) 是金融风险管理中使用最广泛的市场风险度量,也被投资组合经理等从业者用来解释未来市场风险(点击文末"阅读原文 ...
- VaR(value at risk)在险价值
VaR,即Value at Risk,它是一种定量衡量风险的指标. 在险价值是指在一定概率下,某种投资组合在某段时间 内的最大损失. VaR的方法有:历史模拟方法,正态方法,蒙特卡洛方法,压力测试法. ...
最新文章
- Python-Numpy(3)矩阵基本操作
- nginx+awstats多域名日志分析2
- Latent dirichlet allocation note
- 金色丰收的FreeEIM季节
- QML笔记-QML基本数据类型的使用
- (王道408考研数据结构)第二章线性表-第三节3:循环单链表和循环双链表
- linux中 ls |wc -l
- 【深入理解Java虚拟机学习笔记】第二章 Java 内存区域与内存溢出异常
- BigDFT的编译运行
- 微信小程序显示列表数据
- Win10磁盘管理教程:新建、合并分区,添加和修改盘符
- AI足球预测软件|足球大数据预测分析爬虫
- 笔记本电脑装android系统安装教程,电脑安装安卓系统教程 三分钟教学换装系统...
- dtools: error while loading shared libraries: libicui18n.so.55: cannot open shared object file
- 第三届蓝桥杯Java组 黄金队列
- 微信小程序3-模板与配置
- 数据结构实验整理(一)
- 论文笔记:Prefix-Tuning: Optimizing Continuous Prompts for Generation
- Kepware与 smart200建立连接的方法
- 中国游戏辅助写手回忆录(自传小说)