Forecasts, shocks and conditions¶
These options set where the forecast starts, how long it runs, which shocks hit the economy over it, and which variables are put on a path.
Origin and horizon¶
| Option | Values (default first) | Meaning |
|---|---|---|
forecast.origin |
a date (required) | Last quarter of data used; the forecast starts the quarter after |
forecast.horizon |
16 |
Number of forecast quarters, a positive integer |
id |
text | Results folder name results/<id>/; use the scenario function name |
title, description |
text | Shown in summaries and reports |
model |
text | Model package folder under models/, or a folder path |
model_params |
'' |
Parameter function of the package to use instead of spec.params. Project baseline: 'sw07_params_original' |
cfg = a1_learn(); cfg.id = 'a1_from_2023Q4';
cfg.forecast.origin = qq(2023, 4);
cfg.forecast.horizon = 12;
res = hetlearn.run(cfg, 'save', false);
An origin found from the data, as sw07_re does:
spec = hetlearn.load_spec('sw07');
db = hetlearn.load_database(spec);
origin = hetlearn.find_peak(db, 'pinfobs', qq(2020, 1), qq(2024, 4)); % 2022Q2
model_params switches the parameter set of the package for one run. Each parameter set has
its own RE filter cache:
cfg = a1_learn(); cfg.id = 'a1_swX1';
cfg.model_params = ''; % '' = spec.params (sw07_params, the swX1 re-estimate)
Shocks over the horizon¶
| Option | Values (default first) | Meaning |
|---|---|---|
shocks.source |
'none', 'smoothed' |
Zero shocks, or the RE-smoothed shocks |
shocks.range |
[] |
Quarters that get smoothed shocks; [] = the horizon |
shocks.exclude |
{} |
Shocks set to zero, e.g. {'em'} |
shocks.add |
{} |
Shocks added on top: {{name, dates, values}, ...}; values scalar or one per date |
All shocks are unanticipated: every quarter is a new one-quarter simulation with the beliefs and shares in force.
% A one-off monetary tightening of 0.25 (model units) in 2022Q3, on top of zero shocks
cfg = a1_learn(); cfg.id = 'a1_em_shock';
cfg.shocks.add = {{'em', qq(2022, 3), 0.25}};
% Two shocks, the second over four quarters
cfg = a1_learn(); cfg.id = 'a1_two_shocks';
cfg.shocks.add = {{'em', qq(2022, 3), 0.25}, {'epinf', qq(2022, 3):qq(2023, 2), [0.1 0.1 0.05 0.05]}};
% Replay the RE-smoothed shocks except the monetary ones (Application 2 without em)
cfg = a2_learn(); cfg.id = 'a2_learn_nom';
cfg.shocks.exclude = {'em'};
Conditions¶
A condition puts a variable on a path and lets a shock adjust each quarter to hit it.
cfg.conditions is a struct array, one element per variable-shock pair, and it replaces the
inherited value as a whole.
| Field | Values | Meaning |
|---|---|---|
variable |
name | Transition or measurement variable to put on a path, e.g. 'robs', 'ms' |
shock |
name | The shock that adjusts |
dates |
dates, or [start, end] |
Quarters of the condition, inside the horizon; two dates are read as a range |
values |
number or vector | Targets, scalar or one per date |
type |
'level' (default), 'delta' |
The target is the value itself, or the value added to a reference path |
reference |
'self' (default) or a scenario id |
For 'delta': the same scenario without conditions, or another scenario's path |
% Application 3: the monetary shock process 0.25 below its own path for four quarters
cfg = a1_learn(); cfg.id = 'a3_loose_learn_copy';
cfg.conditions = struct('variable', 'ms', 'shock', 'em', ...
'dates', [qq(2022, 3), qq(2023, 2)], 'values', -0.25, ...
'type', 'delta', 'reference', 'self');
% The observed policy rate on a path (% per quarter)
cfg = a1_learn(); cfg.id = 'a1_rate_path';
cfg.conditions = struct('variable', 'robs', 'shock', 'em', ...
'dates', qq(2022, 3):qq(2023, 2), 'values', [0.5 0.8 1.1 1.2], ...
'type', 'level', 'reference', 'self');
% Two conditions at once: rate path and inflation 0.1 above the RE path, with the price mark-up shock
c1 = struct('variable', 'robs', 'shock', 'em', 'dates', qq(2022, 3):qq(2023, 2), ...
'values', [0.5 0.8 1.1 1.2], 'type', 'level', 'reference', 'self');
c2 = struct('variable', 'pinfobs', 'shock', 'epinf', 'dates', [qq(2022, 3), qq(2022, 4)], ...
'values', 0.1, 'type', 'delta', 'reference', 'a1_re');
cfg = a1_learn(); cfg.id = 'a1_two_conditions';
cfg.conditions = [c1, c2];
Rules: a variable conditioned twice in the same quarter is an error. A 'delta' reference to a
scenario id that has no results runs that scenario first. With more adjusting shocks than
targets, the toolbox uses the smallest shocks in standard-deviation units
(engine.conditions_weighting = 'std').
Comparisons¶
| Option | Values | Meaning |
|---|---|---|
compare_with |
{}, cellstr of scenario ids |
Writes results/<id>/compare_<other>.csv: this run minus the other, observables over the horizon, model units |
A comparison target without results is run first. Outside a scenario,
hetlearn.compare(ids, vars, range) builds the same kind of table from saved results:
T = hetlearn.compare({'a1_re', 'a1_learn', 'v2_ar2'}, {'pinfobs', 'robs'}, qq(2022, 3):qq(2026, 2));
Engine¶
| Option | Values (default first) | Meaning |
|---|---|---|
engine.step |
'fast', 'iris' |
One-quarter step from the cached state-space solution (equal to IRIS simulate to about 1e-12, 2-3 times faster), or IRIS simulate itself |
engine.conditions_weighting |
'std', 'none' |
With more shocks than targets: minimum norm in standard-deviation units, or unweighted |
cfg = a1_learn(); cfg.id = 'a1_iris_step';
cfg.engine.step = 'iris'; % slower; bit-identical to IRIS simulate
Reserved¶
report.variables (default {}) is accepted and stored but no toolbox code reads it.