Time Series Econometrics

```{r} #| label: setup #| include: false set.seed(2026) library(ggplot2) theme_set(theme_minimal(base_size = 18)) ``` ## 🎬 The Idea in 3 Minutes ::: {style="text-align:center"} ```{=html} ``` [⬅ Previous lecture: 1 · Stationarity, Ergodicity and White Noise](../01-stationarity-ergodicity/stationarity_ergodicity_lecture1.html){style="font-size:28px"} [A short film with the intuition. Watch it before the slides, or after. Captions: CC button.]{style="font-size:28px"} ::: --- ## 🎯 Learning Objectives ::: {style="font-size: 32px"} By the end of this lecture, you will be able to: - **State** the ergodic theorem, and show how it fails without ergodicity or stationarity - **Apply** the CLT for stationary ergodic martingale difference sequences - **Derive** the long-run variance $V_x = \sum_j \Gamma_j$ from the variance of a sum, and compute it for AR(1) and MA(1) - **Explain** why the naive estimator $\sum_{|j| { if (u === 0) return 1; const a = 6 * Math.PI * u / 5; return 25 / (12 * Math.PI * Math.PI * u * u) * (Math.sin(a) / a - Math.cos(a)); }; const K = { "Uniform": u => Math.abs(u) <= 1 ? 1 : 0, "Bartlett": u => Math.abs(u) <= 1 ? 1 - Math.abs(u) : 0, "Parzen": u => { const a = Math.abs(u); return a <= 0.5 ? 1 - 6 * a * a + 6 * a ** 3 : (a <= 1 ? 2 * (1 - a) ** 3 : 0); }, "Quadratic spectral": qs }; const out = []; for (const name of Object.keys(K)) for (let j = 0; j <= 40; j++) out.push({lag: j, w: K[name](j / delta), kernel: name}); return out; } ``` ```{ojs} //| echo: false Plot.plot({ width: 1100, height: 300, marginLeft: 78, marginBottom: 50, style: {fontSize: "18px"}, x: {label: "lag j", domain: [0, 40]}, y: {label: "weight w(j)", domain: [-0.15, 1.05], grid: true}, color: {domain: ["Uniform", "Bartlett", "Parzen", "Quadratic spectral"], range: ["#9a9a9a", "#2f4b7c", "#e09f3e", "#8b2635"]}, marks: [ Plot.ruleY([0]), Plot.line(kern, {x: "lag", y: "w", stroke: "kernel", strokeWidth: 3, curve: "step-after", filter: d => d.kernel === "Uniform"}), Plot.line(kern, {x: "lag", y: "w", stroke: "kernel", strokeWidth: 3, filter: d => d.kernel !== "Uniform"}) ] }) ``` ::: {style="font-size: 28px"} Grey: uniform, blue: Bartlett, amber: Parzen, red: QS. Larger $\delta$ stretches every kernel over more lags; only QS dips below zero and never quite stops. ::: --- ## 🪶 Why Smoothness Matters ::: {style="font-size: 28px"} - **Bartlett** falls linearly from $u = 0$: even $\hat\Gamma_1$ is down-weighted by $1/\delta$. Its weights converge to 1 **slowly** as $\delta$ grows, so its bias shrinks slowly. - **Parzen** and **QS** are flat at the top, $K(u) = 1 - O(u^2)$: low-order autocovariances, the precisely estimated ones, get weight close to 1. Their bias shrinks **faster**. ::: {.fragment} | Kernel | bias of order | MSE-optimal bandwidth | |---|---|---| | Bartlett | $\delta^{-1}$ | $\delta \propto T^{1/3}$ | | Parzen, QS | $\delta^{-2}$ | $\delta \propto T^{1/5}$ | QS minimises the asymptotic MSE among kernels that guarantee a PSD estimate (Andrews, 1991). For smoothness, Parzen is preferred to Bartlett. ::: ::: --- ## 💻 Newey–West Converges, Slowly ```{r} #| label: nw-consistency #| fig-width: 11 #| fig-height: 3.2 set.seed(2026) nw <- function(x, m) { u <- x - mean(x); n <- length(u) g <- sapply(0:m, function(j) sum(u[1:(n - j)] * u[(1 + j):n]) / n) g[1] + 2 * sum((1 - (1:m) / (m + 1)) * g[-1]) } rho <- 0.5; V_true <- 1 / (1 - rho)^2 # = 4, while Gamma0 = 1.33 sims <- do.call(rbind, lapply(c(200, 1000, 5000), function(n) { rules <- c(`4(T/100)^(2/9)` = floor(4 * (n / 100)^(2 / 9)), `T^(1/3)` = floor(n^(1 / 3))) do.call(rbind, lapply(names(rules), function(r) data.frame(T = factor(n), rule = r, V = replicate(300, nw(as.numeric(filter(rnorm(n), rho, "recursive")), rules[[r]]))))) })) ggplot(sims, aes(T, V, fill = rule)) + geom_boxplot(outlier.size = 0.6) + geom_hline(yintercept = V_true, colour = "#8b2635", linewidth = 1.1) + scale_fill_manual(values = c("#8ba3c7", "#e09f3e"), name = "lag rule") + labs(x = "sample size T", y = expression(hat(V)^NW)) + theme(legend.position = "top") ``` ::: {style="font-size: 28px"} AR(1), $\rho = 0.5$, true $V_x = 4$ (red). The boxes tighten and climb toward 4, but at $T = 5000$ both rules are still biased down: the price of the triangle. ::: --- ## 🧠 Think–Pair–Share ```{r} #| label: tps-timer #| echo: false countdown::countdown(minutes = 3, top = 0, right = 0, font_size = "2em", warn_when = 30) ``` ::: {style="font-size: 28px"} A daily trading strategy's P&L follows $x_t = \varepsilon_t - 0.5\,\varepsilon_{t-1}$, with $\varepsilon_t$ i.i.d., $\operatorname{Var}\varepsilon_t = 1$ (a bid–ask bounce). 1. Compute $\Gamma_0$, $\Gamma_1$ and the long-run variance $V_x$. 2. Is the i.i.d. standard error of $\bar x_T$ too large or too small, and by what factor? 3. In population, what does Newey–West with $m = 1$ give? And the uniform kernel with $\delta = 1$? ::: --- ## ✅ Think–Pair–Share: Solution ::: {style="font-size: 28px"} 1. $\Gamma_0 = 1.25$, $\ \Gamma_1 = \theta\sigma^2 = -0.5$, $\ \Gamma_j = 0$ for $|j| \ge 2$. So $V_x = 1.25 - 1 = 0.25 = (1+\theta)^2$. ::: {.fragment} 2. **Too large**, by $\sqrt{\Gamma_0/V_x} = \sqrt5 \approx 2.24$. Negative autocorrelation makes the average **more** precise. ::: ::: {.fragment} 3. Newey–West, $m = 1$: $\ \Gamma_0 + 2\cdot\tfrac12\Gamma_1 = 0.75$, three times too large, though the memory ends at lag 1: the triangle halves $\Gamma_1$. The uniform kernel with $\delta = 1$ gives $\Gamma_0 + 2\Gamma_1 = 0.25$ exactly, but in a sample $\hat\Gamma_0 + 2\hat\Gamma_1$ can be negative. ::: ::: --- ## 💰 Case Study: Average Inflation :::: columns ::: {.column width="50%"} ::: {.callout-note} ## 📈 The question What is the standard error of average US inflation since 1985? 1. How far apart are the i.i.d. variance $\hat\Gamma_0$ and the long-run variance $\hat V$? 2. Does $\hat V^{NW}$ settle as the truncation lag $m$ grows? 3. Do Parzen and QS kernels tell the same story? ::: ::: ::: {.column width="50%"} ::: {.callout-tip} ## 📊 The data **Series**: CPI for all urban consumers, seasonally adjusted (FRED `CPIAUCSL`) **Period**: Jan 1985 – Sep 2026, $T = 501$ months **Transformation**: $\pi_t = 1200\,(\log P_t - \log P_{t-1})$, annualised % ::: ```{.r .display-only} # How the file was obtained (not run) download.file(paste0( "https://fred.stlouisfed.org/graph/", "fredgraph.csv?id=CPIAUCSL"), "data/CPIAUCSL.csv") ``` ::: :::: --- ## 💰 Case Study: Long-Run Variances in R ```{r} #| label: case-cpi #| code-summary: "📦 Inflation, its autocovariances, and four estimates of V" cpi <- read.csv("data/CPIAUCSL.csv") lp <- log(cpi$CPIAUCSL) gap <- which(is.na(lp)); lp[gap] <- (lp[gap - 1] + lp[gap + 1]) / 2 # Oct 2025 not published: interpolate infl <- 1200 * diff(lp); n <- length(infl); u <- infl - mean(infl) G <- sapply(0:(n - 1), function(j) sum(u[1:(n - j)] * u[(1 + j):n]) / n) # Gamma-hat_0 ... _{T-1} K <- list(bartlett = function(x) pmax(1 - abs(x), 0), parzen = function(x) { a <- abs(x); ifelse(a <= .5, 1 - 6*a^2 + 6*a^3, ifelse(a <= 1, 2*(1 - a)^3, 0)) }, qs = function(x) { a <- 6*pi*x/5; ifelse(x == 0, 1, 25/(12*pi^2*x^2) * (sin(a)/a - cos(a))) }) Vhat <- function(k, d) G[1] + 2 * sum(K[[k]]((1:(n - 1)) / d) * G[-1]) m_rule <- floor(4 * (n / 100)^(2 / 9)) V <- c(Gamma0 = G[1], naive = G[1] + 2 * sum(G[-1]), NW_rule = Vhat("bartlett", m_rule + 1), NW_m12 = Vhat("bartlett", 13), NW_m36 = Vhat("bartlett", 37), Parzen_d12 = Vhat("parzen", 12), QS_d12 = Vhat("qs", 12)) round(rbind(V = V, se_of_mean = sqrt(pmax(V, 0) / n)), 3) ``` ::: {style="font-size: 28px"} Mean inflation is `r round(mean(infl), 2)`% and the rule-of-thumb lag is $m =$ `r m_rule`. Compare the standard errors along the bottom row. ::: --- ## 💰 Case Study: Estimates vs Bandwidth ```{r} #| label: case-cpi-fig #| echo: false #| fig-width: 10 #| fig-height: 3.9 grid <- 1:60 df <- rbind(data.frame(d = grid, V = sapply(grid + 1, function(d) Vhat("bartlett", d)), kernel = "Bartlett (Newey–West, m = δ − 1)"), data.frame(d = grid, V = sapply(grid, function(d) Vhat("parzen", d)), kernel = "Parzen"), data.frame(d = grid, V = sapply(grid, function(d) Vhat("qs", d)), kernel = "Quadratic spectral")) ggplot(df, aes(d, V, colour = kernel)) + geom_line(linewidth = 1.3) + geom_hline(yintercept = G[1], linetype = "dashed", colour = "grey40") + annotate("text", x = 60, y = G[1] + 2.5, label = "i.i.d. variance", hjust = 1, size = 6, colour = "grey30") + geom_vline(xintercept = m_rule, linetype = "dotted", colour = "#2f4b7c") + scale_colour_manual(values = c("#2f4b7c", "#e09f3e", "#8b2635"), name = NULL) + labs(x = "truncation lag m (Bartlett) or bandwidth δ", y = "estimated V") + theme_minimal(base_size = 20) + theme(legend.position = "top") ``` ::: {style="font-size: 28px"} **What the data say:** every HAC estimate lies far above $\hat\Gamma_0 \approx 10$, so the i.i.d. standard error ($0.14$) understates the uncertainty; at the rule-of-thumb lag ($m = 5$, dotted) it is about $0.20$. But no curve settles: $\hat V$ keeps rising with $m$, because inflation's autocorrelations stay small and positive for years. For a series this persistent the fixed rule is not enough, exactly the warning of the theory. ::: --- ## 📝 Quiz #1: The Long-Run Variance {.quiz-question} $x_t = 0.75\,x_{t-1} + \varepsilon_t$, $\operatorname{Var}\varepsilon_t = 1$. What is the long-run variance $V_x$? - $1/(1 - 0.75^2) \approx 2.29$ - $1$ - [$1/(1 - 0.75)^2 = 16$]{.correct data-explanation="✅ For AR(1), V = σ²/(1−ρ)² = 1/0.0625 = 16. The ordinary variance Γ0 = 1/(1−ρ²) ≈ 2.29 is seven times smaller: (1+ρ)/(1−ρ) = 7."} - $(1 + 0.75)^2 = 3.06$ --- ## 📝 Quiz #2: The Naive Estimator {.quiz-question} Why is $\hat V^{N} = \sum_{j=-(T-1)}^{T-1}\hat\Gamma_j$ useless? - It is consistent but not positive semi-definite - It needs the true mean $E x_t$, which is unknown - [With the sample mean subtracted, it equals zero in every sample]{.correct data-explanation="✅ The sum of all Γ̂_j is (1/T)(Σ u_t)(Σ u_t)' with u_t = x_t − x̄, and Σ u_t = 0. More generally, the high-order Γ̂_j rest on a handful of pairs and are pure noise."} - It ignores $\hat\Gamma_0$ --- ## 📝 Quiz #3: Bandwidth Rates {.quiz-question} For the Newey–West estimator to be consistent, the truncation lag $m$ must satisfy … - $m$ fixed, e.g. $m = 5$, whatever $T$ - $m = T - 1$, to use every autocovariance - [$m \to \infty$ and $m/T \to 0$ as $T \to \infty$]{.correct data-explanation="✅ m must grow, so that the bias from ignoring distant autocovariances vanishes, but slower than T, so that the noise from estimating many Γ̂_j also vanishes."} - $m/T \to 1/2$ --- ## 📋 Key Formulas ::: {style="font-size: 28px"} | | | |---|---| | Ergodic theorem | $\bar x_T \xrightarrow{p} E x_t$ for S&E $x_t$, $E\lvert x_t\rvert < \infty$ | | CLT, S&E MDS | $T^{-1/2}\sum x_t \xrightarrow{d} N(0, \operatorname{Var}x_t)$ | | CLT, S&E | $T^{-1/2}\sum (x_t - Ex_t) \xrightarrow{d} N(0, V_x)$, $\ V_x = \sum_{j}\Gamma_j$ | | Finite-$T$ variance | $\operatorname{var}(T^{-1/2}\sum x_t) = \sum_{\lvert j\rvert