*-------------------------------------------------------------------------------------* | This is the program file for the September/October | | 2002 Review article "How Well Do Monetary Fundamentals Forecast Exchange | | Rates?" by Chris Neely and Lucio Sarno. | | | | | | There are 4 gauss programs and 2 gauss libraries used in this paper. | | ols.prg--Produces results in columns 3-8 of Table 1. | | predict.prg--Produces results in columns 9-12 of Table 1. | | Dstmp.set--Used in ols.prg and predict.prg | | Rbste.set--Used in ols.prg and predict.prg | | | | Fig1.prg-Produces data and charts for figure 1. | | Fig2.prg-Produces data and chart for figure 2. | *-------------------------------------------------------------------------------------* /**************************************************************************/ OLS.PRG /*This program is for the September/October 2002 Review article called "How Well Do Monetary Fundamentals Forecast Exchange Rates?" by Christopher Neely and Lucio Sarno. It produces the results in columns 3-8 of Table 1. The program uses the following datasets: can.dat, ger.dat, sws.dat, jpn.dat. It outputs the results to a file called ols.out.*/ new; outwidth 132; #include D:\Neely\Review~1\FXForecasting\pre-Fred\rbstse.set; #include D:\Neely\Review~1\FXForecasting\pre-Fred\dstamp.set; output file=D:\Neely\Review~1\FXForecasting\pre-Fred\ols.out ; output on; dstamp; format /rd 8,3; ts=hsec; " OLS.PGM"; "NONPARAMETRIC BOOTSTRAP"; @===========================================================@ @:::::::::USER DEFINED VARIABLES:::::::::::::::::::::::::::@ @----------------------------------------------------------@ country =1; @ 1--CAN. 2--DEU. 3--JPN. 4--SWS @ do while country<=4; t1=76; nsim =2000; @ NUMBER OF REPLICATIONS @ if country==2; p=5; else; p=4; endif; snstve =0; @ 0--DGP AS ESTIMATED. 1--SENSITIVITY ANALYSIS FOR DGP @ mix =1; @ IF NARROW==0, COUNTRY==1 USE M3CAN, M1US @ svz =2; @ INITIAL VALUES Z: @ @ 0--MEANS. @ @ 1--ACTUAL VALUES. @ @ 2--RANDOM DRAW (NONPARAMETRIC BOOTSTRAP WITH RPLCE ONLY) @ simproc =0; @ BOOTSTRAP OR NORMAL. 0--BOTH. 1--NORMAL. 2--BOOTSTRAP @ narrow =0; @ 0--M1's. 1--M3's @ sa =0; @ 0--NSA MONEY, PRICES. 1--SA MONEY, PRICES @ ci =0; @ 0--F(t). 1--CI ON M,Y. 2--CI ON M,Y,P. 3--P(t)-P*(t) @ replace =1; @ 0--SAMPLING WITHOUT REPLACEMENT. 1--WITH REPLACEMENT @ exra =0; @ 0--NOMINAL. 1--REAL @ seed=72085; lambda=1; @--------------------------------------------------------@ if sa==0; t0=4; endif; nobs=t1-t0+1; @========================================================@ @::::::::: SET UP THE DATA ::::::::::::::::::::::::::::::@ @========================================================@ if country==1; "CANADIAN DOLLAR"; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\can.dat; else; load y[76,10]=cansa.dat; endif; endif; if country==2; "DEUTSCHEMARK "; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\ger.dat; else; load y[76,10]=gersa.dat; endif; endif; if country==3; "JAPANESE YEN "; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\jpn.dat; else; load y[76,10]=jpnsa.dat; endif; endif; if country==4; "SWISS FRANC "; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\sws.dat; else; load y[76,10]=swssa.dat; endif; endif; if narrow==0; mhome=y[.,2]; mstar=y[.,7]; endif; if country==1;if narrow==0;if mix==1; mhome=y[.,2];mstar=y[.,8]; endif; endif; endif; yhome=y[.,4]; phome=y[.,5]; spotlev=y[.,6]; ystar=y[.,9]; pstar=y[.,10]; mtil=zeros(t1,1); ptil=zeros(t1,1); @---LOG LEVELS OF ANNUAL AVERAGES (XTIL MEANS XHOME-XSTAR) ---------@ ytil=ln(yhome./ystar); if sa==0; mtil[t0:t1,1]= ln((mhome[t0:t1,1]+mhome[t0-1:t1-1,1]+mhome[t0-2:t1-2,1]+mhome[t0-3:t1-3,1])./ (mstar[t0:t1,1]+mstar[t0-1:t1-1,1]+mstar[t0-2:t1-2,1]+mstar[t0-3:t1-3,1])); endif; spot=ln(spotlev); @ NOMINAL RATE @ qspot=ln(spotlev[1:t1])-ptil; @ REAL RATE @ @====================================================================@ @=================END OF DATA SETUP =================================@ @====================================================================@ @------------ ESTIMATE MODEL UNDER NULL TO USE AS DGP ---------------@ @--------------------------------------------------------------------@ @---------------- SELECTION OF REGRESSOR, Z ------------------------@ @--------------------------------------------------------------------@ if ci==0; z=mtil[t0:t1,1]-lambda*ytil[t0:t1,1]-spot[t0:t1,1]; endif; @ INITIAL VALUES FOR Z IN AUTOREGRESSION @ if svz==2; strtz=meanc(z); endif; @ PROTECT PARAMETRIC BOOTSTRAP @ @-------------- SELECTION OF DEPENDENT VARIABLE ---------------@ if exra==0; y=spot[t0:t1,1]-spot[t0-1:t1-1,1]; endif; @----------------------------------------------------------------@ nn=rows(z); x=z[p:nn-1,1]; @ THESE 2 LINES CREATE DESIGN MATRIX WITH P-LAGS OF Z @ i=1; do while i<=p-1; x=x~z[p-i:nn-i-1,1]; i=i+1; endo; z0=x; @ SAVE FOR LM TEST ON Z AUTOREGRESSION AND RANDOM @ @ DRAW FOR STARTING VALUES IN BOOTSTRAP WITH RPLCE @ cnst=ones(rows(x),1); x=cnst~x; z=z[p+1:nn,1]; if snstve==0; @ ESTIMATE AUTOREGRESSION ON Z'S @ bznull=inv(x'x)*x'z; endif; uz=z-x*bznull; @ RESIDUAL FOR Z @ uznull=uz; @ RESIDUAL FOR Z FOR NONPARAMETRIC BOOTSTRAP @ y=y[p+1:nn,1]; x=ones(rows(y),1); bxnull=inv(x'x)*x'y; @ EXCHANGE RATE REGRESSION UNDER NULL @ ux=y-x*bxnull; @ RESIDUAL FOR D(exra) @ uxnull=ux; @ RESIDUAL FOR NONPARAMETRIC BOOTSTRAP @ u=ux~uz; sigma=u'u/nn; pu=chol(sigma); unull=uxnull~uznull; @ ORIGINAL RESIDUALS FOR NONPARAMETRIC BOOTSTRAP @ nobsnp=rows(uxnull); @------------------------------------------------------------@ @----------------END ESTIMATION OF MODEL UNDER NULL----------@ @============================================================@ @---------- ESTIMATES FROM THE DATA FOR COMPUTING P VALUES ---@ @-------------------------------------------------------------@ betad=zeros(5,1); rsqd=zeros(5,1); tr20d=zeros(5,1); trad=zeros(5,1); alphad=zeros(5,1); anwlag=zeros(5,1); hzn=1; do while hzn<=5; if hzn==1; k=1; endif; if hzn==2; k=4; endif; if hzn==3; k=8; endif; if hzn==4; k=12; endif; if hzn==5; k=16; endif; @::::::::::::: SELECTION OF Z ::::::::::::::::::::::::::::::::::::::::::@ if ci==0; x=mtil[t0:t1-k,1]-lambda*ytil[t0:t1-k,1]-spot[t0:t1-k,1]; endif; @----------------- SELECTION OF EXCHANGE RATE -------------------@ if exra==0; y=spot[t0+k:t1,1]-spot[t0:t1-k,1]; endif; z=ones(rows(x),1)~x; nv=rows(z); sto=inv(z'z)*z'*y; resid=y-z*sto; alphad[hzn,1]=sto[1,1]; @ CONSTANT @ betad[hzn,1]=sto[2,1]; @ SLOPE COEFFICIENT @ rsqd[hzn,1]=1-(stdc(resid)/stdc(y))^2; @ R-SQUARE @ j=1; do while j<=1; if j==1; nwlag=20; hh=0; endif; vc=rbstse(resid,x,nwlag,hh); @ SEND WITHOUT CONSTANT @ stderr=sqrt(diag(vc)); if j==1; tr20d[hzn,1]=betad[hzn,1]/stderr[2,1]; endif; j=j+1; endo; hzn=hzn+1; endo; dparm=betad~rsqd~tr20d~trad~alphad~anwlag; @ ASSIGN TO DPARM @ sto=maxc(tr20d); sti=maxc(trad); @ !! 1@ dparm2=sti|sto; @ !! 2MAXIMAL T-RATIOS @ idx=1|4|8|12|16; OUTPUT ON; @============================================================@ @-----------END ESTIMATION FROM DATA FOR CONFIDENCE LEVEL----@ @============================================================@ if simproc==0 or simproc==1; /*"::::::::::::: NONPARAMETRIC BOOTSTRAP ::::::::::::::::::::::";*/ @------------------------------------------------------------@ seed=72085; ve=unull; @ SAVE ORIGINAL RESIDUALS AS VE @ beta=zeros(nsim,5); rsq=zeros(nsim,5); tra=zeros(nsim,5); tr20=zeros(nsim,5); mtra=zeros(nsim,1); mtr20=zeros(nsim,1); @ !! 3@ output off; nrep=1; do while nrep <= nsim; @ BEGIN LOOP @ @-------------- RESAMPLE WITH REPLACEMENT--STANDARD BOOTSTRAP -------------- @ if replace==1; v=ve; @ RESET RESIDUAL SERIES TO BE SAMPLED @ epsln=zeros(nobsnp,2); n=nobsnp; t=1; do while t<=nobsnp; u=rndus(1,1,seed); i=1; do while i<=nobsnp-1; if u >= (i-1)/n; if u <= i/n; epsln[t,.]=v[i,.]; if svz==2; if t==1; strtz=z0[i,.]'; endif; endif; goto alright; endif; endif; i=i+1; endo; alright: t=t+1; endo; endif; @--------------- END SAMPLING WITH REPLACEMENT ------------------------------@ uxsim=epsln[.,1]; @ RESIDUALS FOR EXCHANGE RATE CHANGE @ uzsim=epsln[.,2]; @ RESIDUALS FOR Z'S @ yxsim=zeros(nobsnp,1); yzsim=zeros(nobsnp,1); yxsim=bxnull+uxsim; @ SIMULATED EXCHANGE RATE CHANGE @ @ SIMULATED Z'S @ yzsim=recserar(uzsim+bznull[1,1],ones(p,1).*strtz,bznull[2:p+1,1]); @-------- RUN REGRESSION AND COMPUTE STATISTIC FOR EACH HORIZON ----- @ hzn=1; do while hzn<=5; yx=zeros(nobsnp,1); if hzn==1; k=1; endif; if hzn==2; k=4; endif; if hzn==3; k=8; endif; if hzn==4; k=12; endif; if hzn==5; k=16; endif; x=yzsim[1:nobsnp-k,1]; @ THE REGRESSOR @ voo=rows(x); z=ones(voo,1)~x; @ ADD A CONSTANT @ t=1; do while t<=nobsnp-k; @ ACCUMULATE CHANGES IN EX @ yx[t,1]=sumc(yxsim[t+1:t+k,1]); t=t+1; endo; yx=yx[1:nobsnp-k,1]; @ e(t+k)-e(t) @ bxsim=inv(z'z)*z'*yx; @ REGRESS K-HORZ CHANGE IN EXRA ON Z @ beta[nrep,hzn]=bxsim[2,1]; @ SAVE SLOPE COEFFICIENT @ resid=yx-z*bxsim; rsq[nrep,hzn]=1-(stdc(resid)/stdc(yx))^2; @ SAVE R-SQUARE @ j=1; do while j<=1; if j==1; nwlag=20; hh=0; endif; vc=rbstse(resid,x,nwlag,hh); @ SEND WITHOUT CONSTANT @ stderr=sqrt(diag(vc)); if j==1; tr20[nrep,hzn]=beta[nrep,hzn]/stderr[2,1]; endif; j=j+1; endo; "Horizon=";;k;;" NREP = ";;nrep; hzn=hzn+1; endo; mtra[nrep]=maxc(tra[nrep,.]'); @!! 4MAXIMAL tra OVER THE HORIZONS @ mtr20[nrep]=maxc(tr20[nrep,.]'); @!! 5MAXIMAL tr20 OVER THE HORIZONS @ nrep=nrep +1; endo; @ MONTE CARLO DISTRIBUTION COMPUTED @ @---------------------------------------------------------------@ @====================================================@ @:: TABULATE MONTE CARLO DISTRIBUTION BY HORIZON ::::@ @-----------------------------------------------------@ output on; stat=1; do while stat<=4; if stat==1; phi=beta; /*" BETA ";*/ endif; if stat==2; phi=rsq; /*" R-SQUARE ";*/ endif; if stat==3; phi=tr20; /*" NW(20) ";*/ endif; if stat==4; phi=tra; /*" NW(A) ";*/ endif; phibar=meanc(phi); phidev=phi-phibar'; @ DEVIATIONS FROM MEAN @ mm=(phidev'*phidev)/nsim; @ COVARIANCE MATRIX @ sd=sqrt(diag(mm)); @----------------------------------------------------@ hzn=1; do while hzn <=5; if hzn==1; k=1; endif; if hzn==2; k=4; endif; if hzn==3; k=8; endif; if hzn==4; k=12; endif; if hzn==5; k=16; endif; a=sortc(phi[.,hzn],1); n025=round(0.025*nsim); n05=round(0.05*nsim); n50=round(0.5*nsim); n95=round(0.95*nsim); n975=round(0.975*nsim); @----------------- WRITE OUTPUT ------------------------------------@ @ CONFIDENCE LEVEL FOR STATISTIC stat, HORIZ hzn @ conf=counts(a,dparm[hzn,stat])/nsim; if hzn==1 and phi==beta; medians=a[n50,1];else; medians=medians|a[n50,1]; endif; if hzn==1 and phi==beta; msl=(1-conf);else; msl=msl|(1-conf); endif; hzn=hzn+1; endo; stat=stat+1; endo; mbeta=medians[1:5,1];mrsqd=medians[6:10,1];mnw20=medians[11:15,1];mslA=medians[16:20,1]; mslbeta=msl[1:5,1];mslrsqd=msl[6:10,1];mslnw20=msl[11:15,1];mslA=msl[16:20,1]; adjbeta=betad-mbeta; " HORIZON OLSBETA Adj-Beta t20 P(t20) R-SQ P(R-SQ)"; idx~betad~adjbeta~tr20d~mslnw20~rsqd~mslrsqd; if country==1; stats=idx~betad~adjbeta~tr20d~mslnw20~rsqd~mslrsqd; else; stats=stats|idx~betad~adjbeta~tr20d~mslnw20~rsqd~mslrsqd; endif; endif; country=country+1; endo; @--------------- END NONPARAMETRIC BOOTSTRAP --------------------@ @================================================================@ "Elapsed Time (minutes)";;(hsec-ts)/(60*100); output off; /***************************************************************************/ /***************************************************************************/ PREDICT.PRG /*This program is for the September/October 2002 Review article called "How Well Do Monetary Fundamentals Forecast Exchange Rates?" by Christopher Neely and Lucio Sarno. It produces the results in columns 9-12 of Table 1. The program uses the following datasets: can.dat, ger.dat, sws.dat, jpn.dat. It outputs the results to a file called predict.out.*/ new; outwidth 132; #include D:\Neely\Review~1\FXForecasting\pre-Fred\rbstse.set; #include D:\Neely\Review~1\FXForecasting\pre-Fred\dstamp.set; /*#include D:\Neely\Review~1\FXForecasting\pre-Fred\procs.lib;*/ output file=D:\Neely\Review~1\FXForecasting\pre-Fred\mark.out; output on; dstamp; format /rd 8,3; ts=hsec; " PREDICT.PGM"; " NONPARAMETRIC BOOTSTRAP"; @===========================================================@ @:::::::::USER DEFINED VARIABLES:::::::::::::::::::::::::::@ @----------------------------------------------------------@ country =1; @ 1--CAN. 2--DEU. 3--JPN. 4--SWS. @ do while country<=4; t1=76; nsim =2000; @ NUMBER OF REPLICATIONS @ back =40; @ OBS BACK FROM END OF SAMPLE FROM WHICH TO BEGIN FORECASTING@ snstve =0; @ 0--DGP AS ESTIMATED. 1--SENSITIVITY ANALYSIS FOR DGP @ mix =1; @ IF NARROW==0, COUNTRY==1 USE M3CAN, M1US @ svz =2; @ INITIAL VALUES Z: @ @ 0--MEANS. @ @ 1--ACTUAL VALUES. @ @ 2--RANDOM DRAW (NONPARAMETRIC BOOTSTRAP WITH RPLCE ONLY) @ simproc =0; @ BOOTSTRAP OR NORMAL. 0--BOTH. 1--NORMAL. 2--BOOTSTRAP @ narrow =0; @ 0--M1's. 1--M3's @ sa =0; @ 0--NSA MONEY, PRICES. 1--SA MONEY, PRICES @ ci =0; @ 0--F(t). 1--CI ON M,Y. 2--CI ON M,Y,P. 3--P(t)-P*(t) @ replace =1; @ 0--SAMPLING WITHOUT REPLACEMENT. 1--WITH REPLACEMENT @ exra =0; @ 0--NOMINAL. 1--REAL @ drift =0; @ 0--RANDOM WALK-NO DRIFT 1--RANDOM WALK-WITH DRIFT @ if country==2; @ LAG LENGTH OF THE AUTOREGRESSION FOR Z @ p=5; else; p=4; endif; seed=72085; lambda=1; @--------------------------------------------------------@ if sa==0; t0=4; endif; nobs=t1-t0+1; tf0=t1-back; @ DATE WHEN FIRST FORECAST COMPUTED. 40--81,4. 35--83,1 @ @========================================================@ @::::::::: SET UP THE DATA ::::::::::::::::::::::::::::::@ @========================================================@ if country==1; "CANADIAN DOLLAR"; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\can.dat; else; load y[76,10]=cansa.dat; endif; endif; if country==2; "DEUTSCHEMARK "; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\ger.dat; else; load y[76,10]=gersa.dat; endif; endif; if country==3; "JAPANESE YEN "; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\jpn.dat; else; load y[76,10]=jpnsa.dat; endif; endif; if country==4; "SWISS FRANC "; if sa==0; load y[76,10]=D:\Neely\Review~1\FXForecasting\pre-Fred\sws.dat; else; load y[76,10]=swssa.dat; endif; endif; if narrow==0; mhome=y[.,2]; mstar=y[.,7]; endif; if narrow==1; mhome=y[.,3]; mstar=y[.,8]; endif; if country==1;if narrow==0;if mix==1; mhome=y[.,2];mstar=y[.,8]; endif; endif; endif; yhome=y[.,4]; phome=y[.,5]; spotlev=y[.,6]; ystar=y[.,9]; pstar=y[.,10]; mtil=zeros(t1,1); ptil=zeros(t1,1); @---LOG LEVELS OF ANNUAL AVERAGES (XTIL MEANS XHOME-XSTAR) ---------@ ytil=ln(yhome./ystar); if sa==0; mtil[t0:t1,1]= ln((mhome[t0:t1,1]+mhome[t0-1:t1-1,1]+mhome[t0-2:t1-2,1]+mhome[t0-3:t1-3,1])./ (mstar[t0:t1,1]+mstar[t0-1:t1-1,1]+mstar[t0-2:t1-2,1]+mstar[t0-3:t1-3,1])); endif; spot=ln(spotlev); @ NOMINAL RATE @ qspot=ln(spotlev[1:t1])-ptil; @ REAL RATE @ @====================================================================@ @=================END OF DATA SETUP =================================@ @====================================================================@ @------------ ESTIMATE MODEL UNDER NULL TO USE AS DGP ---------------@ @--------------------------------------------------------------------@ @---------------- SELECTION OF REGRESSOR, Z ------------------------@ @--------------------------------------------------------------------@ if ci==0; z=mtil[t0:t1,1]-lambda*ytil[t0:t1,1]-spot[t0:t1,1]; endif; @ INITIAL VALUES FOR Z IN AUTOREGRESSION @ if svz==2; strtz=meanc(z); endif; @ PROTECT PARAMETRIC BOOTSTRAP @ @-------------- SELECTION OF DEPENDENT VARIABLE ---------------@ if exra==0; y=spot[t0:t1,1]-spot[t0-1:t1-1,1]; endif; /*{unull,bxnull,bznull,nobsnp,z00}=mark_dgp(z,y,p);*/ @----------------------------------------------------------------@ nn=rows(z); x=z[p:nn-1,1]; @ THESE 2 LINES CREATE DESIGN MATRIX WITH P-LAGS OF Z @ i=1; do while i<=p-1; x=x~z[p-i:nn-i-1,1]; i=i+1; endo; z00=x; @ SAVE FOR LM TEST ON Z AUTOREGRESSION AND RANDOM @ @ DRAW FOR STARTING VALUES IN BOOTSTRAP WITH RPLCE @ cnst=ones(rows(x),1); x=cnst~x; z=z[p+1:nn,1]; if snstve==0; @ ESTIMATE AUTOREGRESSION ON Z'S @ bznull=inv(x'x)*x'z; endif; uz=z-x*bznull; @ RESIDUAL FOR Z @ uznull=uz; @ RESIDUAL FOR Z FOR NONPARAMETRIC BOOTSTRAP @ @-----------------------------------------------------------@ @----------------------------------------------------------@ y=y[p+1:nn,1]; x=ones(rows(y),1); bxnull=inv(x'x)*x'y; @ EXCHANGE RATE REGRESSION UNDER NULL @ ux=y-x*bxnull; @ RESIDUAL FOR D(exra) @ uxnull=ux; @ RESIDUAL FOR NONPARAMETRIC BOOTSTRAP @ @u=ux~uz; sigma=u'u/nn; pu=chol(sigma);@ unull=uxnull~uznull; @ ORIGINAL RESIDUALS FOR NONPARAMETRIC BOOTSTRAP @ nobsnp=rows(uxnull); @------------------------------------------------------------@ @----------------END ESTIMATION OF MODEL UNDER NULL----------@ @============================================================@ @---------- ESTIMATES FROM THE DATA FOR COMPUTING P VALUES ---@ @-------------------------------------------------------------@ @=============================================================@ @::::: BEGIN STANDARD FORECASTING EXERCISE :::::::::::::::::::@ @ ESTIMATE MODEL USING DATA UP THROUGH t, BEGINNING WITH @ @ t=tf0. FORECAST e[t+k] @ @-------------------------------------------------------------@ dm1d=zeros(5,1); @ DM(A) STAT FOR MODEL VERSUS RANDOM WALK FROM DATA @ dm20d=zeros(5,1); @ DM(20) STAT FOR MODEL VERSUS RANDOM WALK FROM DATA @ outdrw=zeros(5,1); @ OUT/RW RMSE RATIO FROM DATA @ indrw=zeros(5,1); @ IN/RW RMSE RATIO FROM DATA @ AAndrew=zeros(5,1); @ ANDREWS AR(1) RULE FOR AUTOMATIC BANDWIDTH @ hzn=1; do while hzn<=5; if hzn==1; k=1; endif; if hzn==2; k=4; endif; if hzn==3; k=8; endif; if hzn==4; k=12; endif; if hzn==5; k=16; endif; doagain: tf1=t1-k; @ Time at which last forecast is computed @ output on; fem=zeros(t1,1); ferw=zeros(t1,1);ferwd=zeros(t1,1); femin=zeros(t1,1); fitout=zeros(t1,1); fitrwd=zeros(t1,1); fitin=zeros(t1,1); @---------------- IN-SAMPLE STUFF --------------------------@ y=spot[t0+k:t1,1]-spot[t0:tf1,1]; x=mtil[t0:tf1,1]-lambda*ytil[t0:tf1,1] - spot[t0:tf1,1]; z=ones(rows(y),1)~x; gam=inv(z'z)*z'y; @--------------- OUT-OF-SAMPLE STUFF-----------------------@ t=tf0; do while t<=tf1; y0=spot[t0+k:t,1]-spot[t0:t-k,1]; @ SPOT DATA THRU t @ x0=mtil[t0:t-k,1]-lambda*ytil[t0:t-k,1] - spot[t0:t-k,1]; @ REG. THRU t-k @ z0=ones(rows(y0),1)~x0; beta=inv(z0'z0)*z0'*y0; @ EST. REG. s(t)-s(t-k) = a + bz(t-k) @ mu=meanc(spot[t0+1:t,1]-spot[t0:t-1,1]); @ RANDOM WALK DRIFT TERM @ /*-------------------------------------------------------- NOTATION: femin--FORECAST ERROR MODEL IN SAMPLE fem --FORECAST ERROR OF MODEL (OUT OF SAMPLE) ferwd--FORECAST ERROR RANDOM WALK WITH DRIFT ferw --FORECAST ERROR RANDOM WALK (NO DRIFT) ----------------------------------------------------*/ femin[t,1]=spot[t+k,1]-spot[t,1] -gam[1,1]-gam[2,1]*(mtil[t,1]-lambda*ytil[t,1]-spot[t,1]); fitin[t,1]=spot[t+k,1]-spot[t,1]-femin[t,1]; fem[t,1]=spot[t+k,1]-spot[t,1] -beta[1,1]-beta[2,1]*(mtil[t,1]-lambda*ytil[t,1]-spot[t,1]); fitout[t,1]=spot[t+k,1]-spot[t,1]-fem[t,1]; ferwd[t,1]=spot[t+k,1]-spot[t,1]-k*mu; fitrwd[t,1]=k*mu; ferw[t,1]=spot[t+k,1]-spot[t,1]; t=t+1; endo; @----------- COMPUTE RMSEs ------------------------- @ @----------- MULTIPLY BY 100 EXPRESS EXCHANGE RATE --@ @---------- CHANGES IN PERCENT ----------------------@ @----------------------------------------------------@ rmsemin=100*sqrt(meanc(femin[tf0:tf1,1]^2)); rmsem=100*sqrt(meanc(fem[tf0:tf1,1]^2)); rmserwd=100*sqrt(meanc(ferwd[tf0:tf1,1]^2)); rmserw=100*sqrt(meanc(ferw[tf0:tf1,1]^2)); @--------------------------------------------------@ @-----------DIEBOLD-MARIANO TEST-------------------@ /*MODEL AGAINST RW--NO DRIFT*/ if drift==0; d=fem[tf0:tf1,1]^2-ferw[tf0:tf1,1]^2; endif; @ LOSS DIFFERENTIAL @ /*MODEL AGAINST RW--WITH DRIFT*/ if drift==1; d=fem[tf0:tf1,1]^2-ferwd[tf0:tf1,1]^2; endif; @ LOSS DIFFERENTIAL @ dbar1=meanc(d); @ SAMPLE MEAN LOSS DIFFERENTIAL @ resid=d-dbar1; @---------------------------------------------------------------------@ @------------- DO ANDREWS AR(1) PROC TO DETERMINE NWLAG ---------------@ v=resid; @ V PROCESS FOR ANDREWS LAG @ nv=rows(v); yv=v[2:nv]; xv=ones(nv-1,1)~v[1:nv-1]; bv=inv(xv'xv)*xv'*yv; @ RUN AR(1) ON V-PROCESS FOR ANDREWS LAG @ rhov=bv[2]; av=4*(rhov^2)*((1-rhov)^4); bv=((1-rhov)^6)*((1+rhov)^2); alpv=av/bv; andrews=1.1447*(alpv*nv)^(1/3); andrews=round(andrews); @ ANDREWS DATA-DEPENDENT NWLAG @ if andrews>=back; andrews=back-2; endif; nwlag=andrews; redo20=0; @---------------- NWLAG SET ----------------------------------@ tryagin1: ft=resid'; nmom=rows(ft); n2=cols(ft); if nwlag>=n2; nwlag=n2-1; endif; w=zeros(nmom,nmom) ; t=1; do while t <= n2 ; w = ft[.,t]*ft[.,t]' + w ; t=t+1 ; endo ; gamd0=w/n2; clear s; i=1 ; do while i <=nwlag ; w=zeros(nmom,nmom) ; t=1 ; do while t <= n2-i ; w = ft[.,t]*ft[.,t+i]' + w ; t=t+1 ; endo ; w=w/(n2-i); s = s + (w + w')*(1-(i/(nwlag+1))); i=i+1 ; endo ; if gamd0+s<=0; nwlag=nwlag-1; goto tryagin1; endif; vc=sqrt((gamd0+s)/(n2-1)); @------------------------------------------------------------------@ if redo20==0; dm1d[hzn]=dbar1/vc; @ DIEBOLD-MARIANO STATISTIC @ if drift==0; outdrw[hzn]=rmsem/rmserw; endif; @ OUT/RW RMSE RATIO FROM DATA for RW-NO DRIFT @ if drift==1; outdrw[hzn]=rmsem/rmserwd; endif; @ OUT/RW RMSE RATIO FROM DATA for RW-WITH DRIFT @ indrw[hzn]=rmsemin/rmserw; @ IN/RW RMSE RATIO FROM DATA @ AAndrew[hzn]=nwlag; @ ANDREWS AUTOMATIC BANDWIDTH SELECTOR @ redo20=redo20+1; nwlag=20;goto tryagin1; endif; if redo20==1; dm20d[hzn]=dbar1/vc; redo20=0; endif; @------------------------------------------------------------------@ hzn=hzn+1; endo; @------------------------------------------------------------------@ dparm=dm1d~dm20d~outdrw; @ ASSIGN TO DPARM @ idx=1|4|8|12|16; OUTPUT ON; @============================================================@ @-----------END ESTIMATION FROM DATA FOR CONFIDENCE LEVEL----@ @============================================================@ if simproc==0 or simproc==2; /*"::::::::::::: NONPARAMETRIC BOOTSTRAP ::::::::::::::::::::::";*/ @------------------------------------------------------------@ seed=72085; ve=unull; @ SAVE ORIGINAL RESIDUALS AS VE @ dm1=zeros(nsim,5); dm20=zeros(nsim,5); outrw=zeros(nsim,5); mdm1=zeros(nsim,1); mdm20=zeros(nsim,1); moutrw=zeros(nsim,1); output off; nrep=1; do while nrep <= nsim; @ BEGIN LOOP @ "Horizon=";;k;;" NREP = ";;nrep; @-------------- RESAMPLE WITH REPLACEMENT--STANDARD BOOTSTRAP -------------- @ if replace==1; v=ve; @ RESET RESIDUAL SERIES TO BE SAMPLED @ epsln=zeros(nobsnp,2); n=nobsnp; t=1; do while t<=nobsnp; u=rndus(1,1,seed); i=1; do while i<=nobsnp-1; if u >= (i-1)/n; if u <= i/n; epsln[t,.]=v[i,.]; if svz==2; if t==1; strtz=z00[i,.]'; endif; endif; goto alright; endif; endif; i=i+1; endo; alright: t=t+1; endo; endif; @--------------- END SAMPLING WITH REPLACEMENT ------------------------------@ /*{yxsim,yzsim}=mark_data(epsln,bxnull,bznull,p,strtz);*/ uxsim=epsln[.,1]; @ RESIDUALS FOR EXCHANGE RATE CHANGE @ uzsim=epsln[.,2]; @ RESIDUALS FOR Z'S @ yxsim=zeros(nobsnp,1); yzsim=zeros(nobsnp,1); yxsim=bxnull+uxsim; @ SIMULATED EXCHANGE RATE CHANGE @ @ SIMULATED Z'S @ yzsim=recserar(uzsim+bznull[1,1],ones(p,1).*strtz,bznull[2:p+1,1]); @-------- RUN REGRESSION AND COMPUTE STATISTIC FOR EACH HORIZON ----- @ hzn=1; do while hzn<=5; yx=zeros(nobsnp,1); if hzn==1; k=1; endif; if hzn==2; k=4; endif; if hzn==3; k=8; endif; if hzn==4; k=12; endif; if hzn==5; k=16; endif; x=yzsim[1:nobsnp-k,1]; @ THE REGRESSOR @ voo=rows(x); z=ones(voo,1)~x; @ ADD A CONSTANT @ t=1; do while t<=nobsnp-k; @ ACCUMULATE CHANGES IN EX @ yx[t+k,1]=sumc(yxsim[t+1:t+k,1]); t=t+1; endo; t0=1; t1=nobsnp; tf0=t1-back; tf1=t1-k; t=tf0; do while t<=tf1; y0=yx[t0+k:t]; x0=x[t0:t-k]; z0=ones(rows(y0),1)~x0; beta=inv(z0'z0)*z0'*y0; @ EST. REG. s(t)-s(t-k) = a + bz(t-k) @ mu=meanc(yx[t0+k:t]); @ DRIFT TERM @ fem[t]=yx[t+k]-beta[1]-beta[2]*x[t]; ferwd[t]=yx[t+k]-k*mu; ferw[t]=yx[t+k]; t=t+1; endo; @-----------RMSE'S---------------------------------@ rmsem=100*sqrt(meanc(fem[tf0:tf1,1]^2)); rmserw=100*sqrt(meanc(ferw[tf0:tf1,1]^2)); rmserwd=100*sqrt(meanc(ferwd[tf0:tf1,1]^2)); @-----------DIEBOLD-MARIANO TEST-------------------@ /*MODEL AGAINST RW--NO DRIFT */ if drift==0; d=fem[tf0:tf1,1]^2-ferw[tf0:tf1,1]^2; endif; @ LOSS DIFFERENTIAL @ /*MODEL AGAINST RW--WITH DRIFT */ if drift==1; d=fem[tf0:tf1,1]^2-ferwd[tf0:tf1,1]^2; endif; @ LOSS DIFFERENTIAL @ dbar1=meanc(d); @ SAMPLE MEAN LOSS DIFFERENTIAL @ resid=d-dbar1; @---------------------------------------------------------------------@ @------------- DO ANDREWS AR(1) PROC TO DETERMINE NWLAG ---------------@ v=resid; @ V PROCESS FOR ANDREWS LAG @ nv=rows(v); yv=v[2:nv]; xv=ones(nv-1,1)~v[1:nv-1]; bv=inv(xv'xv)*xv'*yv; @ RUN AR(1) ON V-PROCESS FOR ANDREWS LAG @ rhov=bv[2]; av=4*(rhov^2)*((1-rhov)^4); bv=((1-rhov)^6)*((1+rhov)^2); alpv=av/bv; andrews=1.1447*(alpv*nv)^(1/3); andrews=round(andrews); @ ANDREWS DATA-DEPENDENT NWLAG @ if andrews>=back; andrews=back-2; endif; nwlag=andrews; redo20=0; @---------------- NWLAG SET ----------------------------------@ tryagin3: ft=resid'; nmom=rows(ft); n2=cols(ft); if nwlag>=n2; nwlag=n2-1; endif; w=zeros(nmom,nmom) ; t=1; do while t <= n2 ; w = ft[.,t]*ft[.,t]' + w ; t=t+1 ; endo ; gamd0=w/n2; clear s; i=1 ; do while i <=nwlag ; w=zeros(nmom,nmom) ; t=1 ; do while t <= n2-i ; w = ft[.,t]*ft[.,t+i]' + w ; t=t+1 ; endo ; w=w/(n2-i); s = s + (w + w')*(1-(i/(nwlag+1))); i=i+1 ; endo ; if gamd0+s<=0; nwlag=nwlag-1; goto tryagin3; endif; vc=sqrt((gamd0+s)/(n2-1)); @------------------------------------------------------------------@ if redo20==0; dm1[nrep,hzn]=dbar1/vc; @ DIEBOLD-MARIANO STATISTIC@ if drift==0; outrw[nrep,hzn]=rmsem/rmserw; endif; @ OUT/RW RMSE RATIO FROM DATA RW--NO DRIFT @ if drift==1; outrw[nrep,hzn]=rmsem/rmserwd; endif; @ OUT/RW RMSE RATIO FROM DATA RW--WITH DRIFT @ redo20=redo20+1; nwlag=20; goto tryagin3; endif; if redo20==1; dm20[nrep,hzn]=dbar1/vc; redo20=0; endif; @------------------------------------------------------------------@ hzn=hzn+1; endo; nrep=nrep+1; endo; @ MONTE CARLO DISTRIBUTION COMPUTED @ @---------------------------------------------------------------@ @===============================================================@ @::::::::: TABULATE MONTE CARLO DISTRIBUTION BY HORIZON ::::::::@ @---------------------------------------------------------------@ output on; stat=1; do while stat<=3; if stat==1; phi=dm1 ; /*" DM(A)-RW(NODRIFT) "*/; endif; if stat==2; phi=dm20 ;/*" DM(20)-RW(NODRIFT) "*/; endif; if stat==3; phi=outrw;/*" OUT/RW "*/; endif; phibar=meanc(phi); phidev=phi-phibar'; @ DEVIATIONS FROM MEAN @ mm=(phidev'*phidev)/nsim; @ COVARIANCE MATRIX @ sd=sqrt(diag(mm)); @----------------------------------------------------@ /*"NUMBER OF REPLICATIONS--";;nsim;*/ hzn=1; do while hzn <=5; if hzn==1; k=1; endif; if hzn==2; k=4; endif; if hzn==3; k=8; endif; if hzn==4; k=12; endif; if hzn==5; k=16; endif; a=sortc(phi[.,hzn],1); n025=round(0.025*nsim); n05=round(0.05*nsim); n10=round(0.10*nsim); n50=round(0.5*nsim); n90=round(0.9*nsim); n95=round(0.95*nsim); n975=round(0.975*nsim); @----------------- WRITE OUTPUT ------------------------------------@ @ CONFIDENCE LEVEL FOR STATISTIC stat,HORIZ hzn @ conf=counts(a,dparm[hzn,stat])/nsim; if hzn==1 and phi==dm1; msl=conf; else; msl=msl|conf; endif; hzn=hzn+1; endo; stat=stat+1; endo; msldm1=msl[1:5,1]; msldm20=msl[6:10,1]; msloutrw=msl[11:15,1]; if drift==0; "RANDOM WALK--NO DRIFT"; " HORIZON OUT/RW P(OUT/RW) DM(20) P(DM(20))"; idx~outdrw~msloutrw~dm20d~msldm20; endif; if drift==1; "RANDOM WALK--WITH DRIFT"; " HORIZON OUT/RW P(OUT/RW) DM(20) P(DM(20))"; idx~outdrw~msloutrw~dm20d~msldm20; endif; endif; country=country+1; endo; @--------------- END NONPARAMETRIC BOOTSTRAP --------------------@ "Elapsed Time (minutes)";;(hsec-ts)/(60*100); output off; /**********************************************************************/ /**********************************************************************/ FIG1.PRG /*This program is for the September/October 2002 Review article called "How Well Do Monetary Fundamentals Forecast Exchange Rates?" by Christopher Neely and Lucio Sarno. It produces the data and graphs used in Figure 1. The raw data file is called MMDATA.wks and the output file with the data for Figure 1 is called fig1.xls.*/ library pgraph; /*------------------ Column headings of MMDATA.wks 1 Year 2 ITAE 3 ITAM 4 ITAY 5 USAM 6 USAY ----------------------*/ {x ,namel} = import("D:\\Neely\\REVIEW~1\\FXFore~1\\pre-Fred\\MMDATA.wks", 0, 0); x = miss(x,-999); x = selif(x,x[.,1] .>= 1880 .and x[.,1] .<= 1995); /* Col 2 ITAE, Col 3 ITAM, Col 4 ITAY, Col 5 USAM, Col 6 USAY, Col 7 USAP */ e = ln(x[.,2]); mi = ln(x[.,3]); yi = ln(x[.,4]); mu = ln(x[.,5]); yu = ln(x[.,6]); m = mi - mu; @ Define monetary variable @ y = yi - yu; @ Define output variable @ c = ones(rows(e),1); /* Recover cointegrating vector */ xx = c~m~y; bcoint = inv(xx'xx)*xx'e; bcoint; /* Forecast one-quarter ahead */ f = (m - y); ect = e - f; @ s(t) - f(t) @ de = e[2:rows(e),1] - e[1:rows(e)-1,1]; @ change in e from 2 to T @ xx = trimr(c~ect,0,1); @ Match e(t+1)-e(t) with f(t) @ bfull = inv(xx'xx)*xx'de; @ Full Sample Coefs @ dehat = xx*bfull; @ Full Sample Prediction @ xy(x[2:rows(x),1],100*(dehat~de)); /*------------- Compute recursive forecasts ----------------*/ /* Coefs are computed with data through t, forecasts of change at t+1 are made with data at t+1. */ /*------------------------------------------------------------*/ t0 = 55; t = t0; se = miss(zeros(rows(x),2),0); @ Store errors @ dehat = miss(zeros(rows(x),1),0); @ Store predictions @ do while t < rows(x)-1; @ Last coefs computed at t-2 @ xx = trimr(c~ect,0,1); @ Match e(t+1)-e(t) with s(t) - f(t) @ xx = xx[1:t,.]; @ 1~s(t)-f(t) @ b = inv(xx'xx)*xx'de[1:t,.]; @ s(t+1)-s(t) on 1~ect(t) from 1 to t@ mu = meanc(de[1:t,.]); @ mean FX change from 1 to t @ dehat[t+2,.] = (1~ect[t+1,.])*b; @ Predict e(t+1)-e(t) with s(t)-f(t)@ error1 = (de[t+1,1] - (1~ect[t+1,.])*b); @ Monetary forecast error @ error2 = (de[t+1,1] - mu); @ naive error - RW with drift @ se[t+2,.] = error1~error2; @ Errors at t+2 @ t = t + 1; endo; se = trimr(se,t0+1,0); rmse = sqrt(meanc(se^2)); theil = rmse[1]/rmse[2]; theil; year = trimr(x[.,1],t0+1,0); outde = trimr(de,t0,0); @ There is one fewer ob for de @ outdehat = trimr(dehat,t0+1,0); graphinit; graphset; begwind; window(2,1,0); setwind(1); @fonts("MICROB");@ _pltype = {1, 6}; _ptitlht = .28; _paxht = .25; _pnumht = .25; _plwidth = 8; _pypmax = 2; _pdate = 0; _pframe = 0|1; _pcolor = 8; _pmcolor = 8; xtics(1939,1995,10,0); xlabel("Year"); ylabel("Percentage Change in USD/ITL"); ydata= -100*(outdehat~outde); xy(year,ydata); @Export predicted and actual values to excel@ xldata=year~ydata; let vnames=year predict actual; z=export(xldata, "d:\\neely\\review articles\\fxforecasting\\pre-Fred\\fig1.xls", vnames); nextwind; xtics(1973,1995,3,0); ydata = -100*(outdehat[33:rows(outdehat),1]~outde[33:rows(outde),1]); xy(year[33:rows(year),1],ydata); outgrf = "D:\\neely\\REVIEW~1\\FXFore~1\\figures\\fig1.grf"; cmdstr = " -c=3" $+ " -cf=" $+ outgrf $+ " -w=15"; graphprt(cmdstr); endwind; /************************************************************************/ /************************************************************************/ FIG2.PRG /*This program is for the September/October 2002 Review article called "How Well Do Monetary Fundamentals Forecast Exchange Rates?" by Christopher Neely and Lucio Sarno. It produces the data and graph used in Figure 2. The raw data file is called Ger.txt and the output file with the data for Figure 1 is called fig2.xls.*/ new; library pgraph; graphset; /* Data is col. 1 date (yymm) col. 2 spot exchange rate (U.S.$/DM) col. 3 CPI for Germany col. 4 CPI for U.S. */ load data[] = d:\Neely\Review~1\FXFore~1\pre-Fred\Ger.txt; data = reshape(data,rows(data)/4,4); /* Compute Real Exchange Rate and express it in $/DM */ realexch = (data[.,4]./data[.,3]).*data[.,2]; /* Convert dates for Gauss graph */ datz = 1900 + (trunc(data[.,1]/100)+(data[.,1] % 100)/12); datz = datz[2:rows(datz)]; /* Compute % change from previous period */ relag1 = realexch[1:(rows(realexch)-1)]; renolag = realexch[2:rows(realexch)]; percent = 100*(renolag-relag1)./relag1; /* Graph % change of real exchange rate */ _pdate=0; _pline={1 6 1973.25 -12 1973.25 16 1 2 0}; _pframe=0; xtics(1960,1998,2,1); cnvtype= "3"; @ conversion file type @ wtime = "5"; @ time to wait, in seconds @ outgrf = "fig2.grf"; cmdstr = " -c=" $+ cnvtype $+ " -cf=" $+ outgrf $+ " -w=" $+ wtime; graphprt(cmdstr); xy(datz,percent); @Export datz and percent to excel@ xldata=datz~percent; let vnames=date percent; z=export(xldata, "d:\\neely\\review articles\\fxforecasting\\pre-Fred\\fig2.xls", vnames); /********************************************************************************************/ /********************************************************************************************/ DSTMP.SET proc (0) = dstamp; local d,t; format /rds 1,0; "@ ";;datestr(date);;" ";;timestr(time);; " @"; format /m1 10,4; retp; endp; /********************************************************************************************/ /********************************************************************************************/ RBSTE.PRG /*------------------------------------------------------------------- !! RBSTSE.SET: THIS PROC RETURNS ROBUST COVARIANCE MATRIX FOR REGRESSION IN PRESENCE OF BOTH SERIAL CORRELATION AND CONDITIONAL HETEROSKEDASTICITY USING METHOD OF NEWEY AND WEST USAGE: v=rbstse(resid,x,nwlag,hh); v=robust covariance matrix resid=Tx1 vector of regression residuals x=Tx(K-1) matrix of regressors (no constant) nwlag: obvious hh--1, Does Hansen-Hodrick ----------------------------------------------------------------*/ proc rbstse(resid,x,nwlag,hh) ; local hub,vcvnw,i,t,w,s,ft,nmom,n2 ; @-------------construct ft-----------------@ hub=rows(x); x=ones(hub,1)~x; ft=resid'.*x'; nmom=rows(ft); n2=cols(ft); w=zeros(nmom,nmom) ; t=1; do while t <= n2 ; w = ft[.,t]*ft[.,t]' + w ; t=t+1 ; endo ; s=w; i=1 ; do while i <= nwlag ; w=zeros(nmom,nmom) ; t=1 ; do while t <= n2-i ; w = ft[.,t]*ft[.,t+i]' + w ; t=t+1 ; endo ; if hh==1; s=s+(w+w');else; s = s + (w + w')*(1-(i/(nwlag+1))) ; endif; i=i+1 ; endo ; w=s; vcvnw=inv((x'x)*inv(w)*(x'x)); @ Covariance matrix @ retp(vcvnw) ; endp ; @=============================================================@ /******************************************************************************************/