Chapter 5. Implementing Risk Forecasts (in MATLAB/Julia)


Copyright 2011 - 2019 Jon Danielsson. This code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The GNU General Public License is available at: https://www.gnu.org/licenses/.


Listing 5.1/5.2: Download stock prices in MATLAB
Last updated August 2016

stocks = csvread('stocks.csv',1,0);
p1 = stocks(:,1);                   % consider first two stocks
p2 = stocks(:,2);
y1=diff(log(p1));                   % convert prices to returns
y2=diff(log(p2));
y1=y1(length(y1)-4100+1:end);       % length adjustment
y2=y2(length(y2)-4100+1:end);       % length adjustment
y=[y1 y2];
T=length(y1);
value = 1000;                       % portfolio value
p = 0.01;                           % probability
		
Listing 5.1/5.2: Download stock prices in Julia
Last updated June 2018

using CSV;
p = CSV.read("stocks.csv",nullable=false);
## convert prices of first two stocks to returns, and adjust length
y1 = diff(log.(p[:,1]));
y2 = diff(log.(p[:,2]));
y1 = y1[length(y1)-4100+1:length(y1)];
y2 = y2[length(y2)-4100+1:length(y2)];
y = hcat(y1,y2);
T = size(y,1)
value = 1000;                              # portfolio value
p = 0.01;                                  # probability
		

Listing 5.3/5.4: Univariate HS VaR in MATLAB
Last updated 2011

ys = sort(y1);       % sort returns
op = T*p;            % p percent smallest
VaR1 = -ys(op)*value
		
Listing 5.3/5.4: Univariate HS in Julia
Last updated June 2018

ys = sort(y1)            # sort returns
op = convert(Int64, T*p) # p percent smallest
VaR1 = -ys[op] * value
		

Listing 5.5/5.6: Multivariate HS VaR in MATLAB
Last updated 2011

w = [0.3; 0.7];       % vector of portfolio weights
yp = y*w;             % portfolio returns
yps = sort(yp);
VaR2 = -yps(op)*value
		
Listing 5.5/5.6: Multivariate HS in Julia
Last updated June 2018

w = [0.3; 0.7]          # vector of portfolio weights
yp = y * w              # portfolio returns
yps = sort(yp)
VaR2 = -yps[op] * value
		

Listing 5.7/5.8: Univariate ES in MATLAB
Last updated 2011

ES1 = -mean(ys(1:op))*value
		
Listing 5.7/5.8: Univariate ES in Julia
Last updated June 2018

ES1 = -mean(ys[1:op]) * value
		

Listing 5.9/5.10: Normal VaR in MATLAB
Last updated 2011

sigma = std(y1);                   % estimate volatility
VaR3 = -sigma * norminv(p) * value
		
Listing 5.9/5.10: Normal VaR in Julia
Last updated June 2018

sigma = std(y1);                                # estimate volatility
using Distributions;
VaR3 = -sigma * quantile(Normal(0,1),p) * value
		

Listing 5.11/5.12: Portfolio normal VaR in MATLAB
Last updated 2011

sigma = sqrt(w' * cov(y) * w);       % portfolio volatility
VaR4 = - sigma * norminv(p) *  value
		
Listing 5.11/5.12: Portfolio normal VaR in Julia
Last updated June 2018

sigma = sqrt(w'*cov(y)*w)                        # portfolio volatility
VaR4 = -sigma * quantile(Normal(0,1), p) * value
		

Listing 5.13/5.14: Student-t VaR in MATLAB
Last updated 2011

scy1=y1*100;                                   % scale the returns
res=mle(scy1,'distribution','tlocationscale');
sigma1 = res(2)/100;                           % rescale the volatility
nu = res(3);
VaR5 = - sigma1 * tinv(p,nu) * value
		
Listing 5.13/5.14: Student-t VaR in Julia
Last updated June 2018

## using Distributions;
## res = fit_mle(TDist, y1)
## nu = res.ν (this is the Greek letter nu, not Latin v)
## sigma = sqrt(nu/(nu-2))
## VaR5 = -sigma * quantile(TDist(nu), p) * value
## Julia does not have a function for fitting Student-t data yet
## Currently: there exists Distributions.jl with fit_mle
## usage: Distributions.fit_mle(Dist_name, data[, weights])
		

Listing 5.15/5.16: Normal ES in MATLAB
Last updated June 2018

sigma = std(y1);
ES2=sigma*normpdf(norminv(p))/p * value
		
Listing 5.15/5.16: Normal ES in Julia
Last updated June 2018

sigma = std(y1)
ES2 = sigma * pdf(Normal(0,1), (quantile(Normal(0,1), p))) / p * value
		

Listing 5.17/5.18: Direct integration ES in MATLAB
Last updated 2011

VaR = -norminv(p);
ES = -sigma*quad(@(q) q.*normpdf(q),-6,-VaR)/p*value
		
Listing 5.17/5.18: Direct integration ES in Julia
Last updated June 2018

using QuadGK;
VaR = -quantile(Normal(0,1), p)
integrand(x) = x*pdf(Normal(0,1), x)
ES = -sigma * quadgk(integrand, -Inf, -VaR)[1] / p * value
		

Listing 5.19/5.20: MA normal VaR in MATLAB
Last updated June 2018

WE=20;
for t=T-5:T
    t1=t-WE+1;
    window=y1(t1:t);                   % estimation window
    sigma=std(window);
    VaR6 = -sigma * norminv(p) * value
end
		
Listing 5.19/5.20: MA normal VaR in Julia
Last updated June 2018

WE = 20
for t in range(T-5, 6)
    t1 = t-WE
    window = y1[t1+1:t]                         # estimation window
    sigma = std(window)
    VaR6 = -sigma*quantile(Normal(0,1),p)*value
    println(VaR6)
end
		

Listing 5.21/5.22: EWMA VaR in MATLAB
Last updated 2011

lambda = 0.94;
s11 = var(y1(1:30));                              % initial variance
for t = 2:T
    s11 = lambda * s11  + (1-lambda) * y1(t-1)^2;
end
VaR7 = -norminv(p) * sqrt(s11) * value
		
Listing 5.21/5.22: EWMA VaR in Julia
Last updated June 2018

lambda = 0.94
s11 = var(y1[1:30])                                  # initial variance
for t in range(2, T-1)
    s11 = lambda * s11 + (1-lambda) * y1[t-1]^2
end
VaR7 = -sqrt(s11) * quantile(Normal(0,1), p) * value
		

Listing 5.23/5.24: Two-asset EWMA VaR in MATLAB
Last updated 2011

s = cov(y);                                              % initial covariance
for t = 2:T
    s = lambda * s +  (1-lambda) * y(t-1,:)' * y(t-1,:);
end
sigma = sqrt(w' * s * w);                                % portfolio vol
VaR8 = - sigma * norminv(p) * value
		
Listing 5.23/5.24: Two-asset EWMA VaR in Julia
Last updated June 2018

s = cov(y)                                               # initial covariance
for t in range(2, T-1)
    s = lambda * s + (1-lambda) * y[t-1,:] * (y[t-1,:])'
end
sigma = sqrt(w'*s*w)                                     # portfolio vol
VaR8 = -sigma * quantile(Normal(0,1), p) * value
		

Listing 5.25/5.26: GARCH in MATLAB
Last updated August 2016

[parameters,ll,ht]=tarch(y1,1,0,1);
omega = parameters(1)
alpha = parameters(2)
beta = parameters(3)
sigma2 = omega + alpha*y1(end)^2 + beta*ht(end) % calc sigma2 for t+1
VaR9 = -sqrt(sigma2) * norminv(p) * value
		
Listing 5.25/5.26: GARCH VaR in Julia
Last updated June 2018

## We use the FRFGarch mini-package again (refer to Chapter 2 above)
using FRFGarch;
res = GARCHfit(y1)
sigma_fc = res.seForecast
## seForecast contains the next-day conditional volatility forecast
VaR9 = - sigma_fc * quantile(Normal(0,1), p) * value
## GARCH estimation will be slightly different from other languages
## this is due to GARCHfit choosing initial conditional vol = sample vol