思路简介
每一次蒙特卡洛模拟,对资产组合中的每一资产按照随机过程公式模拟出下一个交易日的价格,公式中的ε可以假定服从t分布或正态分布(即资产收益率服从的分布),然后可以得到每一资产的收益率,乘以各自的权重和市值就能得到每一资产在下一个交易日的收益,全部相加就是该资产组合在下一个交易日的模拟收益。
比如蒙特卡罗模拟法的抽样次数是10000次,通过重复以上的步骤可以得到组合收益的10000个不同的样本值,持有期1天、置信水平95%的投资组合风险价值就对应于样本数值中排在第500位最大损失的取值。
案例分析
依然以(四十三)中的案例为例,计算该资产组合持有期为1天、置信水平为99%情况下的VaR,同时假定ε在模拟过程中服从正态分布或t分布。ε服从t分布时:
import numpy as np
I=10000
e1=np.random.standard_t(df=len(R),size=I)#自由度为收益率数据长度的t分布
e2=np.random.standard_normal(size=I)
S0=np.array(data.iloc[-1])#每一资产最后一个交易日的价格
Rmean=R.mean()*252#计算每一资产的μ
Rvol=R.std()*np.sqrt(252)#计算每一资产的σ
dt=1/252#时间间隔
S=np.zeros(shape=(I,len(w)))#存放10000×5个模拟价格数据
for i in range(len(w)):#代入随机过程S[:,i]=S0[i]*np.exp((Rmean[i]-0.5*Rvol[i]**2)*dt+Rvol[i]*e1*np.sqrt(dt))
#每一行∑资产收益率×相应权重市值就得到一个资产组合的收益,一共10000行
Sp=(np.dot(S/S0-1,w))*1e8
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
plt.hist(Sp,bins=40,edgecolor='k')
plt.xlabel('模拟的投资组合日收益额')
plt.ylabel('频数')
plt.title('蒙特卡洛模拟投资组合日收益额直方图(t分布)')
plt.grid()
VaR99_1day=abs(np.percentile(Sp,1))
VaR99_1day
Out[11]: 2017308.9989261786
ε服从正态分布时:
S=np.zeros(shape=(I,len(w)))
for i in range(len(w)):S[:,i]=S0[i]*np.exp((Rmean[i]-0.5*Rvol[i]**2)*dt+Rvol[i]*e2*np.sqrt(dt))
Sp2=(np.dot(S/S0-1,w))*1e8
VaR99_1day=abs(np.percentile(Sp2,1))
VaR99_1day
Out[11]: 2008156.813210965
从结果来看,当资产收益率服从正态分布时,蒙特卡洛模拟计算的组合VaR值低于服从t分布的VaR值(大部分情况下)。