diff --git a/.gitignore b/.gitignore index 2d2b605..2453d06 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ *.png *.eps *.DS_Store +!applications/kaenzig/dataQuantM.mat +!applications/kaenzig/OilSurprisesMLog.mat diff --git a/README.md b/README.md index 96a6651..1e16bf8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,10 @@ Matlab code for inference on variance decompositions and the degree of invertibility/recoverability in a general Structural Vector Moving Average (SVMA) model identified by external instruments (IVs, also known as proxies) **Reference:** -Plagborg-Møller, Mikkel and Christian K. Wolf (2020), "Instrumental Variable Identification of Dynamic Variance Decompositions", https://scholar.princeton.edu/mikkelpm/decomp_iv (paper + online appendix) +Plagborg-Møller, Mikkel and Christian K. Wolf (2021), "Instrumental Variable Identification of Dynamic Variance Decompositions", https://scholar.princeton.edu/mikkelpm/decomp_iv (paper + online appendix) + +**Acknowledgements:** +We are grateful to Diego Känzig for allowing us to reproduce some of the data files used in his 2021 AER paper. Tested in: Matlab R2020a on Windows 10 PC (64-bit) @@ -13,8 +16,9 @@ Tested in: Matlab R2020a on Windows 10 PC (64-bit) - [SVMAIV_estim.m](functions/SVMAIV_estim.m): main function for SVMA-IV inference - [SVARIV_estim.m](functions/SVARIV_estim.m): SVAR-IV inference (assumes invertibility) -**[application](application):** empirical example -- [run_gk.m](application/run_gk.m): example based on Gertler & Karadi (2015) +**[applications](applications):** empirical applications +- [gk/run_gk.m](applications/gk/run_gk.m): application based on Gertler & Karadi (2015) +- [kaenzig/run_kaenzig.m](applications/kaenzig/run_kaenzig.m): application based on Känzig (2021) **[illustration](illustration):** numerical illustration - [run_sw.m](illustration/run_sw.m): SVMA-IV and SVAR-IV analysis of Smets & Wouters (2007) model @@ -55,4 +59,12 @@ Parameter names: - `FVR`: forecast variance ratio - `FVD`: forecast variance decomposition -See the [empirical application](application/run_gk.m) for a concrete example. Additional optional arguments to [`SMVAIV_estim.m`](functions/SVMAIV_estim.m) are listed at the top of the function. +See our [empirical applications](applications) for concrete examples of how to use the code. Additional optional arguments to [`SMVAIV_estim.m`](functions/SVMAIV_estim.m) are listed at the top of the function. + +## Replication instructions + +The figures and tables in our paper and supplement are produced as follows: +- Figures 1 and B.7 and Table 1: [applications/gk/run_gk.m](applications/gk/run_gk.m) +- Table 2: First run [simulations/run_sim.m](simulations/run_sim.m) nine separate times, with the variable `model.dgp` at the top set to each of the options `0` through `8`. Then run [simulations/print_results.m](simulations/print_results.m) +- Figures B.1-B.6 and Table B.1: [illustration/run_sw.m](illustration/run_sw.m) +- Figures B.8-B.11: [applications/kaenzig/run_kaenzig.m](applications/kaenzig/run_kaenzig.m) diff --git a/applications/gk/run_gk.m b/applications/gk/run_gk.m index bba0c11..f7cd2e0 100644 --- a/applications/gk/run_gk.m +++ b/applications/gk/run_gk.m @@ -32,7 +32,7 @@ % Estimation settings (see other optional settings in "functions/SVMAIV_estim.m") settings = {'ic', 'aic'; % Information criterion - 'n_boot', 500; % Number of bootstrap samples + 'n_boot', 1e3; % Number of bootstrap samples 'signif', 0.1; % Significance level 'horiz', 1:24}'; % Horizons of FVR to report diff --git a/applications/kaenzig/OilSurprisesMLog.mat b/applications/kaenzig/OilSurprisesMLog.mat new file mode 100644 index 0000000..9d7c40c Binary files /dev/null and b/applications/kaenzig/OilSurprisesMLog.mat differ diff --git a/applications/kaenzig/dataQuantM.mat b/applications/kaenzig/dataQuantM.mat new file mode 100644 index 0000000..335d284 Binary files /dev/null and b/applications/kaenzig/dataQuantM.mat differ diff --git a/applications/kaenzig/run_kaenzig.m b/applications/kaenzig/run_kaenzig.m index 41e5dc1..fc9d815 100644 --- a/applications/kaenzig/run_kaenzig.m +++ b/applications/kaenzig/run_kaenzig.m @@ -4,33 +4,24 @@ % Empirical application: Kaenzig (AER, 2021) -%% Load data - -% settings - -data.endo_vars = {'oil_price','oil_production','oil_inventories','world_ip','neer','ip','cpi','ffr','vxo','tot'}; -data.iv = 'oil_surprise'; - -% data.smpl_start = '1974M01'; -% data.smpl_start = '1983M04'; -data.smpl_start = '1983M03'; -data.smpl_end = '2017M12'; -% data - -load data_kaenzig - -% endogenous variables +%% Load data -data.sampleDates = sampleDates; +% Settings +data.endo_vars = {'oil_price','oil_production','oil_inventories','world_ip','neer','ip','cpi','ffr','vxo','tot'}; % Abbreviations of endogenous variables +data.diff = [0,1,1,1,1,1,1,0,0,0]; % =1: take first differences of endogenous variable +data.iv = 'oil_surprise'; +data.smpl_start = '1983M03'; % Sample start point +data.smpl_end = '2017M12'; % Sample end point +% Endogenous variables +dat_endo = load('dataQuantM'); % Endogenous variables +data.sampleDates = dat_endo.sampleDates; data.smplStartInd = find(strcmp(data.sampleDates,data.smpl_start)); data.smplEndInd = find(strcmp(data.sampleDates,data.smpl_end)); +data.Y = dat_endo.data(data.smplStartInd:data.smplEndInd,:); -data.Y = dataEndo(data.smplStartInd:data.smplEndInd,:); - -data.diff = [0,1,1,1,1,1,1,0,0,0]; - +% First differences for i = 1:size(data.Y,2) if data.diff(i) == 1 data.Y(:,i) = [NaN;12 * (data.Y(2:end,i) - data.Y(1:end-1,i))]; @@ -38,19 +29,18 @@ end % IV - -proxyRaw = [oilProxiesWTIM(:,14)]; - +dat_iv=load('OilSurprisesMLog'); % IV +proxyRaw = dat_iv.oilProxiesWTIM(:,14); data.Z = proxyRaw(data.smplStartInd:data.smplEndInd,:); -% adjust sample - +% Adjust sample if max(data.diff) == 1 data.Y = data.Y(2:end,:); data.Z = data.Z(2:end,:); end -clear sampleDates dataEndo oilProxiesWTIM proxyRaw +clear sampleDates dataEndo oilProxiesWTIM proxyRaw; + %% SVMA-IV inference @@ -58,14 +48,13 @@ % Preliminaries addpath('../../functions'); % Add folder with SVMA-IV analysis functions -addpath('subroutines'); % Add folder with some application-specific auxiliary functions rng(2018); % Seed random number generator (for bootstrap) % Estimation settings (see other optional settings in "functions/SVMAIV_estim.m") -settings = {'p', 12; % Information criterion - 'n_boot', 100; % Number of bootstrap samples +settings = {'p', 12; % Lag length + 'n_boot', 1e3; % Number of bootstrap samples 'signif', 0.1; % Significance level - 'horiz', 1:50}'; % Horizons of FVR to report + 'horiz', 1:48}'; % Horizons of FVR to report % Run inference routines [bounds, id_recov, inv_test, settings_struct] = SVMAIV_estim(data.Y, data.Z, settings{:}); @@ -105,7 +94,7 @@ % figure -plots.xticks = 0:10:50; % X axis ticks for FVR plot +plots.xticks = 0:12:48; % X axis ticks for FVR plot plots.titles = {'FVR of Oil Price', 'FVR of Oil Production Growth', 'FVR of Oil Inventories Growth', 'FVR of World IP Growth', 'FVR of U.S. NEER Growth', ... 'FVR of U.S. IP Growth', 'FVR of U.S. CPI Growth', 'FVR of FFR', 'FVR of VXO', 'FVR of U.S. TOT'}; plots.xlabel = 'Horizon (Months)'; % X axis label for FVR plot @@ -131,11 +120,8 @@ end -clear i - -% table +clear i; -svmaiv_table %% SVAR-IV analysis for comparison (assumes invertibility) @@ -165,8 +151,4 @@ end -clear i - -% FVD table - -svariv_table \ No newline at end of file +clear i; diff --git a/applications/kaenzig/subroutines/svariv_table.m b/applications/kaenzig/subroutines/svariv_table.m deleted file mode 100644 index 40eb2c1..0000000 --- a/applications/kaenzig/subroutines/svariv_table.m +++ /dev/null @@ -1,64 +0,0 @@ -SVARIV_FVD_med = min(1,max(0,SVARIV_FVD.estim)); -SVARIV_FVD_lb = min(1,max(0,SVARIV_FVD.ci.lower)); -SVARIV_FVD_ub = min(1,max(0,SVARIV_FVD.ci.upper)); - -nvar = size(SVARIV_FVD_med,2); - -nvarbase = 5; -FID = fopen('tables/svariv_kaenzig.tex','w'); -fprintf(FID, strcat('\\begin{tabular}{l',repmat('c',1,6),'}\\toprule\\midrule \n')); -fprintf(FID,'\\multicolumn{6}{l}{\\textit{Global variables and exchange rates:}} \\\\ \n'); -nameString = [ ]; -for ii = 1:nvarbase-1 - nameString = [nameString ' %s &']; -end -nameString = [nameString ' %s ']; -fprintf(FID,strcat(' & ',nameString,' \\\\ \\midrule \n'),data.endo_vars{1:nvarbase}); -numString = ' %1.0f & '; -for ii = 1:nvarbase-1 - numString = [numString '%8.2f & ']; -end -numString = [numString '%8.2f']; -numStringBands = []; -for ii = 1:nvarbase-1 - numStringBands = [numStringBands ' [%1.2f,%8.2f] &']; -end -numStringBands = [numStringBands ' [%1.2f,%8.2f]']; -for kk=[0 12 24 48] %48 - kk2=kk+1; - if kk<36 - fprintf(FID,strcat(numString,' \\\\ \n'),kk,SVARIV_FVD_med(kk2,1:nvarbase)); - fprintf(FID, strcat(' & ',numStringBands,' \\\\ \n'),vec([SVARIV_FVD_lb(kk2,1:nvarbase)' SVARIV_FVD_ub(kk2,1:nvarbase)']')); - else - fprintf(FID,strcat(numString,' \\\\ \n'),kk,SVARIV_FVD_med(kk2,1:nvarbase)); - fprintf(FID, strcat(' & ',numStringBands,' \\\\[2ex] \\midrule \n'),vec([SVARIV_FVD_lb(kk2,1:nvarbase)' SVARIV_FVD_ub(kk2,1:nvarbase)']')); - end -end -fprintf(FID,'\\multicolumn{6}{l}{\\textit{U.S. variables:}} \\\\ \n'); -nameString = [ ]; -for ii = 1:nvar-nvarbase-1 - nameString = [nameString ' %s &']; -end -nameString = [nameString ' %s ']; -fprintf(FID,strcat(' & ',nameString,' \\\\ \\midrule \n'),data.endo_vars{nvarbase+1:end}); -numString = ' %1.0f & '; -for ii = 1:nvar-nvarbase-1 - numString = [numString '%8.2f & ']; -end -numString = [numString '%8.2f']; -numStringBands = []; -for ii = 1:nvar-nvarbase-1 - numStringBands = [numStringBands ' [%1.2f,%8.2f] &']; -end -numStringBands = [numStringBands ' [%1.2f,%8.2f]']; -for kk=[0 12 24 48] - kk2=kk+1; - fprintf(FID,strcat(numString,' \\\\ \n'),kk,SVARIV_FVD_med(kk2,nvarbase+1:end)); - fprintf(FID, strcat(' & ',numStringBands,' \\\\ \n'),vec([SVARIV_FVD_lb(kk2,nvarbase+1:end)' SVARIV_FVD_ub(kk2,nvarbase+1:end)']')); - -end -fprintf(FID, '\\midrule\\bottomrule \n'); -fprintf(FID, '\\end{tabular}\n'); -fclose(FID); - -clear ans nvarbase FID ii kk kk2 nameString numString numStringBands nvar SVARIV_FVD_lb SVARIV_FVD_med SVARIV_FVD_ub \ No newline at end of file diff --git a/applications/kaenzig/subroutines/svmaiv_table.m b/applications/kaenzig/subroutines/svmaiv_table.m deleted file mode 100644 index 4bc8cfb..0000000 --- a/applications/kaenzig/subroutines/svmaiv_table.m +++ /dev/null @@ -1,73 +0,0 @@ -SVMAIV_FVD_IS_lb = min(1,max(0,bounds.estim.lower.FVR)); -SVMAIV_FVD_IS_ub = min(1,max(0,bounds.estim.upper.FVR)); -SVMAIV_FVD_CI_lb = min(1,max(0,bounds.ci.lower.FVR)); -SVMAIV_FVD_CI_ub = min(1,max(0,bounds.ci.upper.FVR)); -nvar = size(SVMAIV_FVD_IS_lb,2); - -nvarbase = 5; -FID = fopen('tables/svmaiv_kaenzig.tex','w'); -fprintf(FID, strcat('\\begin{tabular}{l',repmat('c',1,6),'}\\toprule\\midrule \n')); -fprintf(FID,'\\multicolumn{6}{l}{\\textit{Global variables and exchange rates:}} \\\\ \n'); -nameString = [ ]; -for ii = 1:nvarbase-1 - nameString = [nameString ' %s &']; -end -nameString = [nameString ' %s ']; -fprintf(FID,strcat(' & ',nameString,' \\\\ \\midrule \n'),data.endo_vars{1:nvarbase}); -numString = ' %1.0f & '; -for ii = 1:nvarbase-1 - numString = [numString '%8.2f & ']; -end -numString = [numString '%8.2f']; -numStringBands1 = []; -for ii = 1:nvarbase-1 - numStringBands1 = [numStringBands1 ' %1.2f,%8.2f &']; -end -numStringBands1 = [numStringBands1 ' %1.2f,%8.2f']; -numStringBands2 = []; -for ii = 1:nvarbase-1 - numStringBands2 = [numStringBands2 ' [%1.2f,%8.2f] &']; -end -numStringBands2 = [numStringBands2 ' [%1.2f,%8.2f]']; -for kk=[0 12 24 48] %48 - kk2=kk+1; - if kk<36 - fprintf(FID,strcat(' %1.0f '),kk); - fprintf(FID, strcat(' & ',numStringBands1,' \\\\ \n'),vec([SVMAIV_FVD_IS_lb(kk2,1:nvarbase)' SVMAIV_FVD_IS_ub(kk2,1:nvarbase)']')); - fprintf(FID, strcat(' & ',numStringBands2,' \\\\ \n'),vec([SVMAIV_FVD_CI_lb(kk2,1:nvarbase)' SVMAIV_FVD_CI_ub(kk2,1:nvarbase)']')); - else - fprintf(FID,strcat(' %1.0f '),kk); - fprintf(FID, strcat(' & ',numStringBands1,' \\\\ \n'),vec([SVMAIV_FVD_IS_lb(kk2,1:nvarbase)' SVMAIV_FVD_IS_ub(kk2,1:nvarbase)']')); - fprintf(FID, strcat(' & ',numStringBands2,' \\\\[2ex] \\midrule \n'),vec([SVMAIV_FVD_CI_lb(kk2,1:nvarbase)' SVMAIV_FVD_CI_ub(kk2,1:nvarbase)']')); - end -end -fprintf(FID,'\\multicolumn{6}{l}{\\textit{U.S. variables:}} \\\\ \n'); -nameString = [ ]; -for ii = 1:nvar-nvarbase-1 - nameString = [nameString ' %s &']; -end -nameString = [nameString ' %s ']; -fprintf(FID,strcat(' & ',nameString,' \\\\ \\midrule \n'),data.endo_vars{nvarbase+1:end}); -numString = ' %1.0f & '; -for ii = 1:nvar-nvarbase-1 - numString = [numString '%8.2f & ']; -end -numString = [numString '%8.2f']; -numStringBands2 = []; -for ii = 1:nvar-nvarbase-1 - numStringBands2 = [numStringBands2 ' [%1.2f,%8.2f] &']; -end -numStringBands2 = [numStringBands2 ' [%1.2f,%8.2f]']; -for kk=[0 12 24 48] - kk2=kk+1; - fprintf(FID,strcat(' %1.0f '),kk); - fprintf(FID, strcat(' & ',numStringBands1,' \\\\ \n'),vec([SVMAIV_FVD_IS_lb(kk2,nvarbase+1:end)' SVMAIV_FVD_IS_ub(kk2,nvarbase+1:end)']')); - fprintf(FID, strcat(' & ',numStringBands2,' \\\\ \n'),vec([SVMAIV_FVD_CI_lb(kk2,nvarbase+1:end)' SVMAIV_FVD_CI_ub(kk2,nvarbase+1:end)']')); - -end -fprintf(FID, '\\midrule\\bottomrule \n'); -fprintf(FID, '\\end{tabular}\n'); -fclose(FID); - -clear ans nvarbase FID ii kk kk2 nameString numString numStringBands1 numStringBands2 nvar ... - SVMAIV_FVD_IS_lb SVMAIV_FVD_IS_ub SVMAIV_FVD_CI_lb SVMAIV_FVD_CI_ub \ No newline at end of file diff --git a/applications/kaenzig/subroutines/vec.m b/applications/kaenzig/subroutines/vec.m deleted file mode 100644 index 3db218d..0000000 --- a/applications/kaenzig/subroutines/vec.m +++ /dev/null @@ -1,2 +0,0 @@ -function X = vec(X) -X = X(:); \ No newline at end of file diff --git a/applications/kaenzig/tables/svariv_kaenzig.tex b/applications/kaenzig/tables/svariv_kaenzig.tex deleted file mode 100644 index 49788fa..0000000 --- a/applications/kaenzig/tables/svariv_kaenzig.tex +++ /dev/null @@ -1,23 +0,0 @@ -\begin{tabular}{lcccccc}\toprule\midrule -\multicolumn{6}{l}{\textit{Global variables and exchange rates:}} \\ - & oil_price & oil_production & oil_inventories & world_ip & neer \\ \midrule - 0 & 1.00 & 0.00 & 0.00 & 0.00 & 0.00 \\ - & [0.80, 1.00] & [0.00, 0.00] & [0.00, 0.00] & [0.00, 0.04] & [0.00, 0.05] \\ - 12 & 0.52 & 0.00 & 0.00 & 0.08 & 0.00 \\ - & [0.30, 0.71] & [0.00, 0.04] & [0.00, 0.02] & [0.00, 0.15] & [0.00, 0.05] \\ - 24 & 0.47 & 0.00 & 0.00 & 0.08 & 0.00 \\ - & [0.26, 0.63] & [0.00, 0.03] & [0.00, 0.02] & [0.00, 0.14] & [0.00, 0.05] \\ - 48 & 0.50 & 0.00 & 0.00 & 0.08 & 0.00 \\ - & [0.28, 0.64] & [0.00, 0.03] & [0.00, 0.02] & [0.00, 0.14] & [0.00, 0.05] \\[2ex] \midrule -\multicolumn{6}{l}{\textit{U.S. variables:}} \\ - & ip & cpi & ffr & vxo & tot \\ \midrule - 0 & 0.00 & 0.24 & 0.00 & 0.00 & 0.51 \\ - & [0.00, 0.06] & [0.03, 0.39] & [0.00, 0.00] & [0.00, 0.04] & [0.19, 0.74] \\ - 12 & 0.17 & 0.28 & 0.03 & 0.09 & 0.65 \\ - & [0.07, 0.24] & [0.16, 0.38] & [0.00, 0.11] & [0.00, 0.16] & [0.44, 0.89] \\ - 24 & 0.18 & 0.28 & 0.09 & 0.07 & 0.59 \\ - & [0.09, 0.25] & [0.17, 0.37] & [0.00, 0.18] & [0.00, 0.13] & [0.41, 0.78] \\ - 48 & 0.18 & 0.28 & 0.25 & 0.05 & 0.60 \\ - & [0.10, 0.24] & [0.18, 0.37] & [0.04, 0.37] & [0.00, 0.11] & [0.42, 0.77] \\ -\midrule\bottomrule -\end{tabular} diff --git a/applications/kaenzig/tables/svmaiv_kaenzig.tex b/applications/kaenzig/tables/svmaiv_kaenzig.tex deleted file mode 100644 index b5473e7..0000000 --- a/applications/kaenzig/tables/svmaiv_kaenzig.tex +++ /dev/null @@ -1,23 +0,0 @@ -\begin{tabular}{lcccccc}\toprule\midrule -\multicolumn{6}{l}{\textit{Global variables and exchange rates:}} \\ - & oil_price & oil_production & oil_inventories & world_ip & neer \\ \midrule - 0 & 0.03, 0.17 & 0.00, 0.00 & 0.00, 0.00 & 0.00, 0.00 & 0.00, 0.00 \\ - & [0.00, 0.23] & [0.00, 0.00] & [0.00, 0.00] & [0.00, 0.01] & [0.00, 0.01] \\ - 12 & 0.02, 0.11 & 0.01, 0.09 & 0.01, 0.10 & 0.00, 0.04 & 0.01, 0.12 \\ - & [0.00, 0.18] & [0.00, 0.14] & [0.00, 0.15] & [0.00, 0.08] & [0.00, 0.18] \\ - 24 & 0.00, 0.05 & 0.01, 0.10 & 0.01, 0.12 & 0.00, 0.06 & 0.01, 0.13 \\ - & [0.00, 0.10] & [0.00, 0.14] & [0.00, 0.16] & [0.00, 0.10] & [0.00, 0.18] \\ - 48 & 0.00, 0.02 & 0.01, 0.10 & 0.01, 0.11 & 0.00, 0.06 & 0.01, 0.14 \\ - & [0.00, 0.07] & [0.00, 0.14] & [0.00, 0.16] & [0.00, 0.10] & [0.00, 0.18] \\[2ex] \midrule -\multicolumn{6}{l}{\textit{U.S. variables:}} \\ - & ip & cpi & ffr & vxo & tot \\ \midrule - 0 & 0.00, 0.00 & 0.01, 0.04 & 0.00, 0.00 & 0.00, 0.00 & 0.02, 0.08 \\ - & [0.00, 0.01] & [0.00, 0.06] & [0.00, 0.00] & [0.00, 0.01] & [0.00, 0.11] \\ - 12 & 0.00, 0.02 & 0.03, 0.18 & 0.04, 0.20 & 0.00, 0.04 & 0.03, 0.16 \\ - & [0.00, 0.05] & [0.00, 0.24] & [0.00, 0.28] & [0.00, 0.09] & [0.00, 0.23] \\ - 24 & 0.00, 0.05 & 0.03, 0.20 & 0.06, 0.30 & 0.00, 0.02 & 0.02, 0.12 \\ - & [0.00, 0.10] & [0.00, 0.26] & [0.00, 0.41] & [0.00, 0.07] & [0.00, 0.18] \\ - 48 & 0.00, 0.06 & 0.03, 0.20 & 0.06, 0.29 & 0.00, 0.05 & 0.01, 0.10 \\ - & [0.00, 0.10] & [0.00, 0.26] & [0.00, 0.39] & [0.00, 0.10] & [0.00, 0.15] \\ -\midrule\bottomrule -\end{tabular}