ExampleCodeOLShac
Below you can find example code which uses the OLShac function. That function estimates a linear model using OLS. Results are returned in a structure out
. Amongst the results are White standard errors and Newey-West standard errors. From the comments in OLShac
you can see the exact specifications of all outputs. See OLShac
below.
hac_estimators.m
In this code we simulate artificial data. We do so to establish the properties of t-tests based on different standard errors. The code simulates three different processes, one with error terms that meet the Gauss-Markov assumptions, another with heteroskedastic and another with autocorrelated error terms. In order to simulate autocorrelated we use another function armasim
, which is attached to the end of this file.
%====================================================
% In here we
% 1) simulate three different processes
% a) regression model with that meets GM assumptions
% b) regression model with heteroskedastic errors
% c) regression model with AC errors
% 2) Perform parameter inference using normal, White and NW se
% 3) Evaluate whether tests have correct size
%
%====================================================
function main
clc % Clears the command window
randn('state',123467); % ensures that random number generator starts with same random number
% Parameters for DGP
% y = x*b + u
n = 200; % length of the simulated series
nsim = 10000; % number of simulations
x = [ones(n,1) randn(n,2)]; % constant and two randomly generated series
b = [0.5; 1.0; -0.5]; % true parameter vector
sig = 0.1; % standard deviation of error terms
% Parameters for the AR error terms
p = 1; % AR order
q = 1; % MA order
% process parameters
alpha = 0.0;
phi = [0.9];
theta = [0.7];
sigar = 0.1; % standard error of innovation term
% save t-stats for DGP with GM errors here, col1: OLS se, Col2: White,
% Col3: NW; only safe results for b(2)
tsave = zeros(nsim,3);
% simulate model with GM (gmerr), heteroskedatic (hserr) or
% autocorrelated (arerr) errors
for i = 1 : nsim
% gmerr = randn(n,1)*sig; % GM errors
% hserr = [randn(n/2,1)*sig;randn(n/2,1)*(sig/5)]; % heterosk errors
arerr = armasim(n,p,q,alpha,phi,theta,sigar); % AR errors
y = x*b + arerr; % DGP with selected errors
results = OLShac(y,x,0); % estimate and save results in "results"
bmb0 = results.b(2) - b(2); % difference of estimated value from true value
tsave(i,:) = [bmb0/results.bse(2) bmb0/results.wh_bse(2) bmb0/results.nw_bse(2)];
end
cv5 = norminv(0.975); % 2 tailed 5% cv, Normal
cv1 = norminv(0.995); % 2 tailed 1% cv, Normal
cv5t = tinv(0.975,n-length(b)); % 2 tailed 5% cv, t-Distr
cv1t = tinv(0.995,n-length(b)); % 2 tailed 1% cv, t-Distr
count5 = (abs(tsave(:,2:3))>cv5); % 1 if test stat exceed cv, 0 otherwise
count1 = (abs(tsave(:,2:3))>cv1); % 1 if test stat exceed cv, 0 otherwise
count5 = [(abs(tsave(:,1))>cv5t) count5];
count1 = [(abs(tsave(:,1))>cv1t) count1];
prop5 = sum(count5)./nsim; % proportion of rejections of true H0 at 5%
prop1 = sum(count1)./nsim; % proportion of rejections of true H0 at 1%
disp('Rejections for standard OLS, White and NW based t-tests');
disp(' OLS White NW');
disp('at 5%');
disp(prop5);
disp('at 1%');
disp(prop1);
end
This is the armasim
function. Either copy it below the above file (as it is written as a function you can do that), or you can save it in a new function file with the name armasim.m
.
function y = armasim(t,p,q,al,ph,th,si);
% Function that simulates ARMA(p,q) process of
% input: t length series to be simulated
% p, AR order
% q, MA order
% al, constant
% ph, AR parameters [ph(1); ph(2); ...; ph(p)]
% th, MA parameters [th(1); th(2); ...; th(q)]
%
% y(t) = al + ph(1)*y(t-1) + ... + ph(p)*y(t-p)
% + th(1)*eps(t-1) + ... + th(q)*eps(t-q) + eps(t)
% where eps(t) comes from ~N(0,si^2)
eps = randn(t+100,1)*si;% error terms, 100 extra for startup
maxlag = max([p;q]); % find max lag
if sum(ph)==1
um = 1;
else
um = al/(1-sum(ph)); % unconditional mean
end
fph = flipud(ph); % reversed AR parameter vector
fth = flipud(th); % reversed MA parameter vector
y = ones(t+100,1)*um; % in here we safe the series, start with unconditional mean
if p>0 & q>0 % ARMA model
for i = maxlag+1:t+100
y(i) = al + y(i-p:i-1)'*fph + eps(i-q:i-1)'*fth + eps(i);
end
elseif p>0 & q==0 % AR Model
for i = maxlag+1:t+100
y(i) = al + y(i-p:i-1)'*fph + eps(i);
end
elseif p==0 & q>0 % MA model
for i = maxlag+1:t+100
y(i) = al + eps(i-q:i-1)'*fth + eps(i);
end
else % White noise process
for i = maxlag+1:t+100
y(i) = al + eps(i);
end
end
y = y(101:end);
end
An example output of this code (using autocorrelated error terms) is as follows:
OLS White NW
at 5%
0.0243 0.0299 0.0455
at 1%
0.0021 0.0039 0.0079
As we are testing the size of the tests (testing a correct null hypothesis) you can see that the empirical sizes are closest to the nominal sizes (0.05 and 0.01) for the t-test using the Newey-West standard errors.
OLShac.m
This is a function that estimates a linear model with OLS. The results are all returned in a structure. Save this as a new function file called OLShac.m
.
function out = OLShac(y,x,output,B);
% This function performs an OLS estimation
% input: y, vector with dependent variable
% x, matrix with explanatory variable
% function will automatically add a constant if the first col
% is not a vector of ones
% output, 1 = printed output
% B, lag lengths for Newey-West standard errors
% output: Structure called OLS with the following elements:
% .b, estimated parameters
% .bse, standard errors for bhat
% .wh_bse, White standard errors for bhat
% .nw_bse, Newey-West standard errors for bhat
% .res, estimated residuals
% .n, number of observations used
% .rss, residual sum of squares
% .r2, Rsquared
% This checks how many inputs have been provided and chooses defaults for
% missing inputs
switch nargin
case 2
output = 1;
B = 0; % will later be replaced by default value
case 3
B = 0; % will later be replaced by default value
case 4
% nothing
otherwise
error('2 to 4 inputs are required!')
end
% select those rows that have observations for all variables
ninit = length(y);
testnan = [isnan(y) isnan(x)];
testnan = (sum(testnan,2)==0);
y = y(testnan);
x = x(testnan,:);
% test whether first column is vector of ones
temp = (x(x(:,1)==1));
if length(temp) ~= length(x)
x = [ones(length(x),1) x]; % add constant of not included in x
end
[n,k] = size(x); % sample size - n, number of explan vars (incl constant) - k
xxi = inv(x'*x);
n = n;
b = xxi*x'*y;
res = y - x*b;
rss = res'*res;
ssq = rss/(n-k);
s = sqrt(ssq);
bse = ssq*xxi;
bse = sqrt(diag(bse));
tstat = b./bse;
ym = y - mean(y);
r2 = 1 - (res'*res)/(ym'*ym);
adjr2 = 1 - (n-1)*(1-r2)/(n-k);
fstat = ((((ym'*ym))-(res'*res))/(k-1))/((res'*res)/(n-k));
dw = corrcoef([res(1:end-1) res(2:end)]);
dw = 2*(1-dw(2,1));
% calculation of robust standard errors
% White standard errors
resx = repmat(res,1,size(x,2)).*x;
wh_vcm = xxi*(resx'*resx)*xxi;
wh_bse = sqrt(diag(wh_vcm));
% Newey-West standard errors
if B==0 % recalculate B only if not provided as input
B = ceil(4*(n/100)^(2/9)); % This is the lag length in the Newey West calculation
end
xox = resx(1:end,:)'*resx(1:end,:);
for i = 1:B-1;
w = 1-(i/B);
za = resx(1+i:end,:)'*resx(1:end-i,:);
xox = xox+w*(za+za');
end;
nw_vcm = xxi*xox*xxi;
nw_bse = sqrt(diag(nw_vcm));
% Save the outputs
out.b = b;
out.bse = bse;
out.wh_bse = wh_bse;
out.nw_bse = nw_bse;
out.res = res;
out.n = n;
out.rss = rss;
out.r2 = r2;
if output
pval = 2*(1-tcdf(abs(tstat),n-k));
pvalf = 1- fcdf(fstat,k-1,n-k);
try % if stats toolbox is available
pval = 2*(1-tcdf(abs(tstat),n-k));
pvalf = 1- fcdf(fstat,k-1,n-k);
catch
try % if NAG toolbox is available
pval = 2*(1-g01eb(abs(tstat),n-k));
pvalf = g01ed(fstat,k-1,n-k,'tail','U');
catch
pval = -999*ones(size(tstat));
pvalf = -999;
end
end
fprintf('===========================================================\n');
fprintf('===== Regression Output ==================================\n');
fprintf('Obs used = %4.0f, missing obs = %4.0f \n',n,(ninit-n));
fprintf('Rsquared = %5.4f \n',r2);
fprintf('adj_Rsq = %5.4f \n',adjr2);
fprintf('===== Estimated Model Parameters ==========================\n');
fprintf('= Par se se(White) se(NW) ==================\n');
format short;
disp([b bse wh_bse nw_bse]);
fprintf('===== Model Statistics ====================================\n');
fprintf(' Fstat = %5.4f (%5.4f)\n',[fstat;pvalf]);
fprintf(' standard error = %5.4f\n',sqrt(ssq));
fprintf(' RSS = %5.4f\n',rss);
fprintf(' Durbin-Watson = %5.4f\n',dw);
fprintf('===========================================================\n');
end