--- title: "Residual Adjustments" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{residual_adjustments} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` Residual adjustments (add-factors) add a value to the residual of selected stochastic equations in the forecast period, e.g. to include information the model does not capture. The model then computes the forecast of all variables with the adjusted equations. # Model and Data We use the small macro model for Switzerland from the [small macro model vignette](koma-small-macro-model.html), estimated up to 2023 Q4 and forecast for 2024. ```{r} library(koma) equations <- "consumption ~ gdp + consumption.L(1), investment ~ investment.L(1), exports ~ world_gdp + exports.L(1), imports ~ domestic_demand + imports.L(1), prices ~ exchange_rate + oil_price + prices.L(1), interest_rate ~ prices + interest_rate_germany + prices.L(1), gdp == 0.9*domestic_demand + 0.5*exports - 0.4*imports, domestic_demand == 0.6*consumption + 0.4*investment" exogenous_variables <- c("world_gdp", "interest_rate_germany", "exchange_rate", "oil_price") sys_eq <- system_of_equations(equations, exogenous_variables) dates <- list( estimation = list(start = c(1996, 1), end = c(2023, 4)), forecast = list(start = c(2024, 1), end = c(2024, 4)) ) series <- names(small_open_economy) series <- series[!series %in% c("interest_rate", "interest_rate_germany")] ts_data <- lapply(series, function(x) { as_ets(small_open_economy[[x]], series_type = "level", method = "diff_log") }) names(ts_data) <- series ts_data$interest_rate <- as_ets(small_open_economy$interest_rate, series_type = "rate", method = "none" ) ts_data$interest_rate_germany <- as_ets(small_open_economy$interest_rate_germany, series_type = "rate", method = "none" ) # endogenous data up to the quarter before the forecast ts_data[sys_eq$endogenous_variables] <- lapply( sys_eq$endogenous_variables, function(x) stats::window(ts_data[[x]], end = c(2023, 4)) ) ``` ```{r, results = "hide", message = FALSE} set.seed(1) estimates <- estimate(sys_eq, ts_data = ts_data, dates = dates) ``` # Residuals Before adjusting, look at the recent residuals of the equations. They show where the model was off. Like the data, they are in rates. ```{r} res <- residuals(estimates) utils::tail(res$imports, 4) ``` # Adjusting an Equation Adjustments are given by equation, in the same forms as restrictions for conditional forecasts: by forecast horizon, by date or as a time series. Here exports are raised by 0.5 in the first quarter and 0.3 in the second. ```{r, results = "hide", message = FALSE} adjustments <- list( exports = ts(c(0.5, 0.3), start = c(2024, 1), frequency = 4) ) adjusted <- forecast(estimates, dates = dates, adjustments = adjustments) ``` The result keeps the forecast without adjustments in `unadjusted`, computed with the same shocks. The difference between the two is the effect of the adjustments. ```{r} compare <- function(forecasts, variable) { stats::ts( cbind( unadjusted = as.numeric(forecasts$unadjusted$mean[[variable]]), adjusted = as.numeric(forecasts$mean[[variable]]) ), start = c(2024, 1), frequency = 4 ) } compare(adjusted, "exports") compare(adjusted, "gdp") ``` The applied adjustments are stored by variable and forecast quarter: ```{r} adjusted$adjustments ``` # Decaying Adjustments An adjustment can also start at a value and decay by a factor per quarter until the end of the forecast. `decay = 0` adjusts one quarter only, `decay = 1` all quarters by the same value. The adjustment starts in the first forecast quarter, or at the quarter given by `horizon` or `date`. ```{r, results = "hide", message = FALSE} adjustments <- list( investment = list(value = 0.8, decay = 0.5, date = c(2024, 2)) ) adjusted <- forecast(estimates, dates = dates, adjustments = adjustments) ``` ```{r} adjusted$adjustments$investment ``` # Starting at the Last Residual To carry the recent error of an equation into the forecast, start the adjustment at its last residual with `init = "last"`. It takes the residual of the quarter before the forecast and lets it decay. ```{r, results = "hide", message = FALSE} adjustments <- list(imports = list(init = "last", decay = 0.6)) adjusted <- forecast(estimates, dates = dates, adjustments = adjustments) ``` ```{r} adjusted$adjustments$imports compare(adjusted, "imports") ``` The adjustment starts at the last residual of imports shown above. All variables of the equation must be observed in the quarter before the forecast. If one of them is filled because its series ends earlier, `forecast()` fails; set the start value with `value` instead, e.g. from `residuals()`. # Notes - Adjustments are in rates, like the data the model is estimated on. - Only stochastic equations can be adjusted, identities cannot. - Adjustments cannot be combined with restrictions for conditional forecasts. - `adjusted$adjustments_spec` keeps the adjustments as given to `forecast()`.