Skip to content

Latest commit

 

History

41 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SystemProjectionsIV.jl

CI Docs docs codecov Aqua QA

A Julia implementation of the System Projections IV (SP-IV) estimator of Lewis & Mertens (2024). SP-IV identifies structural macroeconomic relationships (such as the Phillips Curve) by exploiting external instruments through impulse responses rather than raw variables, conditioning on a rich set of predetermined controls so that many lags of instruments can be used without losing identifying power.

Status: alpha, under active development. The API is not yet stable.

Note: This is an independent, unofficial implementation of the SP-IV methodology developed by Lewis & Mertens (2024). It is not affiliated with or endorsed by the paper's authors, and any implementation errors are the package author's own.

Installation

The package is not registered. Install directly from the repository:

using Pkg
Pkg.add(url = "https://github.com/andrerecio/SystemProjectionsIV.jl")

Quick start

using SystemProjectionsIV, StatsBase, Random

# Simulate a small SP-IV design: y_t = β·Y_t + u_t, where Y responds to an
# external instrument ε through a known impulse response and is endogenous (Y
# correlates with the structural error u).
Random.seed!(1234)
T, H, β = 400, 8, 0.5
ε = randn(T)                          # external instrument / shock
u = 0.3 .* randn(T)
Y = zeros(T)
for t in 1:T, j in 0:3
    t - j  1 && (Y[t] += 0.8^j * ε[t - j])
end
Y .+= 0.7 .* u .+ 0.2 .* randn(T)     # endogeneity

y = β .* Y .+ u

# y outcome, Y endogenous regressor(s), ε instrument(s); vectors or matrices
# both work, and an intercept is included by default.
result = spiv(y, Y, ε; H = H, weak_iv = :AR)

result                  # pretty summary: β̂, weak-IV verdict, robust set, IRF shapes
summary(result)         # the same table, R-style
coef(result)            # β̂
confint(result)         # strong-identification 95% CI
weak_iv_test(result)    # g statistic, critical value, is_weak
robust_inference(result)            # AR confidence set + per-parameter bounds
irf(result).point                   # outcome IRF point estimates (H × Nz)
irf(result; response = :endogenous) # endogenous-regressor IRFs (H × K × Nz)

spiv returns an SPIVResult carrying the structural estimate β̂, its sandwich covariance under strong identification, residuals, weak-IV diagnostics, robust (AR or KLM) confidence sets, and the implied IRFs with HAC standard errors. Pass hac = :neweywest (or :andrews) for automatic-bandwidth Newey–West IRF standard errors instead of the default fixed lag truncation. With Plots loaded, plot(result) draws the outcome IRF bands (plot(result; response = :endogenous) for the endogenous IRFs).

Controls enter through keywords, with the sample adjusted automatically (Stata/R-style): leading rows containing NaN — the burn-in that the exported lag/lags helpers produce — are dropped from every input. xlags = p controls for p lags of all the variables (the same information set as the VAR variant), and X = ... adds arbitrary extra columns beyond the automatic intercept (intercept = false drops the constant):

result = spiv(y, Y, ε; H = H, xlags = 4)             # lags of [y Y ε] as controls
result = spiv(y, Y, ε; H = H, X = lags(Y, 4))        # your own lagged controls

Examples

Runnable scripts live under examples/:

  • examples/demo.jl — a text-only walkthrough of the whole API (LP and VAR variants, weak-IV diagnostic, AR/KLM robust sets, IRFs, an overidentified case). Run it in the package environment:

    julia --project examples/demo.jl
  • examples/plots.jl — renders the IRF figures via the Plots recipe. The package itself depends only on RecipesBase, so Plots is kept out of its dependencies and lives in a separate examples/ environment instead:

    julia -e 'using Pkg; Pkg.activate("examples"); Pkg.develop(path="."); Pkg.add("Plots")'
    julia --project=examples examples/plots.jl

What it estimates

The structural equation

y_t = β' Y_t + u_t

is estimated by regressing the impulse responses of y_t to the external shocks Z on the impulse responses of Y_t to the same shocks, after residualising on lagged controls X_{t-1}. This bypasses the weak-instrument problem that afflicts standard 2SLS with distributed-lag instruments. The canonical empirical application is the Phillips Curve, where y_t = π_t, Y_t = (π_{t-1}, E_t π_{t+1}, gap_t), and Z_t is a vector of monetary-policy shocks.

Inference

  • Strong identification. Sandwich asymptotic variance with no HAR adjustment (lagged controls absorb the autocorrelation); normal confidence intervals always reported.
  • Weak identification. A bias-based first-stage test with a conservative (moment-matched) critical value flags weak instruments. Robust confidence sets are available via either the Anderson–Rubin (weak_iv = :AR) or Kleibergen LM (weak_iv = :KLM) statistic, computed by grid search.
  • IRFs. Newey–West HAC standard errors on the implied outcome and endogenous impulse responses, with a fixed (hac = :fixed, default) or automatic (:neweywest / :andrews) bandwidth.

See docs/technical.md for the full mathematical specification.

References

  • Lewis, D. J., & Mertens, K. (2024). Dynamic Identification Using System Projections on Instrumental Variables. Federal Reserve Bank of Dallas Working Paper No. 2204 (revised July 2024). doi:10.24149/wp2204r3

If you use this package, please cite the paper and the package — see CITATION.bib.

License

MIT — see LICENSE.

About

Julia package for estimating System Projections on Instrumental Variables (SP-IV), following Lewis and Mertens (2024)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages