金融分析与风险管理——风险价值(VaR)
金融分析與風險管理——風險價值(VaR)
- 1. 風險價值(VaR)簡述
- 1.1 Python可視化風險價值
- 2. VaR值的測度方法
- 2.1 方差-協方差法
- 2.2 歷史模擬法
- 2.3 蒙特卡洛模擬法
- 3. 回溯檢驗
- 4. 壓力VaR
1. 風險價值(VaR)簡述
風險價值(value at risk,VaR)是指在一定的持有期和給定的置信水平下,利率、匯率、股價等風險因子發生變化時可能對投資組合造成的潛在最大損失。例如:持有期 1 天、置信水平 95% 的情況下,計算得到的 VaR 值為 1000 萬元,則表明該投資組合在1天中有 95%的可能性損失不會超過1000萬,換句話說,1 天中,有5%的可能性損失會超過 1000 萬元。
VaR的大小取決于兩個參數:持有期(N)、置信水平(X)。由于 VaR 度量的是投資組合的虧損,其對應于投資組合盈虧分布的左端尾部,為了表述方便,通常 VaR 值用絕對值表示。
VaR 的數學表達式如下:
Prob(ΔP<?VaR)=1?XProb:概率函數ΔP:投資組合虧損金額X:置信水平Prob(\Delta P < - VaR) = 1 - X \\[10pt] Prob:概率函數 \\[10pt] \Delta P:投資組合虧損金額 \\[10pt] X:置信水平 Prob(ΔP<?VaR)=1?XProb:概率函數ΔP:投資組合虧損金額X:置信水平
根據巴塞爾協議的明確規定:銀行需要計算持有期10天、置信水平99%的VaR。在實際計算中,通常先計算 N=1 時的VaR,在計算相同置信水平下 N>1 時的 VaR,其表達式如下:
N天VaR=1天VaR?NN天VaR = 1天VaR*\sqrt{N}N天VaR=1天VaR?N?
上式成立的條件是:投資組合價值在不同交易日之間的變化是相互獨立并服從期望值為0的相同正態分布,其他情況下,該等式只是一個近似值。
1.1 Python可視化風險價值
利用Python對VaR進行可視化,圖中陰影部分右側的臨界值就是對應置信水平的VaR,其程序如下:
import numpy as np import pandas as pd import scipy.stats as st ''' st.norm中的子模塊 pdf:概率密度函數 cdf:累計概率分布函數 ppf:分位點函數,cdf的反函數 '''import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei'] #中文顯示問題 plt.rcParams['axes.unicode_minus'] = False #負數顯示問題a = 0.95 #置信水平 z = st.norm.ppf(q=1-a) #返回q對應的分位點 x = np.linspace(-4,4,200) #組合的盈虧數組 y = st.norm.pdf(x) #組合盈虧對應的概率密度數組 x1 = np.linspace(-4,z,100) #組合最小虧損值與返回的分位點構成的盈虧數組 y1 = st.norm.pdf(x1)plt.figure(figsize=(8,6)) plt.plot(x,y) plt.fill_between(x1, y1) plt.grid('True')2. VaR值的測度方法
2.1 方差-協方差法
數學假定:
- 1 投資組合的各風險因子服從聯合正態分布
- 2 線性假定,持有期內,投資組合的風險暴露與風險因子之間是線性相關的
其表達式如下:
VaR=Vp[zcσp?E(Rp)]E(Rp)=∑wiE(Ri)σ2=Wcov(Ri,Rj)WTVp:投資組合的最新價值zc:顯著性水平c對應的分位數絕對值E(Rp):投資組合的期望收益VaR = V_p[z_c\sigma_p - E(R_p)] \\[10pt] E(R_p) = \sum w_iE(R_i) \\[10pt] \sigma^2 = Wcov(R_i,R_j)W^{T} \\[10pt] V_p:投資組合的最新價值 \\[10pt] z_c:顯著性水平 c 對應的分位數絕對值 \\[10pt] E(R_p):投資組合的期望收益 \\[10pt] VaR=Vp?[zc?σp??E(Rp?)]E(Rp?)=∑wi?E(Ri?)σ2=Wcov(Ri?,Rj?)WTVp?:投資組合的最新價值zc?:顯著性水平c對應的分位數絕對值E(Rp?):投資組合的期望收益
本文通過一個案例來說明如何運用方差-協方差法計算投資組合的 VaR,該投資組合有 5 個不同的資產構成,投資組合當前的市值為1億元,其權重權重配比如下表:
| 權重 | 0.15 | 0.2 | 0.5 | 0.05 | 0.1 |
案例中投資組合2015年—2018年完整的數據可以通過百度網盤獲取,提取碼:zbbx。
Python程序如下:
data = pd.read_excel(r'C:\Users\Administrator\Desktop\投資組合配置的資產情況.xlsx',header = 0,index_col = 0)#初始數據的歸一化處理 R = np.log(data/data.shift(1)) #處理缺失數據 R = R.dropna() R_mean = R.mean() #計算均值 R_cov = R.cov() #計算協方差 R_corr = R.corr() #計算相關系數 R_vol = R.std() #計算標準差# 方差協方差方法 def VaR_VCM(value,Rp,Vp,X,N):'''Parameters----------value : 投資組合的價值Rp : 投資組合的日收益率Vp : 投資組合的日波動率X : 置信水平N : 持有天數'''import scipy.stats as stimport numpy as npz = np.abs(st.norm.ppf(q=1-X))return np.sqrt(N)*value*(z*Vp-Rp)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)))print('投資組合日收益率:',Rp_daily) print('投資組合日波動率:',Vp_daily)D1 = 1 D2 = 10 X1 = 0.99 X2 = 0.95 value_port = 100000000VaR99_1day_VCM = VaR_VCM(value=value_port, Rp=Rp_daily, Vp=Vp_daily, X=X1, N=D1) VaR99_10day_VCM = VaR_VCM(value=value_port, Rp=Rp_daily, Vp=Vp_daily, X=X1, N=D2) VaR95_1day_VCM = VaR_VCM(value=value_port, Rp=Rp_daily, Vp=Vp_daily, X=X2, N=D1) VaR95_10day_VCM = VaR_VCM(value=value_port, Rp=Rp_daily, Vp=Vp_daily, X=X2, N=D2)print('1天、99%的VaR:',VaR99_1day_VCM) print('10天、99%的VaR:',VaR99_10day_VCM) print('1天、95%的VaR:',VaR95_1day_VCM) print('10天、99%的VaR:',VaR95_10day_VCM)計算結果表明:持有期10天、置信水平99%的VaR=464.34萬;持有期10天、置信水平95%的VaR=325.83萬。
2.2 歷史模擬法
歷史模擬法:從當前回溯一定時期投資組合的歷史盈虧,并把歷史盈虧按照由大到小的順序排列,從中找出符合給定置信水平的盈虧值。例如:1天、置信水平95%的VaR,把歷史盈虧由大到小排列,VaR為95%的位置對應盈虧值的絕對值,或者由小到大排列,VaR為5%位置對應盈虧值的絕對值。
本文仍然使用上述案例數據進行說明,其Python程序如下:
#各資產配置 value_asset = value_port*weights #歷史交易日投資組合的盈虧值 Return_history = np.dot(R,value_asset) Return_history = pd.DataFrame(Return_history,index=R.index,columns=['投資組合模擬日收益'])#盈虧數據描述 Return_history.describe() Return_history.plot()#盈虧數據分布直方圖 plt.hist(Return_history,bins=30) plt.grid('True')#投資組合盈虧值的正態性檢驗 #KS檢驗,返回統計量及P值 st.kstest(rvs=Return_history['投資組合模擬日收益'], cdf='norm') #AD檢驗,返回統計量、顯著性水平對應的臨界值(統計量)、顯著性水平 st.anderson(x=Return_history['投資組合模擬日收益'], dist='norm') #返回統計量及P值 st.shapiro(Return_history['投資組合模擬日收益']) #返回統計量及P值 st.normaltest(Return_history['投資組合模擬日收益'])
由頻數分布直方圖、正態性檢驗的P值(P<1%)結果可知,投資組合的日收益數據不服從正態分布,運用方差—協方差方法計算的投資組合VaR值會存在偏差。使用歷史模擬法的計算程序如下:
計算結果表明:持有期10天、置信水平99%的VaR=675.38萬;持有期10天、置信水平95%的VaR=274.21萬。
2.3 蒙特卡洛模擬法
蒙特卡洛模擬法又稱隨機抽樣或統計試驗方法,即從一個給定的分布中,隨機抽取隨機數并進行計算,該方法能較好地逼近實際分布情況。
在投資組合的模擬抽樣步驟如下:
- 1 利用第 iii 個資產的當前價值(最新價值)SiS_iSi? 加總計算投資組合的當前價值SpS_pSp?。
- 2 在第 iii 個資產價值的日百分比變化 XiX_iXi? 所服從的分布中進行一次抽樣得到 xix_ixi? 。
- 3 利用抽樣獲取的 xix_ixi? 計算第 iii 個資產下一個交易日的收益金額變動 xiSix_iS_ixi?Si? 。
- 4 計算本次抽樣獲取的下一交易日投資組合的盈虧ΔSp=∑xiSi\Delta S_p = \sum x_iS_iΔSp?=∑xi?Si?。
- 5 重復上述第2-4步,并將獲取的 ΔSp\Delta S_pΔSp?按大小順序排列,從而構建投資組合在下一交易日的盈虧概率分布。
- 6 計算持有期 1 天、置信水平 X 的 VaR 值,然后計算 N天的VaRN天的VaRN天的VaR(公式:N天VaR=1天VaR?NN天VaR = 1天VaR*\sqrt{N}N天VaR=1天VaR?N?)
本文仍然使用上述案例數據進行說明,在模擬過程中,需要用到金融資產價格服從的隨機過程公式,即
St=St?Δte(μ?12σ2)Δt+σεtΔtS_t = S_{t-\Delta t}e^{(\mu-\frac{1}{2}\sigma^2)\Delta t + \sigma \varepsilon_t\sqrt{\Delta t}}St?=St?Δt?e(μ?21?σ2)Δt+σεt?Δt?
上式中 εt\varepsilon_tεt? 的模擬過程中假定服從 ttt 分布或者正態分布。
其服從 ttt 分布的 Python 程序如下:
#蒙特卡洛模擬法 import numpy.random as npr I = 10000 #模擬次數 #從學生t分布進行I次模擬 epsilon = npr.standard_t(df=len(R),size=I)#獲取最新收盤價 S1 = data.iloc[-1,0] #第一個資產的最新價格 S2 = data.iloc[-1,1] S3 = data.iloc[-1,2] S4 = data.iloc[-1,3] S5 = data.iloc[-1,4] R_mean = R.mean()*252 #投資組合各資產的年化收益 R_vol = R.std()*np.sqrt(252) #投資組合各資產的年化波動率 dt = 1/252 #年化單個交易日#模擬投資組合下一個交易日各資產的收盤價 S1_new = S1*np.exp((R_mean[0]-0.5*R_vol[0]**2)*dt + R_vol[0]*epsilon*np.sqrt(dt)) S2_new = S2*np.exp((R_mean[1]-0.5*R_vol[1]**2)*dt + R_vol[1]*epsilon*np.sqrt(dt)) S3_new = S3*np.exp((R_mean[2]-0.5*R_vol[2]**2)*dt + R_vol[2]*epsilon*np.sqrt(dt)) S4_new = S4*np.exp((R_mean[3]-0.5*R_vol[3]**2)*dt + R_vol[3]*epsilon*np.sqrt(dt)) S5_new = S5*np.exp((R_mean[4]-0.5*R_vol[4]**2)*dt + R_vol[4]*epsilon*np.sqrt(dt))#模擬投資組合下一個交易日各資產的盈虧 S1_delta = (S1_new/S1 - 1)*value_port*weights[0] S2_delta = (S2_new/S2 - 1)*value_port*weights[1] S3_delta = (S3_new/S3 - 1)*value_port*weights[2] S4_delta = (S4_new/S4 - 1)*value_port*weights[3] S5_delta = (S5_new/S5 - 1)*value_port*weights[4] #計算投資組合下一個交易日的盈虧 Sp_delta = S1_delta + S2_delta + S3_delta + S4_delta + S5_delta#下一交易日投資組合盈虧的可視化 plt.figure(figsize=(10,8)) plt.hist(Sp_delta,bins=30) plt.ylabel('頻數') plt.grid(True)#蒙特卡洛模擬法計算VaR VaR99_1day_MS = np.abs(np.percentile(a=Sp_delta,q=(1-X1)*100)) VaR95_1day_MS = np.abs(np.percentile(a=Sp_delta,q=(1-X2)*100))VaR99_10day_MS = np.sqrt(10)*VaR99_1day_MS VaR95_10day_MS = np.sqrt(10)*VaR95_1day_MS#由于抽樣隨機數的原因,結果可能會有不同 print('1天、99%的VaR:',VaR99_1day_MS) print('10天、99%的VaR:',VaR99_10day_MS) print('1天、95%的VaR:',VaR95_1day_MS) print('10天、95%的VaR:',VaR95_10day_MS)
計算結果表明:持有期10天、置信水平99%的VaR=640.81萬;持有期10天、置信水平95%的VaR=436.52萬。
其服從正態分布的 Python 程序如下:
#服從正態分布進行模擬 epsilon_norm = npr.standard_normal(I)S_new = np.zeros(shape=(I,len(R_mean)))S1_new = S1*np.exp((R_mean[0]-0.5*R_vol[0]**2)*dt + R_vol[0]*epsilon*np.sqrt(dt))for i in range(len(R_mean)):S_new[:,i] = data.iloc[-1,i]*np.exp((R_mean[i]-0.5*R_vol[i]**2)*dt + R_vol[i]*epsilon_norm*np.sqrt(dt))S = np.array(data.iloc[-1])Sp_delta_norm = (np.dot(S_new/S-1,weights))*value_portplt.figure(figsize=(10,8)) plt.hist(Sp_delta_norm,bins=30) plt.ylabel('頻數') plt.grid(True)VaR99_1day_MSnorm = np.abs(np.percentile(a=Sp_delta_norm,q=(1-X1)*100)) VaR95_1day_MSnorm = np.abs(np.percentile(a=Sp_delta_norm,q=(1-X2)*100))VaR99_10day_MSnorm = np.sqrt(10)*VaR99_1day_MSnorm VaR95_10day_MSnorm = np.sqrt(10)*VaR95_1day_MSnormprint('1天、99%的VaR:',VaR99_1day_MSnorm) print('10天、99%的VaR:',VaR99_10day_MSnorm) print('1天、95%的VaR:',VaR95_1day_MSnorm) print('10天、95%的VaR:',VaR95_10day_MSnorm)
計算結果表明:持有期10天、置信水平99%的VaR=626.17萬;持有期10天、置信水平95%的VaR=451.86萬。
3. 回溯檢驗
回溯檢驗又稱為后檢驗,即通過模型獲取的VaR與實際發生的損益進行比較,以檢驗模型的準確性、可靠性,并據此對模型進行改進及優化。
本文仍然使用上述案例進行說明,其Python程序如下:
#回溯檢測 Return_2015 = Return_history.loc['2015-01-01':'2015-12-31'] Return_2016 = Return_history.loc['2016-01-01':'2016-12-31'] Return_2017 = Return_history.loc['2017-01-01':'2017-12-31'] Return_2018 = Return_history.loc['2018-01-01':'2018-12-31']days_2015 = len(Return_2015) days_2016 = len(Return_2016) days_2017 = len(Return_2017) days_2018 = len(Return_2018)VaR_2015 = pd.DataFrame(-VaR95_1day_VCM*np.ones_like(Return_2015),index=Return_2015.index) VaR_2016 = pd.DataFrame(-VaR95_1day_VCM*np.ones_like(Return_2016),index=Return_2016.index) VaR_2017 = pd.DataFrame(-VaR95_1day_VCM*np.ones_like(Return_2017),index=Return_2017.index) VaR_2018 = pd.DataFrame(-VaR95_1day_VCM*np.ones_like(Return_2018),index=Return_2018.index)plt.figure(figsize=(9,15)) plt.subplot(4,1,1) plt.plot(Return_2015) plt.plot(VaR_2015) plt.ylabel('頻數') plt.grid(True)plt.subplot(4,1,2) plt.plot(Return_2016) plt.plot(VaR_2016) plt.ylabel('頻數') plt.grid(True)plt.subplot(4,1,3) plt.plot(Return_2017) plt.plot(VaR_2017) plt.ylabel('頻數') plt.grid(True)plt.subplot(4,1,4) plt.plot(Return_2018) plt.plot(VaR_2018) plt.ylabel('頻數') plt.grid(True)#計算超出VaR的天數 dayexcept_2015 = len(Return_2015[Return_2015['投資組合模擬日收益']<-VaR95_1day_VCM]) dayexcept_2016 = len(Return_2016[Return_2016['投資組合模擬日收益']<-VaR95_1day_VCM]) dayexcept_2017 = len(Return_2017[Return_2017['投資組合模擬日收益']<-VaR95_1day_VCM]) dayexcept_2018 = len(Return_2018[Return_2018['投資組合模擬日收益']<-VaR95_1day_VCM]) print('2015年超出風險天數:',dayexcept_2015) print('2015年超出風險天數在全年的占比:',dayexcept_2015/days_2015)print('2016年超出風險天數:',dayexcept_2016) print('2016年超出風險天數在全年的占比:',dayexcept_2016/days_2016)print('2017年超出風險天數:',dayexcept_2017) print('2017年超出風險天數在全年的占比:',dayexcept_2017/days_2017)print('2018年超出風險天數:',dayexcept_2018) print('2018年超出風險天數在全年的占比:',dayexcept_2018/days_2018)
計算結果表明:2015年超出風險天數為22天,全年占比為9.05%,明顯高于5%;2016年超出風險天數為9天,全年占比為3.69%;2017年超出風險天數為1天,全年占比為0.4%;2018年超出風險天數為6天,全年占比為2.47%。
4. 壓力VaR
壓力測試是一種以定量分析為主的風險分析方法,進而測算在小概率事件及極端情況下可能面臨的損失。壓力情景通常分為如下兩種方法:頭腦風暴和歷史重現法。
壓力風險價值具體是指當市場變量在一定壓力市場條件下通過歷史模擬法計算得到的風險價值,其計算步驟與歷史模擬法相同。
本文仍然使用上述案例進行說明,2015年6月持續數月的股災及2016年1月初的股市熔斷可以看做案例數據中的極端情況。其Python程序如下:
#壓力測試 return_stress = Return_history.loc['2015-06-15':'2016-01-07']return_stress.describe()return_zero = pd.DataFrame(np.zeros_like(return_stress),index = return_stress.index)#投資組合盈虧與0的可視化比較 plt.figure(figsize=(8,6)) plt.plot(return_stress) plt.plot(return_zero) plt.grid(True)SVaR99_1day = np.abs(np.percentile(a=return_stress,q=(1-X1)*100)) SVaR95_1day = np.abs(np.percentile(a=return_stress,q=(1-X2)*100)) SVaR99_10day = np.sqrt(10)*SVaR99_1day SVaR95_10day = np.sqrt(10)*SVaR95_1dayprint('1天、99%的VaR:',SVaR99_1day) print('10天、99%的VaR:',SVaR99_10day) print('1天、95%的VaR:',SVaR95_1day) print('10天、95%的VaR:',SVaR95_10day)
計算結果表明:持有期10天、置信水平99%的壓力VaR=1102.12萬;持有期10天、置信水平95%的壓力VaR=670.14萬。
總結
以上是生活随笔為你收集整理的金融分析与风险管理——风险价值(VaR)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单了解var
- 下一篇: SVG排版 | 毛玻璃、磨砂玻璃模板效果