function forecast = dyn_forecast(var_list,M_,options_,oo_,task,dataset_info) % function forecast = dyn_forecast(var_list,M_,options_,oo_,task,dataset_info) % computes mean forecast for a given value of the parameters % computes also confidence bands for the forecast % % INPUTS % var_list: list of variables (character matrix) % M_: Dynare model structure % options_: Dynare options structure % oo_: Dynare results structure % task: indicates how to initialize the forecast % either 'simul' or 'smoother' % dataset_info: Various informations about the dataset (descriptive statistics and missing observations). % % OUTPUTS % forecast: structure containing fields % Mean: point estimate % HPDinf: lower bound of confidence band, ignoring % measurement error % HPDsup: upper bound of confidence band, ignoring % measurement error % HPDinf_ME: lower bound of confidence band, accounting % for measurement error % HPDsup_ME: upper bound of confidence band, accounting % for measurement error % Exogenous: path for var_exo_det % SPECIAL REQUIREMENTS % none % Copyright © 2003-2023 Dynare Team % % This file is part of Dynare. % % Dynare is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Dynare is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . if ~isfield(oo_,'dr') || isempty(oo_.dr) error('dyn_forecast: the decision rules have not been computed. Did you forget a stoch_simul-command?') end if nargin<6 && options_.prefilter error('The prefiltering option is not allowed without providing a dataset') elseif nargin==6 mean_varobs=dataset_info.descriptive.mean'; end oo_=make_ex_(M_,options_,oo_); maximum_lag = M_.maximum_lag; endo_names = M_.endo_names; if isempty(var_list) var_list = endo_names(1:M_.orig_endo_nbr); end i_var = []; for i = 1:length(var_list) tmp = strmatch(var_list{i}, endo_names, 'exact'); if isempty(tmp) error([var_list{i} ' isn''t an endogenous variable']) end i_var = [i_var; tmp]; end n_var = length(i_var); trend = 0; switch task case 'simul' horizon = options_.periods; if horizon == 0 horizon = 5; end if isempty(M_.endo_histval) if options_.loglinear && ~options_.logged_steady_state y0 = repmat(log(oo_.dr.ys),1,maximum_lag); else y0 = repmat(oo_.dr.ys,1,maximum_lag); end else if options_.loglinear y0 = log_variable(1:M_.endo_nbr,M_.endo_histval,M_); else y0 = M_.endo_histval; end end case 'smoother' horizon = options_.forecast; if isnan(options_.first_obs) first_obs=1; else first_obs=options_.first_obs; end if isfield(oo_.SmoothedVariables,'Mean') y_smoothed = oo_.SmoothedVariables.Mean; else y_smoothed = oo_.SmoothedVariables; end y0 = zeros(M_.endo_nbr,maximum_lag); for i = 1:M_.endo_nbr v_name = M_.endo_names{i}; y0(i,:) = y_smoothed.(v_name)(end-maximum_lag+1:end); %includes steady state or mean, but simult_ will subtract only steady state % 2. Subtract mean/steady state and add steady state; takes care of prefiltering if isfield(oo_.Smoother,'Constant') && isfield(oo_.Smoother.Constant,v_name) y0(i,:)=y0(i,:)-oo_.Smoother.Constant.(v_name)(end-maximum_lag+1:end); %subtract mean or steady state if options_.loglinear y0(i,:)=y0(i,:)+log_variable(i,oo_.dr.ys,M_); else y0(i,:)=y0(i,:)+oo_.dr.ys(strmatch(v_name, M_.endo_names, 'exact')); end end % 2. Subtract trend if isfield(oo_.Smoother,'Trend') && isfield(oo_.Smoother.Trend,v_name) y0(i,:)=y0(i,:)-oo_.Smoother.Trend.(v_name)(end-maximum_lag+1:end); %subtract trend, which is not subtracted by simult_ end end gend = options_.nobs; if isfield(oo_.Smoother,'TrendCoeffs') var_obs = options_.varobs; endo_names = M_.endo_names; i_var_obs = []; trend_coeffs = []; for i=1:length(var_obs) tmp = strmatch(var_obs{i}, endo_names(i_var), 'exact'); trend_var_index = strmatch(var_obs{i}, M_.endo_names, 'exact'); if ~isempty(tmp) i_var_obs = [ i_var_obs; tmp]; trend_coeffs = [trend_coeffs; oo_.Smoother.TrendCoeffs(trend_var_index)]; end end if ~isempty(trend_coeffs) trend = trend_coeffs*(first_obs+gend-1+(1-M_.maximum_lag:horizon)); if options_.prefilter trend = trend - repmat(mean(trend_coeffs*[first_obs:first_obs+gend-1],2),1,horizon+1); %subtract mean trend end end else trend_coeffs=zeros(length(options_.varobs),1); end otherwise error('Wrong flag value') end if M_.exo_det_nbr == 0 if isequal(M_.H,0) [yf,int_width] = forcst(oo_.dr,y0,horizon,var_list,M_,oo_,options_); else [yf,int_width,int_width_ME] = forcst(oo_.dr,y0,horizon,var_list,M_,oo_,options_); end else exo_det_length = size(oo_.exo_det_simul,1)-M_.maximum_lag; if horizon > exo_det_length ex = zeros(horizon,M_.exo_nbr); oo_.exo_det_simul = [ oo_.exo_det_simul;... repmat(oo_.exo_det_steady_state',... horizon- ... exo_det_length,1)]; elseif horizon <= exo_det_length ex = zeros(exo_det_length,M_.exo_nbr); end if options_.linear iorder = 1; else iorder = options_.order; end if isequal(M_.H,0) [yf,int_width] = simultxdet(y0,ex,oo_.exo_det_simul,... iorder,var_list,M_,oo_,options_); else [yf,int_width,int_width_ME] = simultxdet(y0,ex,oo_.exo_det_simul,... iorder,var_list,M_,oo_,options_); end end if ~isscalar(trend) %add trend back to forecast yf(i_var_obs,:) = yf(i_var_obs,:) + trend; end if options_.loglinear if options_.prefilter == 1 %subtract steady state and add mean for observables yf(i_var_obs,:)=yf(i_var_obs,:)-repmat(log(oo_.dr.ys(i_var_obs)),1,horizon+M_.maximum_lag)+ repmat(mean_varobs,1,horizon+M_.maximum_lag); end else if options_.prefilter == 1 %subtract steady state and add mean for observables yf(i_var_obs,:)=yf(i_var_obs,:)-repmat(oo_.dr.ys(i_var_obs),1,horizon+M_.maximum_lag)+ repmat(mean_varobs,1,horizon+M_.maximum_lag); end end for i=1:n_var vname = var_list{i}; forecast.Mean.(vname) = yf(i,maximum_lag+(1:horizon))'; forecast.HPDinf.(vname)= yf(i,maximum_lag+(1:horizon))' - int_width(1:horizon,i); forecast.HPDsup.(vname) = yf(i,maximum_lag+(1:horizon))' + int_width(1:horizon,i); if ~isequal(M_.H,0) && ismember(var_list{i},options_.varobs) forecast.HPDinf_ME.(vname)= yf(i,maximum_lag+(1:horizon))' - int_width_ME(1:horizon,i); forecast.HPDsup_ME.(vname) = yf(i,maximum_lag+(1:horizon))' + int_width_ME(1:horizon,i); end end for i=1:M_.exo_det_nbr forecast.Exogenous.(M_.exo_det_names{i}) = oo_.exo_det_simul(maximum_lag+(1:horizon),i); end if ~options_.nograph oo_.forecast = forecast; forecast_graphs(var_list, M_, oo_, options_) end