Difference between revisions of "GMM"
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | The code below performs a standard 2 step GMM estimation. | ||
+ | In this code the estimation is exactly identified (number of moments = number of parameters). | ||
+ | This code requires numgrad.m in your working directory. This is a function to calculate numerical gradients. | ||
+ | |||
<source> | <source> | ||
%========================================================================= | %========================================================================= |
Latest revision as of 08:37, 8 February 2022
The code below performs a standard 2 step GMM estimation. In this code the estimation is exactly identified (number of moments = number of parameters). This code requires numgrad.m in your working directory. This is a function to calculate numerical gradients.
%=========================================================================
%
% Program to estimate level effect in interest rates by GMM
%
% Code based on Martin, Hurn and Harris, Econometric Time Series Modelling
% Specification, Estimation and Testing
% https://www.cambridge.org/features/econmodelling/chapter10.htm
%
% This code by Ralf Becker, March 2021
% http://eclr.humanities.manchester.ac.uk/index.php/MATLAB
%=========================================================================
clear all;
clc;
cd 'YOUR DIRECTORY'
% Load data --- monthly December 1946 to February 1991
% 3 month maturity
% extracted from the datafile provided by
% Martin, Hurn and Harris
% https://www.cambridge.org/features/econmodelling/chapter10.htm
[rt, ~, ~] = xlsread('US3monthRate.xlsx');
drt = trimr(rt,2,0) - trimr(rt,1,1); % creates \Delta r_{t+1}
r1t = trimr(rt,1,1); % creates r_t
r2t = trimr(rt,0,2);
t = length(drt);
%% It is typically good practice to visualise the data
tt = seqa(1946+12/12,1/12,t); % Creates year sequence
subplot(1,2,1);
plot(tt,r1t);
title('r_t')
box off
axis tight
subplot(1,2,2);
plot(tt,drt);
title('\Delta r_{t+1}')
box off
axis tight
%% Estimate the model in the first stage with idendity weighting matrix
ops = optimset('LargeScale','off','Display','off');
b0 = [0.1;0.1;0.1;1.0];
w0 = eye(length(b0));
bgmm1 = fminunc(@(b) qw(b,drt,r1t,w0),b0,ops);
disp('First Stage GMM estimates')
disp(bgmm1)
%% Now estimate the optimal weighting matrix
% using Newey-West estimator
lmax = 5; % lag for the NW estimate
d = meqn(bgmm1,drt,r1t);
% this will calculate Newey-West VCM using lmax lags
s = d'*d;
tau = 1;
while tau <= lmax
wtau = d((tau+1):size(d,1),:)'*d(1:(size(d,1)-tau),:);
s = s + (1.0-tau/(lmax+1))*(wtau + wtau');
tau = tau + 1;
end
w1 = s./t;
% Use this as the weighting matrix for the next pass to the optimisation
% function
%% 2nd Stage
bgmm2 = fminunc(@(b) qw(b,drt,r1t,w1),bgmm1,ops);
disp('Second Stage GMM estimates')
disp(bgmm2)
%% Further Iterations
% You could run further iterations
% 1) Re-calculate d
% 2) Re-calculate the optimal weighting matrix w based on the new d
% 3) Re-estimate using the new w
%
% For now we stop here
bgmm = bgmm2;
obj = qw(bgmm,drt,r1t,w1);
%% Calculate standard errors
% Compute optimal weigthing matrix at GMM estimates
% using Newey-West estimator
lmax = 5; % lag for the NW estimate
d = meqn(bgmm,drt,r1t);
% this will calculate Newey-West VCM using lmax lags
s = d'*d;
tau = 1;
while tau <= lmax
wtau = d((tau+1):size(d,1),:)'*d(1:(size(d,1)-tau),:);
s = s + (1.0-tau/(lmax+1))*(wtau + wtau');
tau = tau + 1;
end
s = s./t;
% Compute standard errors of GMM estimates
dg = numgrad(@meaneqn,bgmm,drt,r1t);
v = dg'*inv(s)*dg;
cov = inv(v)/t;
se = sqrt(diag(cov));
disp(' ');
disp(['The value of the objective function = ', num2str(obj) ]);
disp(['J-test = ', num2str(t*obj) ]);
disp('Estimates Std err. t-stats');
disp( [ bgmm se bgmm./se ])
disp(['Newey-West estimator with max lag = ', num2str(lmax) ]);
disp(' ');
%% Inference t-tests
% Test of gam = 0.0
stat = (bgmm(4) - 0.0)/se(4);
disp(['Test of (gam=0.0) = ', num2str(stat) ]);
disp(['p-value = ', num2str(2*(1-normcdf(abs(stat)))) ]);
disp(' ');
% Test of gam = 0.5
stat = (bgmm(4) - 0.5)/se(4);
disp(['Test of (gam=0.5) = ', num2str(stat) ]);
disp(['p-value = ', num2str(2*(1-normcdf(abs(stat)))) ]);
disp(' ');
% Test of gam = 1.0
stat = (bgmm(4) - 1.0)/se(4);
disp(['Test of (gam=1.0) = ', num2str(stat) ]);
disp(['p-value = ', num2str(2*(1-normcdf(abs(stat)))) ]);
disp(' ');
% Test of gam = 1.5
stat = (bgmm(4) - 1.5)/se(4);
disp(['Test of (gam=1.5) = ', num2str(stat) ]);
disp(['p-value = ', num2str(2*(1-normcdf(abs(stat)))) ]);
disp(' ');
%% Inference - Overidentifying restrictions
%% Plot volatility function for alternative values of gam
tt = seqa(1946+12/12,1/12,t);
figure(1)
subplot(2,2,1);
plot(tt,drt./r1t.^0.0);
title('$\gamma=0.0$')
box off
axis tight
subplot(2,2,2);
plot(tt,drt./r1t.^0.5);
title('$\gamma=0.5$')
box off
axis tight
subplot(2,2,3);
plot(tt,drt./r1t.^1.0);
title('$\gamma=1.0$')
box off
axis tight
subplot(2,2,4);
plot(tt,drt./r1t.^1.5);
title('$\gamma=1.5$')
box off
axis tight
%
%------------------------- Functions -------------------------------------%
%
%-------------------------------------------------------------------------%
% Define the moment equations
%-------------------------------------------------------------------------%
function dt = meqn(b,drt,r1t)
ut = drt - b(1) - b(2)*r1t;
zt = [ones(size(ut,1),1),r1t];
dt = repmat(ut,1,2).*zt;
dt = [dt,repmat((ut.^2 - (b(3)^2)*r1t.^(2*b(4)) ),1,2).*zt];
end
%-------------------------------------------------------------------------%
% Defines the mean of the moment conditions
%-------------------------------------------------------------------------%
function ret = meaneqn(b,drt,r1t)
ret = (mean(meqn(b,drt,r1t)))';
end
%-------------------------------------------------------------------------%
% GMM objective function with user defined
% weighting matrix, w
%-------------------------------------------------------------------------%
function ret = qw(b,drt,r1t,w)
t = length(drt);
d = meqn(b,drt,r1t);
g = mean(d)';
ret = g'*inv(w)*g;
end