close @wf !uselatestgdp = 0 'option for whether to always use the latest release of GDP, or use the release of GDP that was first available for each date. wfcreate(page=quarterly) q 1992 @now dbopen(t=fred) fetch gdpc1 rename gdpc1 gdp_latest %start = "2017-01" !its = @datediff(@now, @dateval(%start), "m") 'difference between current date and starting date, in months %datelist = "" for !i=0 to !its-1 %idate = @datestr(@dateadd(@dateval(%start, "YYYY-MM"), !i, "m"), "YYYY-MM") %datelist = %datelist + " " + %idate next 'loop through monthly files and fetch data, and estimate factors for %ldate {%datelist} statusline {%ldate} call createpage(%ldate) next 'create a monthly page to store forecasts pageselect quarterly %range = @pagesmpl series gdp_earliest pagecreate(page=monthly) m {%range} 'loop through months, fetch archival GDP from fred into quarterly page, and estimate MIDAS. pageselect quarterly for %ldate {%datelist} pageselect quarterly smpl @all %date = @datestr(@dateval(%ldate, "YYYY-MM"), "YYYYMMDD") 'FRED requires series name to include day fetch gdpc1@{%date} rename gdpc1_{%date} gdp_{%date} 'this is the quarter our monthly data is in. The quarter we need to forecast. The data is for the month before our date %date_f = @datestr(@dateval(%date, "YYYYMMDD"), "YYYY[Q]Q") 'this is the last quarter of actual gdp data we have %date_act = gdp_{%date}.@last 'difference between the two dates. Usually 0, but sometimes we're even more lagged on actual GDP, so it's 1 !lags = @datediff(@dateval(%date_F, "YYYY[Q]Q"), @dateval(%date_act), "Q") 'get list of generated factors %pagename = "m" + @replace(%ldate, "-","") pageselect {%pagename} %facs = factors.@members 'estimate midas pageselect quarterly smpl @first {%date_act} %monthlyvars = "" 'calculate which month of the quarter we are in (zero based) !month = @val(@right(%ldate,2)) !m_in_q = @mod(!month-1,3)-1 'build up list of midas variables (factors leaded by the month-in-quarter value for %j {%facs} %monthlyvars = %monthlyvars + " " + %pagename + "\" + %j + "(" + @str(!m_in_q) + ")" next %gdpvar = "gdp_" + %date if !uselatestgdp = 1 then %gdpvar = "gdp_latest" endif 'equation eq_{%date}_m.midas(fixedlag=12, freq=first) {%gdpvar} c {%gdpvar}(-!lags) @ {%monthlyvars} equation eq_{%date}_m.midas(fixedlag=12, freq=first) @pch({%gdpvar}) c @pch({%gdpvar}(-!lags)) @ {%monthlyvars} 'estimate baseline 'equation eq_{%date}_a.ls {%gdpvar} c {%gdpvar}(-!lags) equation eq_{%date}_a.ls @pch({%gdpvar}) c @pch({%gdpvar}(-!lags)) 'set sample to forecast sample (last value of actual data + 1 until forecast period - usually same thing) smpl {%date_act}+1 {%date_f} eq_{%date}_a.forecast(f=na) gdp_f_a_{%date} eq_{%date}_m.forecast(f=na) gdp_f_m_{%date} 'copy forecasts !fm = @elem( gdp_f_m_{%date}, %date_f) !far = @elem( gdp_f_a_{%date}, %date_f) pageselect monthly %date_m = @datestr(@dateval(%date, "YYYYMMDD"), "YYYY/MM") smpl {%date_m} {%date_m} series gdp_f_m = !fm series gdp_f_a = !far 'copy over gdp to make the earliest gdp figure pageselect quarterly smpl if gdp_earliest = na gdp_earliest = gdp_{%date} smpl @all next copy(link, c=r) quarterly\gdp_latest monthly\gdp_latest copy(link, c=r) quarterly\gdp_earliest monthly\gdp_earliest pageselect monthly smpl 2017 @last 'show gdp_earliest.fcasteval(mean) gdp_f_a gdp_f_m if !uselatestgdp = 0 then %gdpvar = "gdp_earliest" endif show {%gdpvar}.fcasteval(mean) gdp_f_a gdp_f_m group g gdp_f_a gdp_f_m {%gdpvar} freeze(forc_graph) g.line forc_graph.setelem(1) legend(AR(1) Nowcast) forc_graph.setelem(2) legend(FA-MIDAS Nowcast) forc_graph.setelem(3) legend(GDP At Release) show forc_graph pageselect quarterly copy monthly\gdp_f_a quarterly\* copy monthly\gdp_f_m quarterly\* group g gdp_f_a gdp_f_m {%gdpvar} smpl 2015 @last freeze(forc_graph) g.line forc_graph.setelem(1) legend(AR(1) Nowcast) forc_graph.setelem(2) legend(FA-MIDAS Nowcast) forc_graph.setelem(3) legend(GDP At Release) show forc_graph pageselect quarterly show gdp_earliest.fcasteval(mean, trim=5, evalsmpl="2019 2023") gdp_f_m gdp_f_a 'subroutine that: ' creates a monthly page (called mYYYYMM) ' brings in the FRED-MD data for input date ' Performs transformations on each series that was imported ' Creates a group containing all the series that have full observations for the last two years until the specified date ' Estimates a Factor object and outputs the factor series as F1, F2, .... 'input %date must be formatted as YYYY-MM subroutine createpage(string %date) 'get the data (monthly only) %pagename = "m" + @replace(%date, "-","") pageload(page={%pagename}) https://files.stlouisfed.org/files/htdocs/fred-md/monthly/{%date}.csv colhead=3 namepos=firstatt pagecontract if sasdate<>na pagestruct @date(sasdate) 'perform transformations %serlist = @wlookup("*", "series") for %j {%serlist} %tform = {%j}.@attr("Transform:") if @len(%tform) then if %tform="1" then series temp = {%j} 'no transform endif if %tform="2" then series temp = d({%j}) 'first difference endif if %tform="3" then series temp = d({%j},2) 'second difference endif if %tform="4" then series temp = log({%j}) 'log endif if %tform= "5" then series temp = dlog({%j}) 'log difference endif if %tform= "6" then series temp = dlog({%j},2) 'log second difference endif if %tform= "7" then series temp = d({%j}/{%j}(-1) -1) 'other endif {%j} = temp {%j}.clearhistory d temp endif next %serlist = @wlookup("*", "series") 'get list of series smpl @last-23 @last 'set sample to last two years of observations group g 'declare a group for %j {%serlist} 'loop through series if @obs({%j})=24 then 'if series has values for every observation in last two years g.add {%j} 'add it to group endif next smpl @all 'reset sample to everything 'estimate a factor Factor FA.ml(n=ah, mfmethod=ah) g 'output the factor series to the workfile (with default names of F1, F2, ..... fa.makescores(n=factors) 'expand the page to full range (this helps with MIDAS, since leads will exist). pagestruct(freq=m, start=1991, end=@now) endsub