金融风险管理作业之三,接简易损失分布法计量操作性风险。做作业的时候,从0开始这部分,找了篇文献作为参考,能省略的变量都省略了,不保证正确,就简单记录一下。欢迎大家批评指正!!!
状态空间模型的构建:
假设时变参数符合随机游走过程:
(1) |
其中,为截距项,为因子i的因子暴露。
将时变参数服从随机游走过程的市场模型表示成状态空间模型的标准形式,如下:
(2) |
|
(3) |
进一步化简得:
(5) |
|
(6) |
其中,式(4)为状态方程,式(5)为量测方程,为资产收益率,为市场风险因子,为市场风险因子的因子暴露,即状态变量,,为的单位矩阵,为的零矩阵,,均服从正态分布。
卡尔曼滤波:
第一步,确定初始值。假设存在k个解释变量。首先,用k+1期数据回归得到,并依据得到下一期状态变量的预测值。用k+2期数据回归得,依据式(6)计算。将作为初始状态变量和方差协方差矩阵
(7) |
第二步,预测。为t+1期市场风险因子的值(含常数项),为t+1期资产收益率的值。依据式(7)(8)预测。同时,依据式(10)(11)计算预测误差和预测误差平方。重复第二步,不断向下预测,直至所有数据全部用完。
(7) |
|
(8) |
|
(9) |
|
(10) |
|
(11) |
第三步,更新。依据预测误差对进行修正
(12) |
|
(13) |
import numpy as np#引入库
from numpy import *
import pandas as pd
import xlrd
path="D:\\julia\\china4(1).xlsx"
data=pd.read_excel(path)#读取excel中的数据
data=data.values#提取dataframe中的值转化为array
Y=data[:,1:2]#读取data的第二列作为被解释变量(第一列是时间)
Y=mat(Y)#转变为矩阵形式
X=data[:,2:]#读取data第二列以后的所有列作为被解释变量
X=mat(X)
beta=(((X.T)*(X)).I)*(X.T)*Y#计算各因子系数
def beta(data,t):#回归前t期数据的beta值
Y=data[0:t,1:2]#读取前t期的被解释变量
Y=mat(Y)
X=data[:t,2:]#读取前t期的解释变量
X=mat(X)
beta=(((X.T)*(X)).I)*(X.T)*Y#计算beta
return beta
at_=beta(data,6)
T=np.eye(len(at_))#生成和解释变量个数相一致的单位矩阵
atpredict=T*at_#依据上一期的状态变量对初始状态变量进行预测
at=beta(data,7)#设定初始状态变量
Pt=((atpredict-at)*((atpredict-at).T))#计算初始协方差矩阵
a=[]#用于记录各期的a(beta)和P
P=[]
a.append(at)#先将初始的a(beta)和P放进去
P.append(Pt)
for i in range(8,len(X)):#卡尔曼滤波
#预测
at_1=T*at#依据t期估计t+1期,a(t_1|t)
Pt_1=T*Pt*(T.T)#P(t_1|t)
xt_1=data[i-1:i,2:]#提取t_1期的解释变量
yt_1=data[i-1:i,1:2]#t_1期被解释变量的实际值
ytpredict_1=xt_1*at_1#t_1期被解释变量的预测值
vt_1=yt_1-ytpredict_1#预测误差
Ft_1=vt_1*(vt_1.T)#预测误差的平方
#更新
at_1=at_1+Pt_1*(xt_1.T)*(Ft_1.I)*vt_1#依据误差对at_1,Pt_1进行更新
Pt_1=Pt_1-(Pt_1.T)*(xt_1.T)*(Ft_1.I)*xt_1*Pt_1
a.append(at_1)#把更新后的a(beta)和P记录下来
P.append(Pt_1)
f=open("D:\\julia\\beta.csv","a")#打开文件,追加写(循环重复写入)
for i in range(0,len(a)):#遍历每一期的a(beta)
m=""#将每一期的a(beta)值放入一行字符串中
for j in range(0,len(a[i])):
m=m+str(a[i][j])+","
m=m+"\n"
f.write(m)#写入csv文件
f.close()#关闭文件
之后,我使用依据Liu et al. (2019)发表《SIZE AND VALUE IN CHINA》中的方法,计算的市场因子、SMB因子(EP加权)、VMG因子(高EP减去低EP)、PMO因子(高换手率-低换手率)作为解释变量,以动量策略收益(形成期为12个月,持有期为1个月)为被解释变量,运行以上代码,得到的结果如下:
时间段较短,结果比较稳定,但拉长时间段后,会出现偏离幅度较大的误差值,比如出现因子暴露是200等,所以程序还是有点儿bug。 后期我们将把状态空间+卡尔曼滤波应用于我们的大创项目,欢迎大佬们批评指正!!!