混合法介绍
Age-Weighted Historical Simulation
The hybrid approach combines techniques of both parametric and nonparametric methods to estimate volatility using historical data.The obvious adjustment to the equal-weighted assumption used in historical simulation is to weight recent observations more and distant observations less. One method proposed by Boudoukh, Richardson, and Whitelaw is as follows.
Assume w(1) is the probability weight for the observation that is one day old. Then w(2) can be defined as λw(1), w(3) can be defined as λ²w(1), and so on. The decay parameter, λ, can take on values 0 ≤ λ ≤ 1 where values close to 1 indicate slow decay. Since all of the weights must sum to 1, we conclude that w(1) = (1 − λ) / (1 − λn). More generally, the weight for an observation that is i days old is equal to w(i) = λi-1(1 − λ) / (1 − λn).
For example, assume 100 observations and a decay factor of 0.96. For the hybrid weight for an observation that occurred one period ago, you would use the following equation: [(1 − 0.96) / (1 − 0.96100)] = 0.0407. For the hybrid weight five periods ago would equal: [(1 − 0.96) / (1 − 0.96100)] × 0.964= 0.0346.
Step 1: Assign weights for historical realized returns to the most recent K returns using an exponential smoothing process mentioned above;
Step 2: Order the returns;
Step 3: Determine the VaR for the portfolio by starting with the lowest return and accumulating the weights until x percentage is reached. Linear interpolation may be necessary to achieve an exact x percentage.
Volatility-Weighted Historical Simulation
If volatility(0) is the current (today’s) volatility estimate and volatility(t) is the volatility estimate on a previous day(t), then each historical return(t) is replaced by: return(t*) = return(t) × volatility(0) / volatility(t). Then conduct typical historical simulation(HS) on adjusted return series. It produces superior VaR estimates to the former one.
案例
假设今天是2020年1月1日,分析师有某一基金过去一年(2019年244个交易日)的日收益率数据,根据上述步骤选取最近的K=100个数据,使用混合法(Age-Weighted Historical Simulation)计算该基金5%的VaR,衰减因子λ = 0.96。
step1:选出244个数据中最近的100个数据(2019年8月6日至2019年12月31日)作为我们的观察值,对数据的新旧程度排名(如最靠近今天的数据排名第1),并按照收益率进行升序排序。
#排序后的100条数据概览
m=pd.DataFrame({'收益率':data,'新旧排名':range(100,0,-1)})
df=m.sort_values(by='收益率',ascending=True)
df
Out[1]:
收益率 新旧排名
2019-11-22 -0.026525 28
2019-09-26 -0.020891 64
2019-10-23 -0.020097 50
2019-10-18 -0.019972 53
2019-08-30 -0.019313 82
... ..
2019-08-19 0.019956 91
2019-09-27 0.020626 63
2019-09-02 0.022611 81
2019-09-09 0.023142 76
2019-10-10 0.034091 59
[100 rows x 2 columns]
step2:由于我们是计算5%的VaR,因此只需要用到前面的几个收益率数据,下面我们找出前10低的收益率并计算它们的权重和累计权重,其中在计算权重时 i 按照该数据的新旧程度排名来算:
data10=df.head(10)
data10
Out[3]:
收益率 新旧排名
date
2019-11-22 -0.026525 28
2019-09-26 -0.020891 64
2019-10-23 -0.020097 50
2019-10-18 -0.019972 53
2019-08-30 -0.019313 82
2019-10-15 -0.018430 56
2019-11-25 -0.017030 27
2019-09-30 -0.015331 62
2019-11-11 -0.014726 37
2019-08-26 -0.011552 86
d=0.96;k=100
w=pd.DataFrame([(0.96**(i-1))*(1-d)/(1-d**k) for i in data10['新旧排名'].values],columns=['权重'])
acc_w=w.cumsum()
acc_w.columns=['累积权重']
weight=pd.concat([w,acc_w],axis=1)
weight.index=data10.index
table=pd.concat([data10,weight],axis=1)
table
Out[9]:
收益率 新旧排名 权重 累积权重
date
2019-11-22 -0.026525 28 0.013514 0.013514
2019-09-26 -0.020891 64 0.003108 0.016622
2019-10-23 -0.020097 50 0.005505 0.022127
2019-10-18 -0.019972 53 0.004870 0.026997
2019-08-30 -0.019313 82 0.001491 0.028488
2019-10-15 -0.018430 56 0.004309 0.032797
2019-11-25 -0.017030 27 0.014077 0.046874
2019-09-30 -0.015331 62 0.003373 0.050246
2019-11-11 -0.014726 37 0.009359 0.059605
2019-08-26 -0.011552 86 0.001266 0.060871
step3:可见置信水平为95%的VaR位于0.017和0.0153之间,可以用插值法来算。最终算出该基金5%的VaR(窗口期为100)为1.55%。
from scipy.interpolate import interp1d
acc=np.array([0.046874,0.050246])#输入相邻累计权重的数组
r=np.array([-0.017030,-0.015331])#输入相邻累计权重对应的收益率数组
accnew=np.array([0.046874,0.05,0.050246])
f=interp1d(x=acc,y=r,kind='linear')
rnew=abs(f(accnew))
print('95%的VaR为{:.4f}'.format(rnew[1]))
95%的VaR为0.0155
#更普遍的,table为K行的数据框时直接计算VaR:
table
Out[9]:
收益率 新旧排名 权重 累积权重
date
2019-11-22 -0.026525 28 0.013514 0.013514
2019-09-26 -0.020891 64 0.003108 0.016622
2019-10-23 -0.020097 50 0.005505 0.022127
2019-10-18 -0.019972 53 0.004870 0.026997
2019-08-30 -0.019313 82 0.001491 0.028488
... ... ... ...
2019-08-19 0.019956 91 0.001032 0.989492
2019-09-27 0.020626 63 0.003238 0.992730
2019-09-02 0.022611 81 0.001553 0.994283
2019-09-09 0.023142 76 0.001905 0.996188
2019-10-10 0.034091 59 0.003812 1.000000
[100 rows x 4 columns]
c=0.90
for i in range(k-1):
if table.iloc[i,3]<1-c<=table.iloc[i+1,3]:
acci,accj=table.iloc[i,3],table.iloc[i+1,3]
ri,rj=table.iloc[i,0],table.iloc[i+1,0]
elif 1-c<table.iloc[0,3]:
print('数据不足!')
break
acc=np.array([acci,accj])
r=np.array([ri,rj])
accnew=np.array([acci,1-c,accj])
f=interp1d(x=acc,y=r,kind='linear')
print('{}%的VaR为{:.4f}'.format(100*c,abs(f(accnew)[1])))
90.0%的VaR为0.0093
注意,随着时间的推移,极端负收益率可能会有变化,比如产生了新的极端值或者旧的极端负收益被淘汰出window,即使没变化每一数据的权重也会发生变化,因此需要定期调整VaR的结果。