The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
This article replicates the out-of-sample Diebold-Mariano
panel of Table 1 in Rossi (2006), “Are exchange rates
really random walks? Some evidence robust to parameter instability”
(Macroeconomic Dynamics, 10(1), 20-38), using
dm_test() from forecastdom and the bundled
rossi2006 dataset.
The exercise is the classical Meese-Rogoff (1983) question: at the monthly horizon, can a small linear AR model of exchange-rate returns beat a driftless random walk out of sample?
Five bilateral nominal exchange rates against the U.S. dollar (Canada, France, Germany, Italy, Japan), monthly from March 1973 to December 1998, 310 observations per country.
ggplot(rossi2006, aes(date, log(fx))) +
geom_line(colour = "#47A5C5") +
facet_wrap(~ country, scales = "free_y") +
labs(x = NULL, y = "log(FX)",
title = "Log nominal exchange rates vs. USD") +
theme_minimal()Let \(e_t\) denote the log exchange rate and \(\Delta e_t = e_t - e_{t-1}\) its monthly return. We compare two one-step-ahead forecasts of \(\Delta e_{t+1}\):
Following Rossi, AR(1) and AR(2) share the same usable sample of \(n_{obs} = 307\) returns. The first \(R = \lceil n_{obs}/2 \rceil = 154\) observations fit the initial model, and the remaining \(P = 153\) are evaluated out of sample. Three estimation schemes are considered:
forecast_oos <- function(log_fx, p, scheme = c("split", "recursive", "rolling")) {
scheme <- match.arg(scheme)
T_full <- length(log_fx)
dy <- diff(log_fx)
Y <- dy[3:(T_full - 1)]
L1 <- dy[2:(T_full - 2)]
L2 <- dy[1:(T_full - 3)]
Xm <- if (p == 1) matrix(L1, ncol = 1) else cbind(L1, L2)
n_obs <- length(Y)
R <- as.integer(ceiling(n_obs / 2))
P_oos <- n_obs - R
e_alt <- numeric(P_oos)
e_bench <- numeric(P_oos)
for (j in seq_len(P_oos)) {
idx <- switch(scheme,
split = seq_len(R),
recursive = seq_len(R + j - 1),
rolling = j:(R + j - 1)
)
Z <- cbind(1, Xm[idx, , drop = FALSE])
b <- as.numeric(solve(crossprod(Z), crossprod(Z, Y[idx])))
pred <- as.numeric(c(1, Xm[R + j, ]) %*% b)
e_alt[j] <- Y[R + j] - pred
e_bench[j] <- Y[R + j]
}
list(e_bench = e_bench, e_alt = e_alt, P = P_oos)
}We call dm_test() with correction = FALSE
to match Rossi’s asymptotic \(\chi^2(1)\) reference distribution. Rossi
defines the loss differential as \(f_t =
u^{AR}_t - u^{RW}_t\), so a positive DM statistic means
the random walk has the lower MSFE. To reproduce her sign convention we
pass the AR errors as e1 and the random-walk errors as
e2.
countries <- levels(rossi2006$country)
schemes <- c("split", "recursive", "rolling")
run_panel <- function(p) {
out <- expand.grid(country = countries, scheme = schemes,
stringsAsFactors = FALSE)
out$DM <- NA_real_
out$DM_p <- NA_real_
for (i in seq_len(nrow(out))) {
log_fx <- log(subset(rossi2006, country == out$country[i])$fx)
fc <- forecast_oos(log_fx, p = p, scheme = out$scheme[i])
res <- dm_test(fc$e_alt, fc$e_bench,
alternative = "two.sided", correction = FALSE)
out$DM[i] <- res$statistic
out$DM_p[i] <- res$pvalue
}
out$cell <- sprintf("%.2f (%.2f)", out$DM, out$DM_p)
wide <- reshape(out[, c("country", "scheme", "cell")],
idvar = "scheme", timevar = "country", direction = "wide")
names(wide) <- gsub("^cell\\.", "", names(wide))
wide
}knitr::kable(run_panel(1), row.names = FALSE,
caption = "$DM_T$ statistic ($p$-value), AR(1) vs. RW")| scheme | Canada | France | Germany | Italy | Japan |
|---|---|---|---|---|---|
| split | 0.87 (0.38) | 1.38 (0.17) | -0.89 (0.38) | 0.80 (0.42) | -0.53 (0.60) |
| recursive | 1.16 (0.25) | 2.24 (0.03) | 0.14 (0.89) | 0.77 (0.44) | 0.00 (1.00) |
| rolling | 2.15 (0.03) | 1.77 (0.08) | 0.93 (0.35) | 0.60 (0.55) | 0.39 (0.69) |
knitr::kable(run_panel(2), row.names = FALSE,
caption = "$DM_T$ statistic ($p$-value), AR(2) vs. RW")| scheme | Canada | France | Germany | Italy | Japan |
|---|---|---|---|---|---|
| split | 1.97 (0.05) | 1.91 (0.06) | -0.03 (0.98) | 0.72 (0.47) | -0.64 (0.52) |
| recursive | 1.94 (0.05) | 1.71 (0.09) | 0.37 (0.71) | 0.73 (0.47) | 0.04 (0.97) |
| rolling | 2.29 (0.02) | 1.74 (0.08) | 0.79 (0.43) | 0.75 (0.45) | 0.41 (0.68) |
These cells reproduce the OOS DM panel of Rossi (2006) Table 1 exactly. The statistics are typically positive (the random walk has the lower MSFE), and the two-sided \(p\)-values rarely fall below 5%. This is the classical Meese-Rogoff finding.
log_fx_jp <- log(subset(rossi2006, country == "Japan")$fx)
fc_jp <- forecast_oos(log_fx_jp, p = 1, scheme = "recursive")
dm_test(fc_jp$e_alt, fc_jp$e_bench, alternative = "two.sided", correction = FALSE)
#>
#> ╭────────────────────────────────────────────────────╮
#> │ Diebold-Mariano Test (1995) │
#> ├────────────────────────────────────────────────────┤
#> │ H0: Equal predictive ability │
#> │ H1: Methods have different predictive ability │
#> ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
#> │ Test Results: │
#> │ DM statistic: 0.0001 │
#> │ P-value: 0.9999 │
#> ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
#> │ Details: │
#> │ Observations (n): 153 │
#> │ Forecast horizon (h): 1 │
#> │ Loss function: SE │
#> │ Reference distribution: N(0,1) │
#> ╰────────────────────────────────────────────────────╯The cumulative squared-error differential, using Rossi’s sign convention so that positive values mean the random walk is winning, shows that the AR’s edge is concentrated in narrow sub-samples rather than spread uniformly across the OOS period.
loss_diff <- fc_jp$e_alt^2 - fc_jp$e_bench^2
oos_dates <- tail(unique(rossi2006$date), fc_jp$P)
ggplot(data.frame(date = oos_dates, cum = cumsum(loss_diff)),
aes(date, cum)) +
geom_hline(yintercept = 0, linetype = "dashed") +
geom_line(colour = "#47A5C5", linewidth = 0.8) +
labs(x = NULL,
y = "Cumulative SE loss (AR(1) - RW)",
title = "Cumulative squared-error loss differential, Japan",
subtitle = "Above zero = RW doing better; below = AR(1) doing better") +
theme_minimal()These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.