matlab 在险价值 VaR 的计算
matlab 在险价值 VaR 的计算
VaR 模型
数据获取
历史模拟法
蒙特卡罗模拟法
参数模型法
代码和数据下载
VaR 模型
Value at Risk 在险价值,即 VaR。是指一定时期内,一定置信水平下,某种资产组合面临的最大损失。
Prob(Δp≤VaR)=1−αProb(\Delta p \le VaR) = 1 - \alphaProb(Δp≤VaR)=1−α
Δp\Delta pΔp 是该时期内投资组合市值变动。这个式子表示,在一定持有期 Δt\Delta tΔt 内,在给定的置信水平 1−α1- \alpha1−α 下,该投资组合的最大损失不会超过 VaR。
数据获取
在做 VaR 实战之前,我们得先获取实验数据。这部分可以参考我之前的文章。简单来说,就是需要个 tuhsare 账号,可以点去这里注册个https://tushare.pro/register?reg=126259账号,好像直接点击链接会提示风险,需要复制打地址栏打开,然后获取 自己的token,替换下文中的 token。代码如下:
close all
clear
clc
%% 数据准备
% 尝试用从tushare读取数据,如果因为版本问题读取数据失败
% 则用之前保存下来的数据进行计算
try
% 加载tushare包
addpath(genpath(pwd));
% 替换成你自己的token
token = '**************937459c8b611e0a97d0abf*******';
api = pro_api(token);
stockall = api.query('stock_basic');
% 读取数据参数设定
start_time = '0101';
end_time = '';
ktype = 'D';
% 取沪深300做为市场指数
indexdata = pro_bar('000300.SH', api, start_time, end_time,ktype,'I');
indexdata = flipud(indexdata);
% 取3支股票
nstock = 3;
% 记录用到的3支股票
stocklist = [];
stockdata = cell(nstock,1);
nday = size(indexdata,1);
% closeprice 第一列为指数价格,其他列为股票数据
closeprice = indexdata.close;
temp = indexdata.trade_date;
temp = char(temp);
temp = str2num(temp);
tradedate = datetime(temp,'ConvertFrom','yyyymmdd','format','yyyy-MM-dd');
% 获取股票数据
m = 0;
for i = 1:size(stockall,1)
temp = pro_bar(stockall.ts_code{i}, api, start_time, end_time,ktype,'E','qfq');
% 有的股票有停牌,我们得选取没有停牌的股票
if size(temp,1) == nday
m = m+1;
stockdata{m} = flipud(temp);
closeprice(:,m+1) = stockdata{m}.close;
stocklist = [stocklist;stockall(i,:)];
end
if size(stocklist,1) == nstock
break;
end
end
save('tempdata.mat');
catch
load tempdata
end
% 对所选用的股票进行绘图
plot(tradedate,closeprice(:,2))
hold on
plot(tradedate,closeprice(:,3))
plot(tradedate,closeprice(:,4))
xlabel('时间');
ylabel('股价');
legend(stocklist.name);
title('投资组合成分股股价变动图');
saveas(gcf,'投资组合成分股股价变动图.jpg');
这部分的代码我进行了容错处理,如果因为版本之类的原因,你的 matlb 无法正确运行这部分的代码,可以去文末我附的链接中下载,这部分的代码和数据,这样也能正确运行代码。这部分绘制出图像:
历史模拟法
所以历史模拟法,就是用投资组合的历史收益率经验分布的分位数来计算 VaR。代码如下:
%% 历史模拟法
% 假定每只股票买N
N = 1000;
% 假定投资组合等权重,求投资组合市值
value = (closeprice(:,2) + closeprice(:,3) + closeprice(:,4)) * N;
% 投资组合收益率
ret = price2ret(value);
figure;
subplot(2,1,1);
plot(tradedate,value);
xlabel('时间');
ylabel('组合市值');
title('投资组合市值')
subplot(2,1,2);
plot(tradedate(2:end),ret,'*');
xlabel('时间');
ylabel('收益率');
title('投资组合日收益率')
saveas(gcf,'投资组合市值及收益率.jpg');
%绘制投资组合收益率直方图
figure;
histogram(ret,20);
ylabel('天数');
xlabel('投资组合日收益率');
title('历史模拟法投资组合日收益率直方图');
saveas(gcf,'历史模拟法投资组合日收益率直方图.jpg')
%在5%置信度时,市值亏损的最大比率
Var = -prctile(ret,5) * value(end);
disp(['历史模拟法投资组合VaR为',num2str(Var)]);
首先,这边得解释一下投资组合的构建。这里是假定,每只股票持有 1000 股。然后用 prctile 函数求出经验分布的分位数。这部分结果如下:
命令行中输出:历史模拟法投资组合VaR为1860.6194
蒙特卡罗模拟法
蒙特卡罗法也就是根据历史的收益率估计出均值和波动率,然后再用这个均值和波动率,模拟出未来价格路径。在分别求每条价格路径的 VaR ,最后求其均值。若是对蒙特卡罗法本身有疑问,可以简单参考一下这篇文章
%% 蒙特卡罗模拟
%计算日收益率均值和方差
mu = mean(ret);
vol = std(ret);
% 年化波动率
vol = vol * sqrt(250);
%资产初始值
s0 = value(end);
% 模拟时长
T = 1;
% 模拟间隔点
nStep = 250;
% 模拟路径数
nPath = 1000;
%用蒙特卡洛模拟1000次
sPath = simulatePath(s0,mu,vol,T,nStep,nPath);
% 绘制蒙特卡罗法模拟路径
figure;
plot(sPath);
xlabel('模拟时间点');
ylabel('组合市值');
title('蒙特卡罗法模拟路径');
saveas(gcf,'蒙特卡罗法模拟路径.jpg')
% 计算每条模拟路径的var
ret_mc = price2ret(sPath);
Var = -mean(prctile(ret_mc,5)) * value(end);
disp(['蒙特卡罗法投资组合VaR为',num2str(Var)]);
其中 simulatePath 函数如下:
function sPath = simulatePath(S0,mu,sigma,T,nStep,nPath)
% mu=r-q
% time step
deltaT = T / nStep;
% initialize stock price matrix
sPath = nan(nStep+1,nPath);
sPath(1,:) = S0;
% Simulated according to ITO's lemma
p1 = (mu - 0.5 * sigma ^ 2 ) * deltaT;
p2 = sigma * sqrt(deltaT);
for i = 1:nPath
for j = 1:nStep
sPath(j+1,i) = sPath(j,i) * exp(p1 + p2 * randn);
end
end
end
命令行输出:蒙特卡罗法投资组合VaR为1816.0601
参数模型法
所谓参数模型法就是调用了 matlab 内置函数 portvrisk。
%% 参数模型法
vol = std(ret);
ValueAtRisk = portvrisk(mu,vol);
Var = ValueAtRisk * value(end);
disp(['参数模型法投资组合VaR为',num2str(Var)]);
命令行输出:参数模型法投资组合VaR为1811.7731
代码和数据下载
我已经将本文的代码和数据上传至 资源下载页面,欢迎下载。随便骂一句,垃圾代码高亮都搞不清楚,老子迟早用自己博客。
如果觉得《matlab计算 var matlab 在险价值 VaR 的计算》对你有帮助,请点赞、收藏,并留下你的观点哦!