14 — Advanced Models

VAR Models#

AdvancedStatistical
◆ The PatternMultiple series forecasting each other

Vector Autoregression (VAR) generalises AR to multiple interrelated series. Each variable is modeled as a linear function of all variables’ lags. Granger causality tests whether one series helps predict another. Impulse response functions show how shocks propagate.

Yt = c + A1Yt−1 + A2Yt−2 + … + ApYt−p + εt
Y is a vector of all variables. Each A is a coefficient matrix capturing cross-series dependencies at that lag.
// Interactive — VAR impulse response
Pattern bridge: VAR captures how variables influence each other — the same idea as correlation matrices but with temporal structure. In markets, cross-asset correlations and intermarket analysis are VAR in practice.
Worked example

Two series where x drives y with a one-step lag (true effect 0.6). A VAR(1) fitted to 500 points recovers it: in y’s equation the coefficient on yesterday’s x is 0.60, while x’s equation puts only 0.03 on yesterday’s y. That asymmetry is what Granger causality tests — x helps predict y, not the reverse.

Where it misleads
  • Granger causality is about prediction, not cause: a third series driving both with different lags produces it too.
  • Parameters grow with the square of the number of series times the lags; VARs overfit fast without shrinkage.
  • Non-stationary series need differencing or a cointegrated VAR (VECM).
In code
rng = np.random.default_rng(8)
n = 500
x, y = np.zeros(n), np.zeros(n)
for t in range(1, n):
    x[t] = 0.5 * x[t - 1] + rng.normal()
    y[t] = 0.3 * y[t - 1] + 0.6 * x[t - 1] + rng.normal()   # x leads y by one step
Z = np.column_stack([x[:-1], y[:-1]])
A = np.linalg.lstsq(Z, np.column_stack([x[1:], y[1:]]), rcond=None)[0].T   # rows: equations for x and y
Python, in your browser — edit the code and run it again

Assumes import numpy as np and import pandas as pd. Each snippet simulates or makes up its own series, as the comments say.

The same idea with a library
# Python — VAR
from statsmodels.tsa.api import VAR

model = VAR(df[['gdp', 'inflation', 'unemployment']])
results = model.fit(maxlags=4, ic='aic')
# Granger causality test
results.test_causality('gdp', ['inflation'], kind='f')
# Impulse response
irf = results.irf(20)
irf.plot()
Sources
  • C. W. J. Granger, “Investigating Causal Relations by Econometric Models and Cross-Spectral Methods”, Econometrica 37(3), 1969
  • C. A. Sims, “Macroeconomics and Reality”, Econometrica 48(1), 1980
  • New Introduction to Multiple Time Series Analysis, H. Lütkepohl, Springer, 2005

Last reviewed October 2026 · How this site checks its content · Report a mistake

Linked from 1
← Previous
GARCH
Open in the full reader, with the topic sidebar