% Use this script to compute the baseline and IRFs of the backward model.

computebaseline = true;

% Load database (generated by the ecb-mc package).
db = dseries('../database/data-for-ecb-base.mat');

% Write the backward version of the model
dynare('hybrid', '-DBACKWARD=true', 'savemacro=backward.mod', 'onlymacro', 'notime');

% Preprocess backward model
dynare('backward', 'stochastic', 'fast', 'nopreprocessoroutput', 'notime');

if computebaseline
% Set options
options.solve_algo = 14;
options.maxiter = 500;
options.tolx = 1e-8;
options.tolf = 1e-8;
options.simulations_along_bgp = 4;

% Cleanup database (remove unnecessary variables from database).
listofvariables = getlistofvariables();
db = db{listofvariables{:}};

% Prepare exogenous variables projection.
info = data.projectionsetup({'U2'}, db, sprintf('%s/backward.mod', pwd()));

% Compute residuals.
listofvariables = getlistofvariables(M_);

db.U2_STN_ZLB = db.U2_STN;
db.U2_TP_10YEXO = dseries(zeros(db.nobs,1), db.dates(1));
db.U2_TP_10YENDO = db.U2_TP_10Y;

db = solvemodelforresiduals('backward.mod', db{listofvariables{:}}, true);

% Set the maximum number of periods.
periods = 12000;

% Compute baseline (we set the residuals to zero and extend the observed exogenous variables)
[baseline, info] = simulatelongrun('backward.mod', db, periods, info, false, true, options);

% Deflate baseline (otherwise we will not be able to use the baseline for perfect foresight simulations).
baseline = deflate(baseline, info, 10000);

baseline = baseline(baseline.dates(9000:10504+M_.orig_maximum_endo_lag+M_.maximum_endo_lead));

% Save baseline on disk.
baseline.save('../database/baseline', 'mat');

end

nperiods = 1500;

ds = dseries('../database/baseline.mat');
ds = backward.dynamic_set_auxiliary_series(ds, M_.params);

initp = ds.firstobservedperiod;
lastp = ds.lastobservedperiod;

listofshocks = {dseries([1; zeros(nperiods-1, 1)], initp+(M_.orig_maximum_lag+1), {'res_U2_STN'})};             % Policy shock (Interest rate)
listofshocks{end+1} = dseries([0.01; zeros(nperiods-1, 1)], initp+(M_.orig_maximum_lag+1), {'res_U2_Q_T_PRO'}); % Technology shock
listofshocks{end+1} = dseries([1; zeros(nperiods-1, 1)], initp+(M_.orig_maximum_lag+1), {'res_U2_TP_10Y'});     % Term Premium shock
listofshocks{end+1} = dseries([1; zeros(nperiods-1, 1)], initp+(M_.orig_maximum_lag+1), {'res_U2_SLRN'});       % Risk Premium shock
listofshocks{end+1} = dseries([.1; zeros(nperiods-1, 1)], initp+(M_.orig_maximum_lag+1), {'res_U2_A_YED'});     % Inflation (Phillips curve)
listofshocks{end+1} = dseries([.1; zeros(nperiods-1, 1)], initp+(M_.orig_maximum_lag+1), {'res_U2_G_C_CER'});   % Wage (Wage curve)


% Set options for nonlinear solver (use the fastest option).
options_.solve_algo = 14;
options_.maxiter = 500;
options_.tolx = 1e-8;
options_.tolf = 1e-8;

% Read JSON output to identify the equations with a logged variable on the LHS.
if ismember(options_.solve_algo, [12,14])
    json = loadjson_(sprintf('%s/model/json/modfile.json', M_.fname));
    lhs = cell(length(json.model),1);
    isauxdiffloggedrhs = false(length(json.model), 1);
    for i = 1:length(json.model)
        lhs{i} = json.model{i}.lhs;
        if i>M_.orig_endo_nbr &&  ~isempty(regexp(lhs{i}, '\<AUX_DIFF_(\d*)\>', 'once')) && ismember(lhs{i}, lhs(1:i-1)) && ...
                ~isempty(regexp(json.model{i}.rhs, 'log\(\w*\)-log\(\w*\(-1\)\)', 'once'))
            isauxdiffloggedrhs(i) = true;
        end
    end
    islog = @(x) ~isempty(regexp(x, 'log\(\w*\)', 'once'));
    M_.isloggedlhs = cellfun(islog, lhs);
    M_.lhs = lhs;
    M_.isauxdiffloggedrhs = isauxdiffloggedrhs;
end

% Compute IRFs
[deviations, baseline, irfs] = backward_model_irf(ds(initp:initp+M_.orig_maximum_lag), ds(initp+(M_.orig_maximum_lag+1):lastp), listofshocks, {}, nperiods);

% Save IRFs

if ~isfolder('./mat')
    mkdir('mat')
end

for i=1:length(listofshocks)
    irfs.(sprintf('experiment_%u', i)).save(sprintf('./mat/irfs_backward_model_%s', listofshocks{i}.name{1}), 'mat');
end


% Cleanup
rmdir('backward', 's');
rmdir('+backward', 's');
delete ./mat/*.old.mat
delete backward.mod backward.log backward_results.mat
