API Functions
This page documents all functions in MacroEconometricModels.jl, organized by module.
Data Management
Validation and Cleaning
MacroEconometricModels.diagnose — Function
diagnose(d::AbstractMacroData) -> DataDiagnosticScan data for NaN, Inf, constant columns, and very short series.
Examples
d = TimeSeriesData(randn(100, 3))
diag = diagnose(d)
diag.is_clean # true if no issuesMacroEconometricModels.fix — Function
fix(d::TimeSeriesData; method=:listwise) -> TimeSeriesDataFix data issues and return a clean copy.
Methods
:listwise— drop rows with any NaN or Inf (default):interpolate— linear interpolation for interior NaN, forward-fill edges:mean— replace NaN with column mean of finite values
Inf values are always replaced with NaN first (then handled by the chosen method). Constant columns are dropped with a warning.
Examples
d = TimeSeriesData([1.0 NaN; 2.0 3.0; 3.0 4.0])
d_clean = fix(d; method=:listwise) # drops row 1fix(d::PanelData; method=:listwise) -> PanelDataFix data issues and return a clean copy.
Methods
:listwise— drop rows with any NaN or Inf (default):interpolate— linear interpolation within each group:mean— replace NaN with within-group column mean
Inf values are replaced with NaN first. Constant columns are dropped with a warning.
fix(d::CrossSectionData; method=:listwise) -> CrossSectionDataFix data issues and return a clean copy.
Methods
:listwise— drop rows with any NaN or Inf (default):mean— replace NaN with column mean of finite values:interpolate— same as:mean(no time ordering in cross-section data)
Inf values are replaced with NaN first. Constant columns are dropped with a warning.
MacroEconometricModels.validate_for_model — Function
validate_for_model(d::AbstractMacroData, model_type::Symbol)Check that data is compatible with the specified model type. Throws ArgumentError on mismatch.
Model types requiring multivariate data (n_vars ≥ 2)
:var, :vecm, :bvar, :factors, :dynamic_factors, :gdfm
Model types requiring univariate data (n_vars == 1)
:arima, :ar, :ma, :arma, :arch, :garch, :egarch, :gjr_garch, :sv, :hp_filter, :hamilton_filter, :beveridge_nelson, :baxter_king, :boosted_hp, :adf, :kpss, :pp, :za, :ngperron
Model types accepting any dimensionality
:lp, :lp_iv, :smooth_lp, :state_lp, :propensity_lp, :gmm
Examples
d = TimeSeriesData(randn(100, 3))
validate_for_model(d, :var) # OK
validate_for_model(d, :arima) # throws ArgumentErrorFRED Transformations
MacroEconometricModels.apply_tcode — Function
apply_tcode(y::AbstractVector{<:Real}, tcode::Int) -> Vector{Float64}Apply FRED transformation code to a univariate series.
Codes 4–7 require strictly positive data. The output vector is shorter than the input for difference-based codes:
- tcode 1: same length
- tcode 2, 4, 5: length T-1
- tcode 3, 6, 7: length T-2
Examples
y = [100.0, 102.0, 105.0, 103.0, 108.0]
apply_tcode(y, 5) # log first differences (approx growth rates)apply_tcode(d::TimeSeriesData, tcodes::Vector{Int}) -> TimeSeriesDataApply per-variable FRED transformation codes. Rows are trimmed consistently (to the shortest transformed series).
Examples
d = TimeSeriesData(rand(200, 3) .+ 1; varnames=["GDP","CPI","FFR"])
d2 = apply_tcode(d, [5, 5, 1]) # log-diff GDP and CPI, leave FFR in levelsapply_tcode(d::TimeSeriesData, tcode::Int) -> TimeSeriesDataApply the same FRED transformation code to all variables.
apply_tcode(d::TimeSeriesData) -> TimeSeriesDataConvenience method: apply the transformation codes stored in d.tcode. Equivalent to apply_tcode(d, d.tcode).
Examples
d = load_example(:fred_md) # tcode already set
d_transformed = apply_tcode(d)apply_tcode(d::PanelData, tcodes::Vector{Int}) -> PanelDataApply per-variable FRED transformation codes to a PanelData container, processing each group independently. Each group is trimmed to its own common length after transformation, then reassembled.
Examples
pd = xtset(df, :id, :t)
pd2 = apply_tcode(pd, [5, 5, 1]) # log-diff first two vars, leave third in levelsapply_tcode(d::PanelData, tcode::Int) -> PanelDataApply the same FRED transformation code to all variables in a PanelData container.
MacroEconometricModels.inverse_tcode — Function
inverse_tcode(y::AbstractVector{<:Real}, tcode::Int;
x_prev::Union{AbstractVector{<:Real},Nothing}=nothing) -> Vector{Float64}Undo a FRED transformation to recover the original series.
For difference-based codes (2, 3, 5, 6, 7), x_prev must supply the initial values needed for reconstruction:
- tcode 2:
x_prev = [x₀](1 value) - tcode 3:
x_prev = [x₀, x₁](2 values, original levels) - tcode 5:
x_prev = [x₀](1 value, original level) - tcode 6:
x_prev = [x₀, x₁](2 values, original levels) - tcode 7:
x_prev = [x₀, x₁](2 values, original levels)
Examples
y = [100.0, 102.0, 105.0]
yd = apply_tcode(y, 2) # [2.0, 3.0]
inverse_tcode(yd, 2; x_prev=[100.0]) # [102.0, 105.0]Filtering
MacroEconometricModels.apply_filter — Function
apply_filter(d::TimeSeriesData, specs::AbstractVector; component=:cycle, kwargs...)Apply per-variable filter specifications to a TimeSeriesData container.
Each element of specs can be:
Symbol— filter name (:hp,:hamilton,:bn,:bk,:boosted_hp)AbstractFilterResult— a pre-computed filter resultTuple{filter, Symbol}— filter with per-variable component override (e.g.,(:hp, :trend))nothing— pass-through (no filtering for this variable)
The output is trimmed to the intersection of valid ranges across all variables.
Arguments
d::TimeSeriesData— input dataspecs::AbstractVector— per-variable filter specifications (length must equaln_vars)
Keyword Arguments
component::Symbol=:cycle— default component to extract (:cycleor:trend)- Additional kwargs are forwarded to filter functions
Returns
A new TimeSeriesData with filtered data, trimmed to the common valid range.
Examples
d = TimeSeriesData(cumsum(randn(200, 3), dims=1); varnames=["GDP","CPI","FFR"])
# Per-variable: HP cycle for GDP, Hamilton cycle for CPI, pass-through FFR
d2 = apply_filter(d, [:hp, :hamilton, nothing])
# Per-variable component overrides via tuples
d3 = apply_filter(d, [(:hp, :trend), (:hamilton, :cycle), nothing])apply_filter(d::TimeSeriesData, spec::Union{Symbol, AbstractFilterResult};
component=:cycle, vars=nothing, kwargs...)Apply a single filter to all variables (or a subset specified by vars).
Variables not in vars are passed through unchanged.
Arguments
d::TimeSeriesData— input dataspec— filter symbol (:hp,:hamilton,:bn,:bk,:boosted_hp) or pre-computed result
Keyword Arguments
component::Symbol=:cycle— component to extract (:cycleor:trend)vars::Union{Nothing, Vector{String}, Vector{Int}}— variables to filter (default: all)- Additional kwargs are forwarded to filter functions
Examples
d = TimeSeriesData(cumsum(randn(200, 3), dims=1); varnames=["GDP","CPI","FFR"])
# HP cycle for all variables
d_hp = apply_filter(d, :hp)
# HP trend for selected variables only
d_sel = apply_filter(d, :hp; vars=["GDP", "CPI"], component=:trend)apply_filter(d::PanelData, spec; component=:cycle, vars=nothing, kwargs...)Apply filters to a PanelData container group-by-group.
Each group is extracted via group_data, filtered, and the results are reassembled into a new PanelData. Each group is trimmed independently to its own common valid range (groups may have different resulting lengths if unbalanced).
Arguments
d::PanelData— input panel dataspec— filter specification: a singleSymbol,AbstractFilterResult, orAbstractVectorof per-variable specs (same formats asTimeSeriesData)
Keyword Arguments
component::Symbol=:cycle— component to extractvars— variables to filter (others pass-through)- Additional kwargs forwarded to filter functions
Examples
pd = xtset(df, :id, :t)
pd_hp = apply_filter(pd, :hp; component=:cycle)
pd_sel = apply_filter(pd, :hp; vars=["GDP"], component=:trend)Summary Statistics
MacroEconometricModels.describe_data — Function
describe_data(d::AbstractMacroData) -> DataSummaryCompute per-variable summary statistics (N, Mean, Std, Min, P25, Median, P75, Max, Skewness, Kurtosis). NaN values are excluded from all computations.
For PanelData, also prints panel dimensions via panel_summary.
Examples
d = TimeSeriesData(randn(200, 3); varnames=["GDP","CPI","FFR"], frequency=Quarterly)
describe_data(d)Panel Data
MacroEconometricModels.xtset — Function
xtset(df::DataFrame, group_col::Symbol, time_col::Symbol;
varnames=nothing, frequency=Other, tcode=nothing,
cohort=nothing) -> PanelData{Float64}Construct a PanelData container from a DataFrame, analogous to Stata's xtset.
Extracts all numeric columns (excluding group_col, time_col, and cohort), sorts by (group, time), validates no duplicate (group, time) pairs, and detects whether the panel is balanced.
Arguments
df::DataFrame— input datagroup_col::Symbol— column name identifying groups (entities)time_col::Symbol— column name identifying time periods
Keyword Arguments
varnames::Union{Vector{String},Nothing}— override variable names (default: column names)frequency::Frequency— data frequency (default:Other)tcode::Union{Vector{Int},Nothing}— transformation codes per variablecohort::Union{Symbol,Nothing}— column name identifying cohort membership (default:nothing)
Examples
using DataFrames
df = DataFrame(id=repeat(1:3, inner=50), t=repeat(1:50, 3),
x=randn(150), y=randn(150))
pd = xtset(df, :id, :t)MacroEconometricModels.isbalanced — Function
isbalanced(d::PanelData) -> BoolReturn true if all groups have the same number of observations.
MacroEconometricModels.groups — Function
groups(d::PanelData) -> Vector{String}Return the group names.
MacroEconometricModels.ngroups — Function
ngroups(d::PanelData) -> IntReturn the number of groups.
MacroEconometricModels.group_data — Function
group_data(d::PanelData, g) -> TimeSeriesDataExtract data for a single group as a TimeSeriesData container.
g can be an integer group index or a string group name.
Examples
pd = xtset(df, :id, :t)
g1 = group_data(pd, 1) # by index
g1 = group_data(pd, "1") # by nameMacroEconometricModels.panel_summary — Function
panel_summary(d::PanelData)Display a summary table of the panel structure: number of groups, observations per group (min, mean, max), and balance status.
Examples
pd = xtset(df, :id, :t)
panel_summary(pd)Data Accessors and Conversion
StatsAPI.nobs — Method
StatsAPI.nobs(d::AbstractMacroData)Return the number of observations.
MacroEconometricModels.nvars — Function
nvars(d::AbstractMacroData)Return the number of variables.
MacroEconometricModels.varnames — Function
varnames(d::AbstractMacroData)Return variable names.
MacroEconometricModels.frequency — Function
frequency(d::TimeSeriesData)
frequency(d::PanelData)Return the data frequency.
MacroEconometricModels.time_index — Function
time_index(d::TimeSeriesData)Return the integer time index vector.
MacroEconometricModels.obs_id — Function
obs_id(d::CrossSectionData)Return the observation identifier vector.
MacroEconometricModels.desc — Function
desc(d::AbstractMacroData) -> StringReturn the dataset description. Returns "" if no description has been set.
Examples
d = TimeSeriesData(randn(100, 3); desc="US macro quarterly data")
desc(d) # "US macro quarterly data"MacroEconometricModels.vardesc — Function
vardesc(d::AbstractMacroData) -> Dict{String,String}Return the dictionary of per-variable descriptions.
Examples
d = TimeSeriesData(randn(100, 2); varnames=["GDP","CPI"],
vardesc=Dict("GDP" => "Real GDP growth", "CPI" => "Consumer prices"))
vardesc(d) # Dict("GDP" => "Real GDP growth", "CPI" => "Consumer prices")vardesc(d::AbstractMacroData, name::String) -> StringReturn the description for variable name. Throws ArgumentError if no description exists for that variable.
Examples
vardesc(d, "GDP") # "Real GDP growth"MacroEconometricModels.rename_vars! — Function
rename_vars!(d::AbstractMacroData, old => new)
rename_vars!(d::AbstractMacroData, names::Vector{String})Rename variables in a data container. With a Pair, renames a single variable. With a Vector{String}, replaces all variable names. Also updates vardesc keys.
MacroEconometricModels.set_time_index! — Function
set_time_index!(d::TimeSeriesData, idx::Vector{Int})Set the time index for a TimeSeriesData container.
MacroEconometricModels.set_obs_id! — Function
set_obs_id!(d::CrossSectionData, ids::Vector{Int})Set observation identifiers for a CrossSectionData container.
MacroEconometricModels.set_desc! — Function
set_desc!(d::AbstractMacroData, text::String)Set the dataset description.
Examples
d = TimeSeriesData(randn(100, 3))
set_desc!(d, "US macroeconomic quarterly data 1959-2024")
desc(d) # "US macroeconomic quarterly data 1959-2024"MacroEconometricModels.set_vardesc! — Function
set_vardesc!(d::AbstractMacroData, name::String, text::String)Set the description for a single variable. The variable must exist in the data.
Examples
d = TimeSeriesData(randn(100, 2); varnames=["GDP", "CPI"])
set_vardesc!(d, "GDP", "Real Gross Domestic Product, seasonally adjusted")
set_vardesc!(d, "CPI", "Consumer Price Index for All Urban Consumers")
vardesc(d, "GDP") # "Real Gross Domestic Product, seasonally adjusted"set_vardesc!(d::AbstractMacroData, descriptions::Dict{String,String})Set descriptions for multiple variables at once. All keys must be valid variable names.
Examples
set_vardesc!(d, Dict("GDP" => "Real GDP", "CPI" => "Consumer prices"))MacroEconometricModels.dates — Function
dates(d::TimeSeriesData) -> Vector{String}Return the date labels vector. Returns empty vector if no dates are set.
MacroEconometricModels.set_dates! — Function
set_dates!(d::TimeSeriesData, dates::Vector{String})Set the date labels for a TimeSeriesData container. Length must match T_obs, or pass an empty vector to clear dates.
Examples
d = TimeSeriesData(randn(4, 2))
set_dates!(d, ["2020Q1", "2020Q2", "2020Q3", "2020Q4"])
dates(d) # ["2020Q1", "2020Q2", "2020Q3", "2020Q4"]MacroEconometricModels.to_matrix — Function
to_matrix(d::TimeSeriesData) -> MatrixReturn the raw data matrix from a TimeSeriesData container.
to_matrix(d::PanelData) -> MatrixReturn the raw stacked data matrix from a PanelData container.
to_matrix(d::CrossSectionData) -> MatrixReturn the raw data matrix from a CrossSectionData container.
MacroEconometricModels.to_vector — Function
to_vector(d::TimeSeriesData) -> VectorReturn the data as a vector (requires exactly 1 variable).
to_vector(d::TimeSeriesData, var::Int) -> VectorReturn a single column by index.
to_vector(d::TimeSeriesData, var::String) -> VectorReturn a single column by name.
MacroEconometricModels.load_example — Function
load_example(name::Symbol) -> AbstractMacroDataLoad a built-in example dataset.
Available Datasets
:fred_md— FRED-MD Monthly Database, January 2026 vintage (126 variables × 804 months) →TimeSeriesData:fred_qd— FRED-QD Quarterly Database, January 2026 vintage (245 variables × 268 quarters) →TimeSeriesData:pwt— Penn World Table 10.01, 38 OECD countries (42 variables × 74 years, 1950–2023) →PanelData:ddcg— Acemoglu et al. (2019) Democracy-GDP Panel (2 variables × 9,384 obs, 184 countries × 51 years) →PanelData:mpdta— Callaway & Sant'Anna (2021) Minimum Wage Panel (3 variables × 2,500 obs, 500 counties × 5 years) →PanelData
For time series datasets, the returned TimeSeriesData includes variable names, transformation codes, frequency, per-variable descriptions (via vardesc), dataset description (via desc), and bibliographic references (via refs).
For panel datasets, the returned PanelData includes country identifiers as groups, year identifiers as time index, variable descriptions, and references.
Examples
# Load FRED-MD
md = load_example(:fred_md)
nobs(md) # 804
nvars(md) # 126
desc(md) # "FRED-MD Monthly Database, January 2026 Vintage (McCracken & Ng 2016)"
vardesc(md, "INDPRO") # "IP Index"
refs(md) # McCracken & Ng (2016)
# Apply recommended transformations
md_transformed = apply_tcode(md, md.tcode)
# Load FRED-QD
qd = load_example(:fred_qd)
# Load Penn World Table (panel data)
pwt = load_example(:pwt)
nobs(pwt) # 2812 (38 countries × 74 years)
nvars(pwt) # 42
ngroups(pwt) # 38
groups(pwt) # ["AUS", "AUT", ..., "USA"]
isbalanced(pwt) # true
g = group_data(pwt, "USA") # extract single country as TimeSeriesData
refs(pwt) # Feenstra, Inklaar & Timmer (2015)Time Series Filters
MacroEconometricModels.hp_filter — Function
hp_filter(y::AbstractVector; lambda=1600.0) -> HPFilterResultApply the Hodrick-Prescott filter to decompose time series y into trend and cycle.
Solves the optimization problem:
\[\min_\tau \sum_{t=1}^T (y_t - \tau_t)^2 + \lambda \sum_{t=2}^{T-1} (\tau_{t+1} - 2\tau_t + \tau_{t-1})^2\]
Implementation uses a sparse pentadiagonal Cholesky factorization for O(T) cost.
Arguments
y::AbstractVector: Time series data (length ≥ 3)
Keywords
lambda::Real=1600.0: Smoothing parameter. Common values: 6.25 (annual), 1600 (quarterly, default), 129600 (monthly)
Returns
HPFilterResult{T}with fieldstrend,cycle,lambda,T_obs
Examples
y = cumsum(randn(200))
result = hp_filter(y)
result = hp_filter(y; lambda=6.25) # annual dataReferences
- Hodrick, R. J., & Prescott, E. C. (1997). JMCB 29(1): 1–16.
MacroEconometricModels.hamilton_filter — Function
hamilton_filter(y::AbstractVector; h=8, p=4) -> HamiltonFilterResultApply the Hamilton (2018) regression filter for trend-cycle decomposition.
Regresses $y_{t+h}$ on $[1, y_t, y_{t-1}, \ldots, y_{t-p+1}]$ by OLS. The residuals form the cyclical component and the fitted values form the trend.
The filter loses h + p - 1 observations at the start of the sample.
Arguments
y::AbstractVector: Time series data
Keywords
h::Int=8: Forecast horizon (default 8 for quarterly data = 2 years)p::Int=4: Number of lags in the regression (default 4 for quarterly data)
Returns
HamiltonFilterResult{T}with fieldstrend,cycle,beta,h,p,T_obs,valid_range
Examples
y = cumsum(randn(200))
result = hamilton_filter(y) # quarterly defaults
result = hamilton_filter(y; h=24, p=12) # monthly data (2-year horizon)References
- Hamilton, J. D. (2018). REStat 100(5): 831–843.
MacroEconometricModels.beveridge_nelson — Function
beveridge_nelson(y::AbstractVector; method=:arima, p=:auto, q=:auto, max_terms=500, cycle_order=2) -> BeveridgeNelsonResultCompute the Beveridge-Nelson decomposition of time series y.
Assumes y is I(1) and decomposes it into:
\[y_t = \tau_t + c_t\]
where $\tau_t$ is a random walk with drift (permanent component) and $c_t$ is a stationary transitory component.
Methods
:arima(default): Classic BN via ARIMA representation (Beveridge & Nelson, 1981):statespace: Correlated UC model via MLE + Kalman smoother (Morley, Nelson & Zivot, 2003)
Arguments
y::AbstractVector: Time series data (assumed I(1), length ≥ 10)
Keywords
method::Symbol=:arima: Decomposition methodp: AR order for ARMA model of Δy (method=:arima).:autousesauto_arimaq: MA order for ARMA model of Δy (method=:arima).:autousesauto_arimamax_terms::Int=500: Maximum ψ-weights for MA(∞) truncation (method=:arima)cycle_order::Int=2: AR order for cyclical component (method=:statespace, 1 or 2)
Returns
BeveridgeNelsonResult{T}with fieldspermanent,transitory,drift,long_run_multiplier,arima_order,T_obs
Examples
# Classic ARIMA-based BN decomposition
y = cumsum(randn(200)) + 0.3 * sin.(2π * (1:200) / 20)
result = beveridge_nelson(y)
result = beveridge_nelson(y; p=2, q=1) # manual ARMA order
# Morley (2002) correlated UC model
result = beveridge_nelson(y; method=:statespace)
result = beveridge_nelson(y; method=:statespace, cycle_order=1)References
- Beveridge, S., & Nelson, C. R. (1981). JME 7(2): 151–174.
- Morley, J. C., Nelson, C. R., & Zivot, E. (2003). REStat 85(2): 235–243.
MacroEconometricModels.baxter_king — Function
baxter_king(y::AbstractVector; pl=6, pu=32, K=12) -> BaxterKingResultApply the Baxter-King band-pass filter to isolate business cycle frequencies.
Computes symmetric moving average weights that approximate the ideal band-pass filter for periods between pl and pu. The filter is constrained to sum to zero (removing stochastic trends).
Loses K observations at each end of the sample (2K total).
Arguments
y::AbstractVector: Time series data (length > 2K)
Keywords
pl::Int=6: Minimum period of oscillation to pass (quarterly: 6 = 1.5 years)pu::Int=32: Maximum period of oscillation to pass (quarterly: 32 = 8 years)K::Int=12: Truncation length (number of leads/lags in the moving average)
Returns
BaxterKingResult{T}with fieldscycle,trend,weights,pl,pu,K,T_obs,valid_range
Examples
y = cumsum(randn(200))
result = baxter_king(y) # quarterly defaults (6-32 quarters)
result = baxter_king(y; pl=2, pu=8, K=6) # annual data (2-8 years)References
- Baxter, M., & King, R. G. (1999). REStat 81(4): 575–593.
MacroEconometricModels.boosted_hp — Function
boosted_hp(y::AbstractVector; lambda=1600.0, stopping=:BIC, max_iter=100, sig_p=0.05) -> BoostedHPResultApply the boosted HP filter (Phillips & Shi 2021) for improved trend estimation.
Iteratively re-filters the cyclical component of the standard HP filter. At each iteration, the cycle is decomposed again and the newly estimated "trend of the cycle" is added back to the overall trend.
Stopping criteria
:ADF— Stop when the ADF test rejects the null of a unit root in the cycle at significance levelsig_p(recommended for detecting stationarity):BIC— Stop when the Phillips-Shi information criterion increases (balances variance reduction against effective degrees of freedom):fixed— Run allmax_iteriterations
Arguments
y::AbstractVector: Time series data (length ≥ 3)
Keywords
lambda::Real=1600.0: HP smoothing parameterstopping::Symbol=:BIC: Stopping criterion (:ADF,:BIC, or:fixed)max_iter::Int=100: Maximum number of boosting iterationssig_p::Real=0.05: Significance level for ADF stopping criterion
Returns
BoostedHPResult{T}with fieldstrend,cycle,lambda,iterations,stopping,bic_path,adf_pvalues,T_obs
Examples
y = cumsum(randn(200))
result = boosted_hp(y) # BIC stopping (default)
result = boosted_hp(y; stopping=:ADF, sig_p=0.05) # ADF stopping
result = boosted_hp(y; stopping=:fixed, max_iter=5) # fixed iterationsReferences
- Phillips, P. C. B., & Shi, Z. (2021). IER 62(2): 521–570.
- Mei, Z., Phillips, P. C. B., & Shi, Z. (2024). JAE 39(7): 1260–1281.
MacroEconometricModels.trend — Function
trend(result::AbstractFilterResult) -> VectorReturn the trend component from a filter result. For BeveridgeNelsonResult, returns the permanent component.
MacroEconometricModels.cycle — Function
cycle(result::AbstractFilterResult) -> VectorReturn the cyclical component from a filter result. For BeveridgeNelsonResult, returns the transitory component.
ARIMA Models
Estimation
MacroEconometricModels.estimate_ar — Function
estimate_ar(y, p; method=:ols, include_intercept=true) -> ARModelEstimate AR(p) model: yₜ = c + φ₁yₜ₋₁ + ... + φₚyₜ₋ₚ + εₜ
Arguments
y: Time series vectorp: AR order (must be ≥ 1)method: Estimation method (:ols or :mle)include_intercept: Whether to include constant term
Returns
ARModel with estimated coefficients and diagnostics.
Example
y = randn(200)
model = estimate_ar(y, 2)
println(model.phi) # AR coefficientsMacroEconometricModels.estimate_ma — Function
estimate_ma(y, q; method=:css_mle, include_intercept=true, max_iter=500) -> MAModelEstimate MA(q) model: yₜ = c + εₜ + θ₁εₜ₋₁ + ... + θqεₜ₋q
Arguments
y: Time series vectorq: MA order (must be ≥ 1)method: Estimation method (:css, :mle, or :css_mle)include_intercept: Whether to include constant termmax_iter: Maximum optimization iterations
Returns
MAModel with estimated coefficients and diagnostics.
Example
y = randn(200)
model = estimate_ma(y, 1)
println(model.theta) # MA coefficientMacroEconometricModels.estimate_arma — Function
estimate_arma(y, p, q; method=:css_mle, include_intercept=true, max_iter=500) -> ARMAModelEstimate ARMA(p,q) model: yₜ = c + φ₁yₜ₋₁ + ... + φₚyₜ₋ₚ + εₜ + θ₁εₜ₋₁ + ... + θqεₜ₋q
Arguments
y: Time series vectorp: AR orderq: MA ordermethod: Estimation method (:css, :mle, or :css_mle)include_intercept: Whether to include constant termmax_iter: Maximum optimization iterations
Returns
ARMAModel with estimated coefficients and diagnostics.
Example
y = randn(200)
model = estimate_arma(y, 1, 1)
println("AR: ", model.phi, " MA: ", model.theta)MacroEconometricModels.estimate_arima — Function
estimate_arima(y, p, d, q; method=:css_mle, include_intercept=true, max_iter=500) -> ARIMAModelEstimate ARIMA(p,d,q) model by differencing d times and fitting ARMA(p,q).
Arguments
y: Time series vectorp: AR orderd: Integration order (number of differences)q: MA ordermethod: Estimation method (:css, :mle, or :css_mle)include_intercept: Whether to include constant term (on differenced series)max_iter: Maximum optimization iterations
Returns
ARIMAModel with estimated coefficients and diagnostics.
Example
y = cumsum(randn(200)) # Random walk
model = estimate_arima(y, 1, 1, 0) # ARIMA(1,1,0)
println(model.phi)Forecasting
MacroEconometricModels._compute_psi_weights — Method
_compute_psi_weights(phi, theta, h) -> Vector{T}Compute ψ-weights for the MA(∞) representation of an ARMA process.
The ARMA(p,q) process can be written as: yₜ = μ + Σⱼ₌₀^∞ ψⱼ εₜ₋ⱼ
where ψ₀ = 1 and ψⱼ follows the recursion: ψⱼ = φ₁ψⱼ₋₁ + ... + φₚψⱼ₋ₚ + θⱼ
Returns ψ₁, ψ₂, ..., ψₕ.
MacroEconometricModels._confidence_band — Method
_confidence_band(forecasts, se, conf_level)Compute symmetric confidence interval bounds from forecasts, standard errors, and a confidence level.
MacroEconometricModels._forecast_arma — Method
_forecast_arma(y, resid, c, phi, theta, sigma2, h, conf_level) -> ARIMAForecastUnified point forecast + CI computation for any ARMA(p,q) model. AR models pass theta=T[], MA models pass phi=T[].
MacroEconometricModels._forecast_variance — Method
_forecast_variance(sigma2, psi, h) -> Vector{T}Compute h-step ahead forecast variance.
Var(eₜ₊ₕ) = σ² (1 + ψ₁² + ψ₂² + ... + ψₕ₋₁²)
MacroEconometricModels._integrate_forecasts — Method
_integrate_forecasts(y, fc_diff, d) -> Vector{T}Integrate d-differenced forecasts back to original scale.
MacroEconometricModels._integrate_se — Method
_integrate_se(se_diff, d) -> Vector{T}Approximate standard errors after integration.
For d-fold integration, the variance grows roughly as h^d. This is a conservative approximation.
MacroEconometricModels.forecast — Method
forecast(model::ARIMAModel, h; conf_level=0.95) -> ARIMAForecastCompute h-step ahead forecasts with confidence intervals for ARIMA model. Forecasts are computed on the differenced series and then integrated back to the original scale.
MacroEconometricModels.forecast — Method
forecast(model::ARMAModel, h; conf_level=0.95) -> ARIMAForecastCompute h-step ahead forecasts with confidence intervals for ARMA model.
MacroEconometricModels.forecast — Method
forecast(model::ARModel, h; conf_level=0.95) -> ARIMAForecastCompute h-step ahead forecasts with confidence intervals for AR model.
MacroEconometricModels.forecast — Method
forecast(model::MAModel, h; conf_level=0.95) -> ARIMAForecastCompute h-step ahead forecasts with confidence intervals for MA model.
StatsAPI.predict — Method
predict(model::AbstractARIMAModel, h::Int) -> Vector{T}Return h-step ahead point forecasts (without confidence intervals).
Order Selection
MacroEconometricModels.select_arima_order — Function
select_arima_order(y, max_p, max_q; criterion=:bic, d=0, method=:css_mle, include_intercept=true)Automatically select ARMA/ARIMA order via grid search over information criteria.
Searches over p ∈ 0:maxp and q ∈ 0:maxq, fits each model, and selects the order that minimizes the specified information criterion.
Arguments
y: Time series vectormax_p: Maximum AR order to considermax_q: Maximum MA order to considercriterion: Selection criterion (:aic or :bic, default :bic)d: Integration order for ARIMA (default 0 = ARMA)method: Estimation method (:css, :mle, or :css_mle)include_intercept: Whether to include constant term
Returns
ARIMAOrderSelection with best orders, IC matrices, and fitted models.
Example
y = randn(200)
result = select_arima_order(y, 3, 3; criterion=:bic)
println("Best order: p=$(result.best_p_bic), q=$(result.best_q_bic)")
best_model = result.best_model_bicMacroEconometricModels.auto_arima — Function
auto_arima(y; max_p=5, max_q=5, max_d=2, criterion=:bic, method=:css_mle, stepwise=true)Automatically select and fit the best ARIMA model.
Performs order selection over p, d, and q using the specified criterion. For integration order d, uses unit root test heuristics.
Arguments
y: Time series vectormax_p: Maximum AR order (default 5)max_q: Maximum MA order (default 5)max_d: Maximum integration order (default 2)criterion: Selection criterion (:aic or :bic)method: Estimation methodstepwise: Iftrue(default), use Hyndman-Khandakar (2008) stepwise search. Iffalse, use exhaustive grid search over all (p,q) combinations.
Returns
Best fitted ARIMAModel or ARMAModel.
Example
y = cumsum(randn(200))
model = auto_arima(y)
println(model)References
- Hyndman, R. J., & Khandakar, Y. (2008). Automatic time series forecasting: the forecast package for R. Journal of Statistical Software 27(3): 1–22.
MacroEconometricModels.ic_table — Function
ic_table(result::ARIMAOrderSelection; criterion=:bic)Return a formatted table of IC values for printing.
ARIMA Accessors
MacroEconometricModels.ar_order — Function
Return AR order p.
MacroEconometricModels.ma_order — Function
Return MA order q.
MacroEconometricModels.diff_order — Function
Return integration order d.
ARIMA StatsAPI Interface
StatsAPI.stderror — Method
Standard errors for AR model coefficients.
StatsAPI.stderror — Method
Standard errors for MA model coefficients.
StatsAPI.stderror — Method
Standard errors for ARMA model coefficients.
StatsAPI.stderror — Method
Standard errors for ARIMA model coefficients.
Cross-Sectional Models
Estimation
MacroEconometricModels.estimate_reg — Function
estimate_reg(y, X; cov_type=:hc1, weights=nothing, varnames=nothing, clusters=nothing) -> RegModel{T}Estimate a linear regression model via OLS or WLS.
OLS: beta = (X'X)^{-1} X'y WLS: beta = (X'WX)^{-1} X'Wy where W = diag(weights)
Arguments
y::AbstractVector{T}— dependent variable (n x 1)X::AbstractMatrix{T}— regressor matrix (n x k), should include a constant columncov_type::Symbol— covariance estimator::ols,:hc0,:hc1(default),:hc2,:hc3,:clusterweights::Union{Nothing,AbstractVector}— WLS weights (nothing for OLS)varnames::Union{Nothing,Vector{String}}— coefficient names (auto-generated if nothing)clusters::Union{Nothing,AbstractVector}— cluster assignments (required for:cluster)
Returns
RegModel{T} with estimated coefficients, robust covariance matrix, fit statistics.
Examples
using MacroEconometricModels
n = 200
X = hcat(ones(n), randn(n, 2))
beta_true = [1.0, 2.0, -0.5]
y = X * beta_true + 0.5 * randn(n)
m = estimate_reg(y, X)
report(m)References
- Greene, W. H. (2018). Econometric Analysis. 8th ed. Pearson.
- White, H. (1980). Econometrica 48(4), 817-838.
MacroEconometricModels.estimate_iv — Function
estimate_iv(y, X, Z; endogenous, cov_type=:hc1, varnames=nothing) -> RegModel{T}Estimate a linear regression model via instrumental variables / two-stage least squares (IV/2SLS).
Algorithm
- Project regressors onto instrument space: Xhat = PZ * X where P_Z = Z(Z'Z)^{-1}Z'
- Second stage: beta = (Xhat'X)^{-1} Xhat'y
- Residuals from ORIGINAL X: e = y - Xbeta (not X_hatbeta)
- Covariance uses X_hat for the bread and original residuals for the meat
Arguments
y::AbstractVector{T}— dependent variable (n x 1)X::AbstractMatrix{T}— regressor matrix (n x k), includes exogenous regressors and interceptZ::AbstractMatrix{T}— instrument matrix (n x m), includes exogenous regressors and excluded instrumentsendogenous::Vector{Int}— column indices of endogenous regressors in Xcov_type::Symbol— covariance estimator::ols,:hc0,:hc1(default),:hc2,:hc3varnames::Union{Nothing,Vector{String}}— coefficient names (auto-generated if nothing)
Returns
RegModel{T} with method=:iv, including first-stage F-statistic and Sargan test.
Diagnostics
first_stage_f: minimum first-stage F across endogenous variables (>10 suggests strong instruments)sargan_stat/sargan_pval: overidentification test (nothing if exactly identified)
Examples
using MacroEconometricModels
n = 500
z1, z2 = randn(n), randn(n)
x_endog = 0.5 * z1 + 0.3 * z2 + randn(n)
u = randn(n)
x_endog .+= 0.5 * u # endogeneity
y = 1.0 .+ 2.0 * x_endog + u
X = hcat(ones(n), x_endog)
Z = hcat(ones(n), z1, z2)
m = estimate_iv(y, X, Z; endogenous=[2])
report(m)References
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press, ch. 5.
- Stock, J. H. & Yogo, M. (2005). Identification and Inference for Econometric Models. Cambridge University Press, ch. 5.
MacroEconometricModels.estimate_logit — Function
estimate_logit(y, X; cov_type=:ols, varnames=nothing, clusters=nothing, maxiter=100, tol=1e-8) -> LogitModel{T}Estimate a binary logistic regression model via maximum likelihood (IRLS/Fisher scoring).
Algorithm
Uses iteratively reweighted least squares with the canonical logit link mu = 1/(1+exp(-X*beta)). Converges when the change in log-likelihood is below tol * (|loglik| + 1).
Arguments
y::AbstractVector{T}— binary dependent variable (0/1), n x 1X::AbstractMatrix{T}— regressor matrix (n x k), should include a constant columncov_type::Symbol— covariance estimator::ols(information matrix),:hc0,:hc1,:hc2,:hc3,:clustervarnames::Union{Nothing,Vector{String}}— coefficient names (auto-generated if nothing)clusters::Union{Nothing,AbstractVector}— cluster assignments (required for:cluster)maxiter::Int— maximum IRLS iterations (default 100)tol— convergence tolerance (default 1e-8)
Returns
LogitModel{T} with estimated coefficients, McFadden pseudo-R-squared, deviance residuals.
Examples
using MacroEconometricModels, Random
rng = MersenneTwister(42)
n = 500
X = hcat(ones(n), randn(rng, n, 2))
beta_true = [0.0, 1.5, -1.0]
p = 1 ./ (1 .+ exp.(-X * beta_true))
y = Float64.(rand(rng, n) .< p)
m = estimate_logit(y, X; varnames=["const", "x1", "x2"])
report(m)References
- McCullagh, P. & Nelder, J. A. (1989). Generalized Linear Models. Chapman & Hall.
- Agresti, A. (2002). Categorical Data Analysis. 2nd ed. Wiley.
MacroEconometricModels.estimate_probit — Function
estimate_probit(y, X; cov_type=:ols, varnames=nothing, clusters=nothing, maxiter=100, tol=1e-8) -> ProbitModel{T}Estimate a binary probit regression model via maximum likelihood (IRLS/Fisher scoring).
Algorithm
Uses iteratively reweighted least squares with the probit link mu = Phi(X*beta), where Phi is the standard normal CDF. Converges when the change in log-likelihood is below tol * (|loglik| + 1).
Arguments
y::AbstractVector{T}— binary dependent variable (0/1), n x 1X::AbstractMatrix{T}— regressor matrix (n x k), should include a constant columncov_type::Symbol— covariance estimator::ols(information matrix),:hc0,:hc1,:hc2,:hc3,:clustervarnames::Union{Nothing,Vector{String}}— coefficient names (auto-generated if nothing)clusters::Union{Nothing,AbstractVector}— cluster assignments (required for:cluster)maxiter::Int— maximum IRLS iterations (default 100)tol— convergence tolerance (default 1e-8)
Returns
ProbitModel{T} with estimated coefficients, McFadden pseudo-R-squared, deviance residuals.
Examples
using MacroEconometricModels, Random
rng = MersenneTwister(42)
n = 500
X = hcat(ones(n), randn(rng, n, 2))
beta_true = [0.0, 1.0, -0.8]
using Distributions
p = cdf.(Normal(), X * beta_true)
y = Float64.(rand(rng, n) .< p)
m = estimate_probit(y, X; varnames=["const", "x1", "x2"])
report(m)References
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press, ch. 15.
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press, ch. 14.
Marginal Effects and Odds Ratios
MacroEconometricModels.marginal_effects — Function
marginal_effects(m::LogitModel{T}; type=:ame, at=nothing, conf_level=0.95) -> MarginalEffects{T}Compute marginal effects from a logistic regression model with delta-method SEs.
Types
:ame— Average Marginal Effects: (1/N) sumi f(Xi beta) * beta_j:mem— Marginal Effects at the Mean: f(Xbar beta) * betaj:mer— Marginal Effects at Representative values: f(x0 beta) * betaj
where f(eta) = logistic PDF = p(1-p) and p = 1/(1+exp(-eta)).
Arguments
m::LogitModel{T}— estimated logit modeltype::Symbol— :ame (default), :mem, or :merat::Union{Nothing,Dict}— for :mer, Dict mapping column index => valueconf_level::Real— confidence level (default 0.95)
Returns
MarginalEffects{T} with effects, delta-method SEs, z-stats, p-values, and CIs.
Examples
m = estimate_logit(y, X)
me_ame = marginal_effects(m) # AME
me_mem = marginal_effects(m; type=:mem) # MEM
me_mer = marginal_effects(m; type=:mer, at=Dict(2=>0.0)) # MER at x2=0References
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press, ch. 14.
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press.
marginal_effects(m::ProbitModel{T}; type=:ame, at=nothing, conf_level=0.95) -> MarginalEffects{T}Compute marginal effects from a probit regression model with delta-method SEs.
Types
:ame— Average Marginal Effects: (1/N) sumi phi(Xi beta) * beta_j:mem— Marginal Effects at the Mean: phi(Xbar beta) * betaj:mer— Marginal Effects at Representative values: phi(x0 beta) * betaj
where phi(eta) = standard normal PDF.
Arguments
m::ProbitModel{T}— estimated probit modeltype::Symbol— :ame (default), :mem, or :merat::Union{Nothing,Dict}— for :mer, Dict mapping column index => valueconf_level::Real— confidence level (default 0.95)
Returns
MarginalEffects{T} with effects, delta-method SEs, z-stats, p-values, and CIs.
Examples
m = estimate_probit(y, X)
me_ame = marginal_effects(m) # AME
me_mem = marginal_effects(m; type=:mem) # MEM
me_mer = marginal_effects(m; type=:mer, at=Dict(2=>0.0)) # MER at x2=0References
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press, ch. 14.
marginal_effects(m::OrderedLogitModel{T}) -> NamedTupleCompute average marginal effects (AME) for an ordered logit model.
Returns a K x J matrix of AMEs where element (k,j) is the average marginal effect of variable k on P(y = j).
Formula: dP(y=j)/dxk = [f(alpha{j-1} - x'beta) - f(alphaj - x'beta)] * betak where f is the logistic PDF, alpha0 = -Inf, alphaJ = +Inf.
Key property: AMEs sum to zero across categories for each variable.
Returns
Named tuple with fields:
effects::Matrix{T}– K x J matrix of AMEsvarnames::Vector{String}– variable namescategories::Vector– category labels
References
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press, ch. 15.
- Greene, W. H. (2012). Econometric Analysis. 7th ed. Prentice Hall.
marginal_effects(m::OrderedProbitModel{T}) -> NamedTupleCompute average marginal effects (AME) for an ordered probit model.
Same structure as marginal_effects(::OrderedLogitModel) but using the standard normal PDF.
References
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press, ch. 15.
- Greene, W. H. (2012). Econometric Analysis. 7th ed. Prentice Hall.
marginal_effects(m::MultinomialLogitModel{T}) -> NamedTupleCompute average marginal effects (AME) for a multinomial logit model.
Returns a K x J matrix of AMEs where element (k,j) is the average marginal effect of variable k on P(y = j).
Formula: dP(y=j)/dxk = pj * (beta{j,k} - summ pm * beta{m,k}) where beta for the base category = 0.
Key property: AMEs sum to zero across categories for each variable.
Returns
Named tuple with fields:
effects::Matrix{T}– K x J matrix of AMEsvarnames::Vector{String}– variable namescategories::Vector– category labels
References
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press, ch. 15.
- Train, K. E. (2009). Discrete Choice Methods with Simulation. 2nd ed. Cambridge Univ. Press.
marginal_effects(m::PanelLogitModel{T}; conf_level=0.95, n_quadrature=12) -> MarginalEffects{T}Compute average marginal effects from a panel logit model with delta-method SEs.
Formulas by model type
- Pooled: AMEj = (1/n) sumi Lambda(xi'beta)(1-Lambda(xi'beta)) * beta_j
- FE (conditional): AMEj = (1/n) sumi Lambda(xi'beta)(1-Lambda(xi'beta)) * beta_j (evaluated at observed X without entity effects)
- RE: AMEj = (1/n) sumi integral Lambda(xi'beta + sigmausqrt(2)u)(1-Lambda(...)) * beta_j * w(u) du (integrated over random effect using Gauss-Hermite quadrature)
- CRE: Same as RE but only reports AMEs for original variables (not group-mean augmented ones)
Arguments
m::PanelLogitModel{T}– estimated panel logit modelconf_level::Real– confidence level for CIs (default 0.95)n_quadrature::Int– number of Gauss-Hermite quadrature points for RE/CRE (default 12)
Returns
MarginalEffects{T} with AMEs, delta-method SEs, z-stats, p-values, and CIs.
References
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press.
- Cameron, A. C. & Trivedi, P. K. (2005). Microeconometrics. Cambridge University Press.
marginal_effects(m::PanelProbitModel{T}; conf_level=0.95, n_quadrature=12) -> MarginalEffects{T}Compute average marginal effects from a panel probit model with delta-method SEs.
Formulas by model type
- Pooled: AMEj = (1/n) sumi phi(xi'beta) * betaj
- RE: AMEj = (1/n) sumi integral phi(xi'beta + sigmausqrt(2)u) * beta_j * w(u) du
- CRE: Same as RE but only reports AMEs for original variables
Arguments
m::PanelProbitModel{T}– estimated panel probit modelconf_level::Real– confidence level for CIs (default 0.95)n_quadrature::Int– Gauss-Hermite quadrature points for RE/CRE (default 12)
Returns
MarginalEffects{T} with AMEs, delta-method SEs, z-stats, p-values, and CIs.
MacroEconometricModels.odds_ratio — Function
odds_ratio(m::LogitModel{T}; conf_level=0.95) -> NamedTupleCompute odds ratios from a logistic regression model with delta-method CIs.
ORj = exp(betaj). Standard error via delta method: SE(OR) = OR * SE(beta). Confidence intervals on log scale: exp(beta +/- z * SE(beta)).
Arguments
m::LogitModel{T}— estimated logit modelconf_level::Real— confidence level (default 0.95)
Returns
Named tuple with fields:
or::Vector{T}— odds ratios exp(beta)se::Vector{T}— delta-method standard errorsci_lower::Vector{T}— lower CI boundsci_upper::Vector{T}— upper CI boundsvarnames::Vector{String}— variable names
Examples
m = estimate_logit(y, X)
result = odds_ratio(m)
result.or # odds ratios
result.ci_lower # lower 95% CIReferences
- Agresti, A. (2002). Categorical Data Analysis. 2nd ed. Wiley, ch. 5.
Diagnostics
MacroEconometricModels.vif — Function
vif(m::RegModel{T}) -> Vector{T}Compute Variance Inflation Factors for each non-intercept regressor.
VIFj = 1 / (1 - R^2j), where R^2j is the R-squared from regressing xj on all other regressors (excluding the intercept column). A VIF > 10 indicates severe multicollinearity (Belsley, Kuh & Welsch 1980).
Arguments
m::RegModel{T}— estimated OLS/WLS model
Returns
Vector{T} of VIF values, one per non-intercept regressor. The order matches m.varnames with the intercept column removed.
Examples
m = estimate_reg(y, X; varnames=["const", "x1", "x2"])
v = vif(m) # VIF for x1, x2References
- Belsley, D. A., Kuh, E. & Welsch, R. E. (1980). Regression Diagnostics. Wiley.
- Greene, W. H. (2018). Econometric Analysis. 8th ed. Pearson, ch. 4.
MacroEconometricModels.classification_table — Function
classification_table(m::Union{LogitModel{T},ProbitModel{T}}; threshold=0.5) -> Dict{String,Any}Compute a classification table (confusion matrix) and summary metrics for a binary response model.
Arguments
m— estimated LogitModel or ProbitModelthreshold::Real— classification threshold (default 0.5)
Returns
Dict with keys:
"confusion"— 2x2 confusion matrix [[TN, FP], [FN, TP]]"accuracy"— (TP + TN) / N"sensitivity"— TP / (TP + FN) (true positive rate / recall)"specificity"— TN / (TN + FP) (true negative rate)"precision"— TP / (TP + FP) (positive predictive value)"f1_score"— 2 * precision * recall / (precision + recall)"n"— number of observations"threshold"— classification threshold used
Examples
m = estimate_logit(y, X)
ct = classification_table(m)
ct["accuracy"] # overall accuracy
ct["confusion"] # 2x2 confusion matrixReferences
- Agresti, A. (2002). Categorical Data Analysis. 2nd ed. Wiley.
Ordered and Multinomial Models
MacroEconometricModels.estimate_ologit — Function
estimate_ologit(y, X; cov_type=:ols, varnames=nothing, clusters=nothing, maxiter=200, tol=1e-8) -> OrderedLogitModel{T}Estimate an ordered logistic regression model via maximum likelihood (Newton-Raphson).
Model
Cumulative link model: P(y <= j | x) = Logistic(alpha_j - x' beta). X should NOT include an intercept column – it is absorbed into cutpoints.
Arguments
y::AbstractVector– ordinal dependent variable (will be remapped to 1:J)X::AbstractMatrix{T}– regressor matrix (n x K, no intercept)cov_type::Symbol– covariance estimator::ols(MLE),:hc1(sandwich)varnames::Union{Nothing,Vector{String}}– coefficient names (auto-generated if nothing)clusters::Union{Nothing,AbstractVector}– cluster assignments (for:cluster)maxiter::Int– maximum Newton-Raphson iterations (default 200)tol– convergence tolerance (default 1e-8)
Returns
OrderedLogitModel{T} with estimated coefficients, cutpoints, and joint vcov.
Examples
using MacroEconometricModels, Random, Distributions
rng = MersenneTwister(42)
n = 1000
X = randn(rng, n, 2)
xb = X * [1.0, -0.5]
p = 1 ./ (1 .+ exp.(-([0.0 1.5]' .- xb)))
u = rand(rng, n)
y = [u[i] < p[1,i] ? 1 : u[i] < p[2,i] ? 2 : 3 for i in 1:n]
m = estimate_ologit(y, X; varnames=["x1", "x2"])
report(m)References
- McCullagh, P. (1980). JRSS B 42(2), 109-142.
- Agresti, A. (2010). Analysis of Ordinal Categorical Data. 2nd ed. Wiley.
MacroEconometricModels.estimate_oprobit — Function
estimate_oprobit(y, X; cov_type=:ols, varnames=nothing, clusters=nothing, maxiter=200, tol=1e-8) -> OrderedProbitModel{T}Estimate an ordered probit regression model via maximum likelihood (Newton-Raphson).
Model
Cumulative link model: P(y <= j | x) = Phi(alpha_j - x' beta). X should NOT include an intercept column – it is absorbed into cutpoints.
Arguments
Same as estimate_ologit.
Returns
OrderedProbitModel{T} with estimated coefficients, cutpoints, and joint vcov.
Examples
using MacroEconometricModels, Random, Distributions
rng = MersenneTwister(42)
n = 1000
X = randn(rng, n, 2)
xb = X * [0.8, -0.5]
d = Normal()
p = cdf.(d, [0.0 1.0]' .- xb)
u = rand(rng, n)
y = [u[i] < p[1,i] ? 1 : u[i] < p[2,i] ? 2 : 3 for i in 1:n]
m = estimate_oprobit(y, X; varnames=["x1", "x2"])
report(m)References
- McCullagh, P. (1980). JRSS B 42(2), 109-142.
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press.
MacroEconometricModels.estimate_mlogit — Function
estimate_mlogit(y, X; cov_type=:ols, varnames=nothing, clusters=nothing, maxiter=200, tol=1e-8) -> MultinomialLogitModel{T}Estimate a multinomial logistic regression model via maximum likelihood (Newton-Raphson).
Model
Multinomial logit: P(y = j | x) = exp(x' betaj) / sumk exp(x' betak), with beta1 = 0 (base category).
Arguments
y::AbstractVector– categorical dependent variable (will be remapped to 1:J)X::AbstractMatrix{T}– regressor matrix (n x K)cov_type::Symbol– covariance estimator::ols(MLE),:hc0,:hc1(sandwich),:clustervarnames::Union{Nothing,Vector{String}}– coefficient names (auto-generated if nothing)clusters::Union{Nothing,AbstractVector}– cluster assignments (for:cluster)maxiter::Int– maximum Newton-Raphson iterations (default 200)tol– convergence tolerance (default 1e-8)
Returns
MultinomialLogitModel{T} with estimated coefficients and joint vcov.
Examples
using MacroEconometricModels, Random
rng = MersenneTwister(42)
n = 1000
X = [ones(n) randn(rng, n, 2)]
beta_true = [0.5 -0.3; 1.0 -0.5; -0.5 0.8] # K=3 x (J-1)=2
V = X * beta_true
P = exp.(V) ./ (1 .+ sum(exp.(V), dims=2))
# ... generate y from probabilities
m = estimate_mlogit(y, X; varnames=["const", "x1", "x2"])
report(m)References
- McFadden, D. (1974). Conditional logit analysis of qualitative choice behavior.
- Train, K. E. (2009). Discrete Choice Methods with Simulation. 2nd ed. Cambridge Univ. Press.
MacroEconometricModels.brant_test — Function
brant_test(m::OrderedLogitModel{T}) -> NamedTupleBrant test of the proportional odds (parallel regression) assumption for an ordered logit model.
For each cutpoint j = 1,...,J-1, fits a binary logit (y <= j vs y > j). Under H0 (proportional odds), all binary logit coefficients should be equal.
Algorithm
- Fit J-1 binary logits splitting at each cutpoint
- Compute Wald statistic comparing each binary logit's beta to the pooled ordered logit estimate
- Overall test: chi-squared with K*(J-2) degrees of freedom
- Per-variable tests: chi-squared with (J-2) df each
Returns
Named tuple with fields:
statistic::T– overall Wald test statisticpvalue::T– overall p-value (chi-squared)df::Int– degrees of freedom K*(J-2)per_variable::Vector{T}– per-variable p-values (length K)binary_coefs::Matrix{T}– K x (J-1) matrix of binary logit coefficients
References
- Brant, R. (1990). Assessing proportionality in the proportional odds model for ordinal logistic regression. Biometrics 46, 1171-1178.
MacroEconometricModels.hausman_iia — Function
hausman_iia(m::MultinomialLogitModel{T}; omit_category::Int) -> NamedTupleHausman-McFadden test of the Independence of Irrelevant Alternatives (IIA) assumption for a multinomial logit model.
Re-estimates the model excluding observations where y = omit_category, then compares coefficients for the remaining categories with the full model using a Hausman-type statistic.
Arguments
m::MultinomialLogitModel{T}– estimated full multinomial logit modelomit_category::Int– category to omit (1-based index into m.categories)
Returns
Named tuple with fields:
statistic::T– Hausman test statisticpvalue::T– p-value (chi-squared)df::Int– degrees of freedomomitted_category– the omitted category label
References
- Hausman, J. & McFadden, D. (1984). Specification Tests for the Multinomial Logit Model. Econometrica 52(5), 1219-1240.
VAR Estimation
Frequentist Estimation
MacroEconometricModels.estimate_var — Function
estimate_var(Y::AbstractMatrix{T}, p::Int; check_stability::Bool=true) -> VARModel{T}Estimate VAR(p) via OLS: Yₜ = c + A₁Yₜ₋₁ + ... + AₚYₜ₋ₚ + uₜ.
Arguments
Y: Data matrix (T × n)p: Number of lagscheck_stability: If true (default), warns if estimated VAR is non-stationary
Returns
VARModel with estimated coefficients, residuals, covariance matrix, and information criteria.
Estimate VAR from DataFrame. Use vars to select columns.
MacroEconometricModels.select_lag_order — Function
Select optimal lag order via information criterion (:aic, :bic, :hqic).
StatsAPI.vcov — Method
Covariance of vectorized coefficients: Σ ⊗ (X'X)⁻¹.
StatsAPI.predict — Function
StatsAPI.predict(m::RegModel{T}, X_new::AbstractMatrix) -> Vector{T}Predict fitted values for new data from a linear regression model.
Returns X_new * beta.
Arguments
m::RegModel{T}— estimated OLS/WLS/IV modelX_new::AbstractMatrix— new regressor matrix (n_new x k)
Returns
Vector{T} of predicted values.
Examples
m = estimate_reg(y, X)
y_hat = predict(m, X_test)StatsAPI.predict(m::LogitModel{T}, X_new::AbstractMatrix) -> Vector{T}Predict probabilities for new data from a logistic regression model.
Returns 1 / (1 + exp(-X_new * beta)).
Arguments
m::LogitModel{T}— estimated logit modelX_new::AbstractMatrix— new regressor matrix (n_new x k)
Returns
Vector{T} of predicted probabilities in (0, 1).
Examples
m = estimate_logit(y, X)
p_hat = predict(m, X_test)StatsAPI.predict(m::ProbitModel{T}, X_new::AbstractMatrix) -> Vector{T}Predict probabilities for new data from a probit regression model.
Returns Phi(X_new * beta), where Phi is the standard normal CDF.
Arguments
m::ProbitModel{T}— estimated probit modelX_new::AbstractMatrix— new regressor matrix (n_new x k)
Returns
Vector{T} of predicted probabilities in (0, 1).
Examples
m = estimate_probit(y, X)
p_hat = predict(m, X_test)StatsAPI.predict(m::OrderedLogitModel{T}, X_new::AbstractMatrix) -> Matrix{T}Predict category probabilities for new data from an ordered logit model.
Returns an n_new x J probability matrix where each row sums to 1.
StatsAPI.predict(m::OrderedProbitModel{T}, X_new::AbstractMatrix) -> Matrix{T}Predict category probabilities for new data from an ordered probit model.
Returns an n_new x J probability matrix where each row sums to 1.
StatsAPI.predict(m::MultinomialLogitModel{T}, X_new::AbstractMatrix) -> Matrix{T}Predict category probabilities for new data from a multinomial logit model.
Returns an n_new x J probability matrix where each row sums to 1.
In-sample fitted values.
Out-of-sample forecasts for steps periods.
Predicted values: F * Λ'.
Predicted values: F * Λ'.
Predicted values (common component).
predict(model::AbstractARIMAModel, h::Int) -> Vector{T}Return h-step ahead point forecasts (without confidence intervals).
Conditional variance series $\hat{\sigma}^2_t$.
Conditional variance series $\hat{\sigma}^2_t$.
Conditional variance series $\hat{\sigma}^2_t$.
Conditional variance series $\hat{\sigma}^2_t$.
Posterior mean volatility series $\hat{\sigma}^2_t$.
StatsAPI.r2 — Method
R² for each equation.
R² for each variable.
R² for each variable.
R² for each variable.
StatsAPI.confint — Method
Confidence intervals for RegModel coefficients (t-distribution).
Confidence intervals for LogitModel coefficients (normal distribution).
Confidence intervals for ProbitModel coefficients (normal distribution).
Confidence intervals at given level (default 95%).
Confidence intervals for PanelRegModel coefficients (t-distribution).
Confidence intervals for PanelIVModel coefficients (t-distribution).
Confidence intervals for PanelLogitModel coefficients (normal distribution).
Confidence intervals for PanelProbitModel coefficients (normal distribution).
Bayesian Estimation
MacroEconometricModels.estimate_bvar — Function
estimate_bvar(Y, p; n_draws=1000, sampler=:direct, burnin=0, thin=1,
prior=:normal, hyper=nothing) -> BVARPosteriorEstimate Bayesian VAR via conjugate Normal-Inverse-Wishart posterior.
Model
Y = X B + E, E ~ MN(0, Σ, I_T)
Prior: Σ ~ IW(ν₀, S₀), vec(B)|Σ ~ N(b₀, Σ ⊗ V₀)Samplers
:direct(default) — i.i.d. draws from analytical posterior.burninandthinare ignored.:gibbs— Standard two-block Gibbs sampler.burnindefaults to 200 if not specified.
Arguments
Y::AbstractMatrix: T × n data matrixp::Int: Number of lags
Keyword Arguments
n_draws::Int=1000: Number of posterior draws to keepsampler::Symbol=:direct: Sampling algorithm (:director:gibbs)burnin::Int=0: Burnin period (only for:gibbs; defaults to 200 when sampler=:gibbs and burnin=0)thin::Int=1: Thinning interval (only for:gibbs)prior::Symbol=:normal: Prior type (:normalor:minnesota)hyper::Union{Nothing,MinnesotaHyperparameters}=nothing: Minnesota hyperparameters. Whenprior=:minnesotaandhyper=nothing, tau is automatically optimized via marginal likelihood maximization (Giannone, Lenza & Primiceri 2015). Pass an explicitMinnesotaHyperparameters(...)to use fixed values instead.
Returns
BVARPosterior{T} containing coefficient and covariance draws.
Example
Y = randn(200, 3)
post = estimate_bvar(Y, 2; n_draws=1000)
post_mn = estimate_bvar(Y, 2; prior=:minnesota, n_draws=500)MacroEconometricModels.posterior_mean_model — Function
VARModel with posterior mean parameters.
MacroEconometricModels.posterior_median_model — Function
VARModel with posterior median parameters.
VAR/BVAR Forecasting
MacroEconometricModels._compute_level_sigma — Method
Compute level residual covariance Sigma for structural analysis.
MacroEconometricModels._draw_inverse_wishart — Method
Draw from Inverse-Wishart(ν, S) distribution. Uses the Bartlett decomposition: if X ~ W(ν, S⁻¹), then X⁻¹ ~ IW(ν, S).
MacroEconometricModels._estimate_favar_bayesian — Method
_estimate_favar_bayesian(X, Y_key, r, p, n_draws, burnin, pvn, Y_key_indices, aug_varnames) -> BayesianFAVARBayesian FAVAR via Gibbs sampling (Bernanke, Boivin & Eliasz 2005, Section IV).
Algorithm:
- Initialize factors via PCA
- Gibbs sampler iterates:
- Draw (B, Σ) | F, Y_key from the VAR posterior
- Draw Λ | F, X equation-by-equation
- Draw F | Λ, B, Σ, X, Y_key via regression posterior
- Store post-burnin draws
MacroEconometricModels._find_key_indices — Method
_find_key_indices(X, Y_key) -> Vector{Int}Try to identify which columns of X correspond to Y_key by exact column matching. Returns empty vector if no match is found.
MacroEconometricModels._remove_double_counting — Method
_remove_double_counting(F_raw, Y_key) -> Matrix{T}Remove the component of Fraw that is spanned by Ykey (BBE 2005 Step 2).
For each factor column, regress it on Y_key via OLS and keep the residual. This yields "slow-moving" factors that are orthogonal to the key variables.
MacroEconometricModels._sample_direct — Method
Draw i.i.d. samples from the conjugate Normal-Inverse-Wishart posterior.
MacroEconometricModels._sample_gibbs — Method
Two-block Gibbs sampler for Normal-Inverse-Wishart posterior.
MacroEconometricModels._windmeijer_correct — Method
Windmeijer (2005) finite-sample correction for equation eq.
MacroEconometricModels.estimate_bvar — Method
estimate_bvar(Y, p; n_draws=1000, sampler=:direct, burnin=0, thin=1,
prior=:normal, hyper=nothing) -> BVARPosteriorEstimate Bayesian VAR via conjugate Normal-Inverse-Wishart posterior.
Model
Y = X B + E, E ~ MN(0, Σ, I_T)
Prior: Σ ~ IW(ν₀, S₀), vec(B)|Σ ~ N(b₀, Σ ⊗ V₀)Samplers
:direct(default) — i.i.d. draws from analytical posterior.burninandthinare ignored.:gibbs— Standard two-block Gibbs sampler.burnindefaults to 200 if not specified.
Arguments
Y::AbstractMatrix: T × n data matrixp::Int: Number of lags
Keyword Arguments
n_draws::Int=1000: Number of posterior draws to keepsampler::Symbol=:direct: Sampling algorithm (:director:gibbs)burnin::Int=0: Burnin period (only for:gibbs; defaults to 200 when sampler=:gibbs and burnin=0)thin::Int=1: Thinning interval (only for:gibbs)prior::Symbol=:normal: Prior type (:normalor:minnesota)hyper::Union{Nothing,MinnesotaHyperparameters}=nothing: Minnesota hyperparameters. Whenprior=:minnesotaandhyper=nothing, tau is automatically optimized via marginal likelihood maximization (Giannone, Lenza & Primiceri 2015). Pass an explicitMinnesotaHyperparameters(...)to use fixed values instead.
Returns
BVARPosterior{T} containing coefficient and covariance draws.
Example
Y = randn(200, 3)
post = estimate_bvar(Y, 2; n_draws=1000)
post_mn = estimate_bvar(Y, 2; prior=:minnesota, n_draws=500)MacroEconometricModels.estimate_favar — Method
estimate_favar(X, Y_key, r, p; method=:two_step, panel_varnames=nothing) -> FAVARModel
estimate_favar(X, key_indices::Vector{Int}, r, p; ...) -> FAVARModelEstimate a Factor-Augmented VAR (Bernanke, Boivin & Eliasz, 2005).
Two-Step Algorithm (BBE 2005)
- Extract
rfactors from panelXvia PCA (estimate_factors) - Remove double-counting: regress each factor on
Y_key, use residuals as slow-moving factorsF_tilde - Estimate VAR(p) on augmented system
[F_tilde, Y_key]
Arguments
X: Panel data matrix (T x N) — large cross-section of macroeconomic variablesY_key: Key observed variables (T x n_key) or column indices into Xr: Number of latent factors to extractp: VAR lag order
Keyword Arguments
method::Symbol=:two_step: Estimation method (currently only:two_step)panel_varnames::Union{Nothing, Vector{String}}=nothing: Names for the N panel variablesn_draws::Int=5000: Number of posterior draws (for Bayesian, reserved for future use)burnin::Int=1000: Burn-in draws (for Bayesian, reserved for future use)
Returns
FAVARModel{T} with estimated VAR on [Ftilde, Ykey], factor loadings, and panel variable metadata for panel-wide IRF mapping.
Example
X = randn(200, 50) # 200 obs, 50 variables
Y_key = X[:, [1, 5]] # 2 key variables
favar = estimate_favar(X, Y_key, 3, 2)
# Or using column indices:
favar = estimate_favar(X, [1, 5], 3, 2)
# IRFs (via to_var delegation):
irf_result = irf(favar, 20)
# Panel-wide IRFs (all 50 variables):
panel_irfs = favar_panel_irf(favar, irf_result)MacroEconometricModels.estimate_favar — Method
estimate_favar(X, key_indices::Vector{Int}, r, p; kwargs...) -> FAVARModel or BayesianFAVAREstimate FAVAR where key variables are specified as column indices of X.
MacroEconometricModels.estimate_pvar — Method
estimate_pvar(d::PanelData{T}, p::Int; kwargs...) -> PVARModel{T}Estimate Panel VAR(p) via GMM.
Arguments
d::PanelData{T}— balanced panel data (usextsetto construct)p::Int— number of lags
Keyword Arguments
dependent_vars::Union{Vector{String},Nothing}=nothing— endogenous variable names (default: all)predet_vars::Vector{String}=String[]— predetermined variable namesexog_vars::Vector{String}=String[]— strictly exogenous variable namestransformation::Symbol=:fd—:fd(first-difference) or:fod(forward orthogonal deviations)steps::Symbol=:twostep—:onestep,:twostep, or:mstep(iterated)system_instruments::Bool=false— if true, use System GMM (Blundell-Bond)system_constant::Bool=true— include constant in level equation (System GMM)min_lag_endo::Int=2— minimum instrument lag for endogenous variablesmax_lag_endo::Int=99— maximum instrument lag (99 = all available)collapse::Bool=false— collapse instruments to limit proliferationpca_instruments::Bool=false— apply PCA reduction to instrumentspca_max_components::Int=0— max PCA components (0 = auto)max_iter::Int=100— max iterations for iterated GMM
Returns
PVARModel{T}with coefficient estimates, robust standard errors, and GMM internals
References
- Arellano, M. & Bond, S. (1991). Review of Economic Studies 58(2), 277-297.
- Blundell, R. & Bond, S. (1998). Journal of Econometrics 87(1), 115-143.
- Windmeijer, F. (2005). Journal of Econometrics 126(1), 25-51.
Examples
pd = xtset(df, :id, :time)
model = estimate_pvar(pd, 2; steps=:twostep)
model = estimate_pvar(pd, 1; system_instruments=true, steps=:twostep)MacroEconometricModels.estimate_pvar_feols — Method
estimate_pvar_feols(d::PanelData{T}, p::Int; kwargs...) -> PVARModel{T}Estimate Panel VAR(p) via Fixed Effects OLS (within estimator).
Simpler than GMM but subject to Nickell (1981) bias when T is small relative to N. Uses within-group demeaning to remove fixed effects, then pooled OLS with cluster-robust standard errors.
Arguments
d::PanelData{T}— panel datap::Int— number of lags
Keyword Arguments
dependent_vars::Union{Vector{String},Nothing}=nothing— endogenous variable namespredet_vars::Vector{String}=String[]— predetermined variable namesexog_vars::Vector{String}=String[]— strictly exogenous variable names
Examples
pd = xtset(df, :id, :time)
model = estimate_pvar_feols(pd, 2)MacroEconometricModels.estimate_var — Method
Estimate VAR from DataFrame. Use vars to select columns.
MacroEconometricModels.estimate_var — Method
estimate_var(Y::AbstractMatrix{T}, p::Int; check_stability::Bool=true) -> VARModel{T}Estimate VAR(p) via OLS: Yₜ = c + A₁Yₜ₋₁ + ... + AₚYₜ₋ₚ + uₜ.
Arguments
Y: Data matrix (T × n)p: Number of lagscheck_stability: If true (default), warns if estimated VAR is non-stationary
Returns
VARModel with estimated coefficients, residuals, covariance matrix, and information criteria.
MacroEconometricModels.extract_chain_parameters — Method
extract_chain_parameters(post::BVARPosterior) -> (b_vecs, sigmas)Extract coefficient vectors and covariance matrices from posterior draws. Returns matrices compatible with downstream parameters_to_model calls.
b_vecs: n_draws × (k*n) matrix of vectorized coefficientssigmas: n_draws × (n*n) matrix of vectorized covariance matrices
MacroEconometricModels.forecast — Method
forecast(post::BVARPosterior, h; reps=nothing, conf_level=0.95, point_estimate=:mean) -> BVARForecast{T}Forecast from Bayesian VAR using posterior draws.
For each posterior draw, iterates the VAR recursion forward h steps. Returns posterior mean forecast with credible intervals from the distribution of forecast paths across draws.
Arguments
post: BVAR posteriorh: Forecast horizon
Keyword Arguments
reps: Number of posterior draws to use (default: all)conf_level: Credible interval level (default: 0.95)point_estimate::mean(default) or:medianfor central tendency
Returns
BVARForecast{T} with posterior mean forecast and credible intervals.
Example
post = estimate_bvar(Y, 4; n_draws=1000)
fc = forecast(post, 12)MacroEconometricModels.forecast — Method
forecast(model::VARModel, h; ci_method=:bootstrap, reps=500, conf_level=0.95) -> VARForecast{T}Forecast from VAR model for h steps ahead with optional bootstrap CIs.
Iterates the VAR recursion forward using the estimated coefficients and the last p observations as initial conditions.
Arguments
model: Estimated VAR modelh: Forecast horizon (number of steps ahead)ci_method::bootstrap(default) or:nonereps: Number of bootstrap replications (default 500)conf_level: Confidence level for intervals (default 0.95)
Returns
VARForecast{T} with point forecasts and CIs.
Example
model = estimate_var(Y, 4)
fc = forecast(model, 12) # 12-step ahead forecast with bootstrap CIsMacroEconometricModels.parameters_to_model — Method
Convert chain parameters to VARModel. Provide data for residual computation.
MacroEconometricModels.posterior_mean_model — Method
VARModel with posterior mean parameters.
MacroEconometricModels.posterior_median_model — Method
VARModel with posterior median parameters.
MacroEconometricModels.select_lag_order — Method
Select optimal lag order via information criterion (:aic, :bic, :hqic).
StatsAPI.confint — Method
Confidence intervals at given level (default 95%).
StatsAPI.loglikelihood — Method
Gaussian log-likelihood.
StatsAPI.predict — Method
In-sample fitted values.
StatsAPI.predict — Method
Out-of-sample forecasts for steps periods.
StatsAPI.r2 — Method
R² for each equation.
StatsAPI.vcov — Method
Covariance of vectorized coefficients: Σ ⊗ (X'X)⁻¹.
Forecast Accessors
MacroEconometricModels.point_forecast — Function
point_forecast(f::AbstractForecastResult)Return the point forecast values (Vector or Matrix).
Most subtypes store the point forecast in a .forecast field; this default accessor returns that field. Overrides exist for VECMForecast (.levels) and FactorForecast (.observables).
MacroEconometricModels.forecast_horizon — Function
forecast_horizon(f::AbstractForecastResult)Return the forecast horizon (number of steps ahead).
MacroEconometricModels.lower_bound — Function
lower_bound(f::AbstractForecastResult)Return the lower confidence interval bound.
Most subtypes store this in .ci_lower; an override exists for FactorForecast (.observables_lower).
MacroEconometricModels.upper_bound — Function
upper_bound(f::AbstractForecastResult)Return the upper confidence interval bound.
Most subtypes store this in .ci_upper; an override exists for FactorForecast (.observables_upper).
Prior Specification
MacroEconometricModels.gen_dummy_obs — Method
gen_dummy_obs(Y, p, hyper) -> (Y_dummy, X_dummy)Generate Minnesota prior dummy observations. Hyperparameters: tau (tightness), decay, lambda (sum-of-coef), mu (co-persistence), omega.
MacroEconometricModels.log_marginal_likelihood — Method
log_marginal_likelihood(Y, p, hyper) -> TClosed-form log marginal likelihood for BVAR with Minnesota prior.
MacroEconometricModels.optimize_hyperparameters — Method
Optimize tau via grid search on marginal likelihood.
MacroEconometricModels.optimize_hyperparameters_full — Method
Full grid search over tau, lambda, mu.
VECM Estimation
MacroEconometricModels.estimate_vecm — Function
estimate_vecm(Y, p; rank=:auto, deterministic=:constant, method=:johansen, significance=0.05)Estimate a Vector Error Correction Model.
Arguments
Y: Data matrix (T × n) in levelsp: Underlying VAR order (VECM has p-1 lagged differences)rank: Cointegrating rank;:auto(default) selects via Johansen trace test, or specify an integerdeterministic::none,:constant(default), or:trendmethod::johansen(default) or:engle_granger(bivariate, rank=1 only)significance: Significance level for automatic rank selection (default 0.05)
Returns
VECMModel with estimated α, β, Γ matrices, residuals, and diagnostics.
Example
Y = cumsum(randn(200, 3), dims=1)
Y[:, 2] = Y[:, 1] + 0.1 * randn(200)
m = estimate_vecm(Y, 2)MacroEconometricModels.to_var — Function
to_var(vecm::VECMModel) -> VARModelConvert VECM to VAR in levels representation.
The VECM: ΔYₜ = ΠYₜ₋₁ + Σᵢ ΓᵢΔYₜ₋ᵢ + μ + uₜ maps to VAR: Yₜ = c + A₁Yₜ₋₁ + ... + AₚYₜ₋ₚ + uₜ
with:
- A₁ = Π + Iₙ + Γ₁
- Aᵢ = Γᵢ - Γᵢ₋₁ for i = 2, ..., p-1
- Aₚ = -Γₚ₋₁
to_var(favar::FAVARModel) -> VARModelConvert a FAVAR to a standard VARModel for use with irf, fevd, historical_decomposition, and other structural analysis methods.
This follows the same delegation pattern as to_var(vecm::VECMModel).
MacroEconometricModels.select_vecm_rank — Function
select_vecm_rank(Y, p; criterion=:trace, significance=0.05) -> IntSelect cointegrating rank using the Johansen trace or max-eigenvalue test.
MacroEconometricModels.cointegrating_rank — Function
cointegrating_rank(m::VECMModel) -> IntReturn the cointegrating rank r of the VECM.
MacroEconometricModels.granger_causality_vecm — Function
granger_causality_vecm(vecm, cause, effect) -> VECMGrangerResultTest Granger causality from variable cause to variable effect in a VECM.
Three tests are computed:
- Short-run: Wald test on Γ coefficients of the
causevariable in theeffectequation - Long-run: Wald test on α coefficients in the
effectequation (error correction channel) - Strong: Joint test of both short-run and long-run
Arguments
vecm: EstimatedVECMModelcause: Index of the causing variableeffect: Index of the effect variable
Returns
VECMGrangerResult with test statistics, p-values, and degrees of freedom.
VECM Analysis and Forecasting
MacroEconometricModels.fevd — Method
fevd(vecm::VECMModel, horizon; kwargs...) -> FEVDCompute FEVD for a VECM by converting to VAR representation.
MacroEconometricModels.historical_decomposition — Method
historical_decomposition(vecm::VECMModel, horizon; kwargs...) -> HistoricalDecompositionCompute historical decomposition for a VECM by converting to VAR representation.
MacroEconometricModels.irf — Method
irf(vecm::VECMModel, horizon; kwargs...) -> ImpulseResponseCompute IRFs for a VECM by converting to VAR representation. All identification methods (Cholesky, sign, narrative, etc.) are supported.
MacroEconometricModels.forecast — Method
forecast(vecm::VECMModel, h; ci_method=:none, reps=500, conf_level=0.95) -> VECMForecastForecast from a VECM by iterating the VECM equations in levels.
Unlike VAR forecasting, this preserves the cointegrating relationships in the forecast path.
Arguments
vecm: Estimated VECMh: Forecast horizonci_method::none(default),:bootstrap, or:simulationreps: Number of bootstrap/simulation replications (default 500)conf_level: Confidence level (default 0.95)
Returns
VECMForecast with level and difference forecasts, plus CIs if requested.
Structural Identification
MacroEconometricModels.compute_Q — Method
compute_Q(model, method, horizon, check_func, narrative_check;
max_draws=100, transition_var=nothing, regime_indicator=nothing)Compute identification matrix Q for structural VAR analysis.
Methods
:cholesky— Cholesky decomposition (recursive ordering):sign— Sign restrictions (requirescheck_func):narrative— Narrative restrictions (requirescheck_funcandnarrative_check):long_run— Long-run restrictions (Blanchard-Quah):fastica— FastICA (Hyvärinen 1999):jade— JADE (Cardoso 1999):sobi— SOBI (Belouchrani et al. 1997):dcov— Distance covariance ICA (Matteson & Tsay 2017):hsic— HSIC independence ICA (Gretton et al. 2005):student_t— Student-t ML (Lanne et al. 2017):mixture_normal— Mixture of normals ML (Lanne et al. 2017):pml— Pseudo-ML (Gouriéroux et al. 2017):skew_normal— Skew-normal ML (Lanne & Luoto 2020):nongaussian_ml— Unified non-Gaussian ML dispatcher (default: Student-t):markov_switching— Markov-switching heteroskedasticity (Lütkepohl & Netšunajev 2017):garch— GARCH-based heteroskedasticity (Normandin & Phaneuf 2004):smooth_transition— Smooth-transition heteroskedasticity (requirestransition_var):external_volatility— External volatility regimes (requiresregime_indicator)
Keyword Arguments
max_draws::Int=100: Maximum draws for sign/narrative identificationtransition_var::Union{Nothing,AbstractVector}=nothing: Transition variable for:smooth_transitionregime_indicator::Union{Nothing,AbstractVector{Int}}=nothing: Regime indicator for:external_volatility
MacroEconometricModels.compute_irf — Method
compute_irf(model, Q, horizon) -> Array{T,3}Compute IRFs for rotation matrix Q. Returns (horizon × n × n) array. IRF[h, i, j] = response of variable i to shock j at horizon h-1.
MacroEconometricModels.compute_structural_shocks — Method
Compute structural shocks: εₜ = Q'L⁻¹uₜ.
MacroEconometricModels.generate_Q — Method
Generate random orthogonal matrix via QR decomposition (Haar measure).
MacroEconometricModels.identify_cholesky — Method
Identify via Cholesky decomposition (recursive ordering). Returns L where Σ = LL'.
MacroEconometricModels.identify_long_run — Method
Identify via long-run restrictions: long-run cumulative impact matrix is lower triangular.
MacroEconometricModels.identify_narrative — Method
identify_narrative(model, horizon, sign_check, narrative_check; max_draws=1000)Combine sign and narrative restrictions. Returns (Q, irf, shocks).
MacroEconometricModels.identify_sign — Method
identify_sign(model, horizon, check_func; max_draws=1000, store_all=false)Find Q satisfying sign restrictions via random draws.
With store_all=false (default), returns (Q, irf) — the first valid rotation. With store_all=true, returns a SignIdentifiedSet containing ALL accepted rotations and their IRFs (Baumeister & Hamilton, 2015).
MacroEconometricModels.irf_bounds — Method
irf_bounds(s::SignIdentifiedSet{T}; quantiles=[0.16, 0.84]) -> (lower, upper)Compute pointwise bounds (or quantile bands) over the identified set.
MacroEconometricModels.irf_median — Method
irf_median(s::SignIdentifiedSet{T}) -> Array{T,3}Compute pointwise median IRF over the identified set.
Arias et al. (2018) Sign/Zero Restrictions
MacroEconometricModels.identify_arias — Function
identify_arias(model, restrictions, horizon; n_draws=1000, n_rotations=1000, compute_weights=true) -> AriasSVARResultIdentify SVAR using Arias et al. (2018) with zero and sign restrictions.
Uses importance sampling with draw-dependent weights (Proposition 4) for zero+sign restriction combinations. For pure sign restrictions, draws uniformly from O(n) with unit weights.
Keywords
n_draws::Int=1000: Target number of accepted drawsn_rotations::Int=1000: Maximum attempts per target drawcompute_weights::Bool=true: Compute importance weights (set false for faster exploratory analysis)
MacroEconometricModels.identify_arias_bayesian — Function
identify_arias_bayesian(post::BVARPosterior, restrictions, horizon; data=nothing, n_rotations=100, quantiles=[0.16,0.5,0.84], compute_weights=true)Apply Arias identification to each posterior draw. Returns IRF quantiles, mean, acceptance rates.
Creates the _AriasSVARSetup once (W matrices fixed across all posterior draws) for consistency.
MacroEconometricModels.zero_restriction — Function
Create zero restriction: variable doesn't respond to shock at horizon.
MacroEconometricModels.sign_restriction — Function
Create sign restriction: variable response has given sign (:positive/:negative) at horizon.
Sign-Identified Set
MacroEconometricModels.irf_bounds — Function
irf_bounds(s::SignIdentifiedSet{T}; quantiles=[0.16, 0.84]) -> (lower, upper)Compute pointwise bounds (or quantile bands) over the identified set.
MacroEconometricModels.irf_median — Function
irf_median(s::SignIdentifiedSet{T}) -> Array{T,3}Compute pointwise median IRF over the identified set.
MacroEconometricModels.irf_mean — Function
Compute weighted mean IRF from AriasSVARResult.
MacroEconometricModels.irf_percentiles — Function
Compute weighted IRF percentiles from AriasSVARResult.
Mountford-Uhlig (2009) Penalty Function
MacroEconometricModels.identify_uhlig — Function
identify_uhlig(model::VARModel{T}, restrictions::SVARRestrictions, horizon::Int;
n_starts=50, n_refine=10, max_iter_coarse=500, max_iter_fine=2000,
tol_coarse=1e-4, tol_fine=1e-8) -> UhligSVARResult{T}Identify SVAR using Mountford & Uhlig (2009) penalty function approach.
Uses Nelder-Mead optimization over spherical coordinates to find the rotation matrix $Q$ that best satisfies sign restrictions, with zero restrictions enforced as hard constraints via null-space projection.
Algorithm
- Precompute MA coefficients and Cholesky factor $L$
- Phase 1 (coarse):
n_startsNelder-Mead runs from random $\theta_0 \in [0, 2\pi]$ - Phase 2 (refinement):
n_refinelocal re-optimizations from best solution - Build final $Q$, compute IRFs, check convergence
Keywords
n_starts::Int=50: Number of random starting points (Phase 1)n_refine::Int=10: Number of local refinements (Phase 2)max_iter_coarse::Int=500: Max iterations per Phase 1 runmax_iter_fine::Int=2000: Max iterations per Phase 2 runtol_coarse::T=1e-4: Convergence tolerance for Phase 1tol_fine::T=1e-8: Convergence tolerance for Phase 2
Returns
UhligSVARResult{T} with optimal rotation matrix, IRFs, penalty values, and convergence indicator.
Example
model = estimate_var(Y, 2)
restrictions = SVARRestrictions(3;
zeros = [zero_restriction(3, 1)],
signs = [sign_restriction(1, 1, :positive),
sign_restriction(2, 1, :positive)]
)
result = identify_uhlig(model, restrictions, 20)Reference: Mountford & Uhlig (2009)
Innovation Accounting
Impulse Response Functions
MacroEconometricModels._simulate_irfs — Method
Simulate IRFs for confidence intervals (bootstrap or asymptotic).
MacroEconometricModels._simulate_var — Method
Simulate VAR data from initial conditions and innovations.
MacroEconometricModels.cumulative_irf — Method
cumulative_irf(irf_result::BayesianImpulseResponse{T}) -> BayesianImpulseResponse{T}Compute cumulative Bayesian impulse response: Σₛ₌₀ʰ IRF_s.
When raw posterior draws are available, cumulates each draw first then extracts quantiles — the statistically correct approach.
MacroEconometricModels.cumulative_irf — Method
cumulative_irf(irf_result::ImpulseResponse{T}) -> ImpulseResponse{T}Compute cumulative impulse response for VAR models: Σₛ₌₀ʰ IRF_s.
When raw bootstrap/simulation draws are available, cumulates each draw first then extracts quantiles — the statistically correct approach since quantiles are NOT additive: Qα(A+B) ≠ Qα(A) + Q_α(B).
MacroEconometricModels.cumulative_irf — Method
cumulative_irf(irf::LPImpulseResponse{T}) -> LPImpulseResponse{T}Compute cumulative impulse response: Σₛ₌₀ʰ β_s.
MacroEconometricModels.irf — Method
irf(post::BVARPosterior, horizon; method=:cholesky, quantiles=[0.16, 0.5, 0.84], point_estimate=:mean, ...)Compute Bayesian IRFs from posterior draws with posterior quantiles. Uses posterior mean as central tendency by default (pass point_estimate=:median for median).
Methods
:cholesky, :sign, :narrative, :long_run, :fastica, :jade, :sobi, :dcov, :hsic, :student_t, :mixture_normal, :pml, :skew_normal, :nongaussian_ml, :markov_switching, :garch, :smooth_transition, :external_volatility
Note: :smooth_transition requires transition_var kwarg. :external_volatility requires regime_indicator kwarg.
Uses process_posterior_samples and compute_posterior_quantiles from bayesian_utils.jl.
MacroEconometricModels.irf — Method
irf(slp::StructuralLP) -> ImpulseResponseExtract the impulse response object from a structural LP result.
MacroEconometricModels.irf — Method
irf(model, horizon; method=:cholesky, ci_type=:none, reps=200, conf_level=0.95, ...)Compute IRFs with optional confidence intervals.
Methods
:cholesky, :sign, :narrative, :long_run, :fastica, :jade, :sobi, :dcov, :hsic, :student_t, :mixture_normal, :pml, :skew_normal, :nongaussian_ml, :markov_switching, :garch, :smooth_transition, :external_volatility
Note: :smooth_transition requires transition_var kwarg. :external_volatility requires regime_indicator kwarg.
CI types
:none, :bootstrap, :theoretical
MacroEconometricModels.lp_irf — Method
lp_irf(Y::AbstractMatrix, shock_var::Int, horizon::Int; kwargs...) -> LPImpulseResponseConvenience function: estimate LP and extract IRF in one call.
MacroEconometricModels.lp_irf — Method
lp_irf(model::LPModel{T}; conf_level::Real=0.95) -> LPImpulseResponse{T}Extract impulse response function with confidence intervals from LP model.
Forecast Error Variance Decomposition
MacroEconometricModels._compute_fevd — Method
Compute FEVD from IRF array: decomposition[i,j,h] = cumulative MSE contribution.
MacroEconometricModels.fevd — Method
fevd(model, horizon; method=:cholesky, ...) -> FEVDCompute FEVD showing proportion of h-step forecast error variance attributable to each shock.
Methods
:cholesky, :sign, :narrative, :long_run, :fastica, :jade, :sobi, :dcov, :hsic, :student_t, :mixture_normal, :pml, :skew_normal, :nongaussian_ml, :markov_switching, :garch, :smooth_transition, :external_volatility
Note: :smooth_transition requires transition_var kwarg. :external_volatility requires regime_indicator kwarg.
Historical Decomposition
MacroEconometricModels._compute_hd_contributions — Method
Compute historical decomposition contributions from structural shocks and MA coefficients. HD[t, i, j] = Σ{s=0}^{t-1} Θs[i, j] * ε_j(t-s)
MacroEconometricModels._compute_initial_conditions — Method
Compute initial conditions as residual: actual - total shock contributions.
MacroEconometricModels._compute_structural_ma_coefficients — Method
Compute structural MA coefficients Θs = Φs * P for s = 0, ..., horizon-1. Returns Vector{Matrix{T}} of length horizon.
Uses _compute_ma_coefficients from identification.jl to avoid code duplication.
MacroEconometricModels.contribution — Method
contribution(hd::BayesianHistoricalDecomposition, var, shock; stat=:mean) -> VectorGet contribution time series for specific variable and shock (Bayesian).
Arguments
hd: Bayesian historical decomposition resultvar: Variable index (Int) or name (String)shock: Shock index (Int) or name (String)stat::meanor quantile index (Int)
MacroEconometricModels.contribution — Method
contribution(hd::HistoricalDecomposition, var, shock) -> VectorGet contribution time series for specific variable and shock.
Arguments
hd: Historical decomposition resultvar: Variable index (Int) or name (String)shock: Shock index (Int) or name (String)
Example
contrib_y1_s1 = contribution(hd, 1, 1) # Contribution of shock 1 to variable 1
contrib_y1_s1 = contribution(hd, "Var 1", "Shock 1")MacroEconometricModels.historical_decomposition — Function
historical_decomposition(post::BVARPosterior, horizon; data=..., ...) -> BayesianHistoricalDecompositionCompute Bayesian historical decomposition from posterior draws with posterior quantiles.
Arguments
post::BVARPosterior: Posterior draws fromestimate_bvarhorizon::Int: Maximum horizon for MA coefficients
Keyword Arguments
data::AbstractMatrix: Override data matrix (defaults topost.data)method::Symbol=:cholesky: Identification methodquantiles::Vector{<:Real}=[0.16, 0.5, 0.84]: Posterior quantile levelscheck_func=nothing: Sign restriction check functionnarrative_check=nothing: Narrative restriction check functiontransition_var=nothing: Transition variable (for method=:smooth_transition)regime_indicator=nothing: Regime indicator (for method=:external_volatility)
Methods
:cholesky, :sign, :narrative, :long_run, :fastica, :jade, :sobi, :dcov, :hsic, :student_t, :mixture_normal, :pml, :skew_normal, :nongaussian_ml, :markov_switching, :garch, :smooth_transition, :external_volatility
Note: :smooth_transition requires transition_var kwarg. :external_volatility requires regime_indicator kwarg.
Returns
BayesianHistoricalDecomposition with posterior quantiles and means.
Example
post = estimate_bvar(Y, 2; n_draws=500)
hd = historical_decomposition(post, 198)MacroEconometricModels.historical_decomposition — Method
historical_decomposition(slp::StructuralLP{T}, T_hd::Int) -> HistoricalDecomposition{T}Compute historical decomposition from structural LP.
Uses LP-estimated IRFs as the structural MA coefficients Θ_h and the structural shocks from the underlying VAR identification.
Arguments
slp: Structural LP resultT_hd: Number of time periods for decomposition (≤ T_eff of underlying VAR)
Returns
HistoricalDecomposition{T} with contributions, initial conditions, and actual data.
MacroEconometricModels.historical_decomposition — Method
historical_decomposition(model::VARModel, restrictions::SVARRestrictions, horizon; ...) -> BayesianHistoricalDecompositionCompute historical decomposition using Arias et al. (2018) identification with importance weights.
Arguments
model::VARModel: Estimated VAR modelrestrictions::SVARRestrictions: Zero and sign restrictionshorizon::Int: Maximum horizon for MA coefficients
Keyword Arguments
n_draws::Int=1000: Number of accepted drawsn_rotations::Int=1000: Maximum rotation attempts per drawquantiles::Vector{<:Real}=[0.16, 0.5, 0.84]: Quantile levels for weighted quantiles
Returns
BayesianHistoricalDecomposition with weighted posterior quantiles and means.
Example
r = SVARRestrictions(3; signs=[sign_restriction(1, 1, :positive)])
hd = historical_decomposition(model, r, 198; n_draws=500)MacroEconometricModels.historical_decomposition — Method
historical_decomposition(model::VARModel, horizon; method=:cholesky, ...) -> HistoricalDecompositionCompute historical decomposition for a VAR model.
Decomposes observed data into contributions from each structural shock plus initial conditions.
Arguments
model::VARModel: Estimated VAR modelhorizon::Int: Maximum horizon for MA coefficient computation (typically T_eff)
Keyword Arguments
method::Symbol=:cholesky: Identification methodcheck_func=nothing: Sign restriction check function (for method=:sign or :narrative)narrative_check=nothing: Narrative restriction check function (for method=:narrative)max_draws::Int=1000: Maximum draws for sign/narrative identificationtransition_var=nothing: Transition variable (for method=:smooth_transition)regime_indicator=nothing: Regime indicator (for method=:external_volatility)
Methods
:cholesky, :sign, :narrative, :long_run, :fastica, :jade, :sobi, :dcov, :hsic, :student_t, :mixture_normal, :pml, :skew_normal, :nongaussian_ml, :markov_switching, :garch, :smooth_transition, :external_volatility
Note: :smooth_transition requires transition_var kwarg. :external_volatility requires regime_indicator kwarg.
Returns
HistoricalDecomposition containing:
contributions: Shock contributions (Teff × nvars × n_shocks)initial_conditions: Initial condition effects (Teff × nvars)actual: Actual data valuesshocks: Structural shocks
Example
model = estimate_var(Y, 2)
hd = historical_decomposition(model, size(Y, 1) - 2)
verify_decomposition(hd) # Check decomposition identityMacroEconometricModels.total_shock_contribution — Method
total_shock_contribution(hd::AbstractHistoricalDecomposition, var) -> VectorGet total contribution from all shocks to a variable over time.
MacroEconometricModels.verify_decomposition — Method
verify_decomposition(hd::BayesianHistoricalDecomposition; tol=1e-6) -> BoolVerify that mean contributions + mean initial_conditions ≈ actual (approximately, due to averaging).
MacroEconometricModels.verify_decomposition — Method
verify_decomposition(hd::HistoricalDecomposition; tol=1e-10) -> BoolVerify that contributions + initial_conditions ≈ actual.
Example
hd = historical_decomposition(model, horizon)
@assert verify_decomposition(hd) "Decomposition identity failed"Summary Tables
MacroEconometricModels.has_uncertainty — Method
has_uncertainty(result::AbstractAnalysisResult) -> BoolCheck if the result includes uncertainty quantification (confidence intervals or posterior quantiles).
MacroEconometricModels.point_estimate — Method
point_estimate(result::AbstractAnalysisResult)Get the point estimate from an analysis result.
Returns the main values/estimates (IRF values, FEVD proportions, HD contributions).
MacroEconometricModels.report — Method
report(post::BVARPosterior)Print comprehensive Bayesian VAR posterior summary.
MacroEconometricModels.report — Method
report(r::BaxterKingResult)Print Baxter-King band-pass filter summary.
MacroEconometricModels.report — Method
report(r::BeveridgeNelsonResult)Print Beveridge-Nelson decomposition summary.
MacroEconometricModels.report — Method
report(r::BoostedHPResult)Print boosted HP filter summary.
MacroEconometricModels.report — Method
report(f::FEVD)
report(f::BayesianFEVD)Print FEVD summary with decomposition at selected horizons.
MacroEconometricModels.report — Method
report(r::HPFilterResult)Print HP filter summary.
MacroEconometricModels.report — Method
report(r::HamiltonFilterResult)Print Hamilton filter summary.
MacroEconometricModels.report — Method
report(hd::HistoricalDecomposition)
report(hd::BayesianHistoricalDecomposition)Print HD summary with contribution statistics.
MacroEconometricModels.report — Method
report(irf::ImpulseResponse)
report(irf::BayesianImpulseResponse)Print IRF summary with values at selected horizons.
MacroEconometricModels.report — Method
report(f::VECMForecast)Print VECM forecast summary.
MacroEconometricModels.report — Method
report(g::VECMGrangerResult)Print VECM Granger causality test results.
MacroEconometricModels.report — Method
report(model::VARModel)Print comprehensive VAR model summary including specification, per-equation coefficient estimates with standard errors and significance, information criteria, residual covariance, and stationarity check.
MacroEconometricModels.report — Method
report(vecm::VECMModel)Print comprehensive VECM summary including cointegrating vectors, adjustment coefficients, short-run dynamics, and diagnostics.
MacroEconometricModels.uncertainty_bounds — Method
uncertainty_bounds(result::AbstractAnalysisResult) -> Union{Nothing, Tuple}Get uncertainty bounds (lower, upper) if available, otherwise nothing.
Local Projections
Core LP Estimation and Covariance
MacroEconometricModels._block_bootstrap — Method
Generate a block bootstrap sample from matrix Y.
MacroEconometricModels._build_structural_lp_arrays — Method
Extract 3D IRF, SE, and analytical CI arrays from per-shock LP models.
MacroEconometricModels._lp_predict_at_horizon — Method
_lp_predict_at_horizon(Y, response_vars, residuals_h, T_eff_h, h)Reconstruct fitted values at horizon h via Yh − residualsh identity.
MacroEconometricModels._lp_robust_vcov — Method
_lp_robust_vcov(X_h, U_h, cov_estimator, h)Horizon-aware robust variance-covariance for LP regressions.
LP residuals at horizon h have MA(h-1) serial correlation (Jordà 2005), so the Newey-West bandwidth must be at least h+1. When automatic bandwidth selection (bandwidth == 0) yields a smaller value, this function enforces the floor max(m̂_NW, h+1).
For non-NW estimators (White, Driscoll-Kraay), falls through to the standard compute_block_robust_vcov.
MacroEconometricModels._structural_lp_bootstrap — Method
Block bootstrap for structural LP confidence intervals.
MacroEconometricModels.build_control_columns! — Method
build_control_columns!(X_h::AbstractMatrix{T}, Y::AbstractMatrix{T},
t_start::Int, t_end::Int, lags::Int, start_col::Int) where TFill control (lagged Y) columns into regressor matrix X_h. Returns the next available column index.
MacroEconometricModels.build_response_matrix — Method
build_response_matrix(Y::AbstractMatrix{T}, h::Int, t_start::Int, t_end::Int,
response_vars::Vector{Int}) where TBuild response matrix Y_h at horizon h.
MacroEconometricModels.compare_var_lp — Method
compare_var_lp(Y::AbstractMatrix{T}, horizon::Int; lags::Int=4) where TCompare VAR-based and LP-based impulse responses.
MacroEconometricModels.compute_block_robust_vcov — Method
compute_block_robust_vcov(X::AbstractMatrix{T}, U::AbstractMatrix{T},
cov_estimator::AbstractCovarianceEstimator) where TCompute block-diagonal robust covariance for multi-equation system.
MacroEconometricModels.compute_horizon_bounds — Method
compute_horizon_bounds(T_obs::Int, h::Int, lags::Int) -> (t_start, t_end)Compute valid observation bounds for horizon h.
MacroEconometricModels.construct_lp_matrices — Method
construct_lp_matrices(Y::AbstractMatrix{T}, shock_var::Int, h::Int, lags::Int;
response_vars::Vector{Int}=collect(1:size(Y,2))) where TConstruct regressor and response matrices for LP regression at horizon h.
Returns: (Yh, Xh, valid_idx)
MacroEconometricModels.create_cov_estimator — Method
create_cov_estimator(cov_type::Symbol, ::Type{T}; bandwidth::Int=0) where TCreate covariance estimator from symbol specification using the global registry.
MacroEconometricModels.estimate_lp — Method
estimate_lp(Y::AbstractMatrix{T}, shock_var::Int, horizon::Int;
lags::Int=4, response_vars::Vector{Int}=collect(1:size(Y,2)),
cov_type::Symbol=:newey_west, bandwidth::Int=0,
conf_level::Real=0.95) -> LPModel{T}Estimate Local Projection impulse response functions (Jordà 2005).
The LP regression for horizon h: y{t+h} = αh + βh * shockt + Γh * controlst + ε_{t+h}
MacroEconometricModels.estimate_lp_cholesky — Method
estimate_lp_cholesky(Y::AbstractMatrix{T}, horizon::Int;
lags::Int=4, cov_type::Symbol=:newey_west, kwargs...) -> Vector{LPModel{T}}Estimate LP with Cholesky-orthogonalized shocks.
MacroEconometricModels.estimate_lp_multi — Method
estimate_lp_multi(Y::AbstractMatrix{T}, shock_vars::Vector{Int}, horizon::Int;
kwargs...) -> Vector{LPModel{T}}Estimate LP for multiple shock variables.
MacroEconometricModels.extract_shock_irf — Method
extract_shock_irf(B::Vector{Matrix{T}}, vcov::Vector{Matrix{T}},
response_vars::Vector{Int}, shock_coef_idx::Int;
conf_level::Real=0.95) where TGeneric IRF extraction from coefficient and covariance vectors. Works for LPModel, LPIVModel, PropensityLPModel.
MacroEconometricModels.structural_lp — Method
structural_lp(Y::AbstractMatrix{T}, horizon::Int;
method=:cholesky, lags=4, var_lags=nothing,
cov_type=:newey_west, conf_level=0.95,
ci_type=:none, reps=200,
check_func=nothing, narrative_check=nothing,
max_draws=1000,
transition_var=nothing, regime_indicator=nothing) -> StructuralLP{T}Estimate structural LP impulse responses using VAR-based identification with LP estimation.
Algorithm:
- Estimate VAR(p) → obtain Σ and residuals
- Compute rotation matrix Q via chosen identification method
- Compute structural shocks εt = Q'L⁻¹ut
- For each shock j, run LP with εj as regressor and Yeff as responses
- Stack into 3D IRF array: irfs[h, i, j]
Arguments
Y: T × n data matrixhorizon: Maximum IRF horizon H
Keyword Arguments
method: Identification methodlags: Number of LP control lags (default: 4)var_lags: VAR lag order for identification (default: same aslags)cov_type: HAC estimator (:newey_west, :white)conf_level: Confidence level for CIs (default: 0.95)ci_type: CI method (:none, :bootstrap)reps: Number of bootstrap replicationscheck_func: Sign restriction check function (for :sign/:narrative)narrative_check: Narrative check function (for :narrative)max_draws: Maximum draws for sign/narrative identificationtransition_var: Transition variable (for :smooth_transition)regime_indicator: Regime indicator (for :external_volatility)
Methods
:cholesky, :sign, :narrative, :long_run, :fastica, :jade, :sobi, :dcov, :hsic, :student_t, :mixture_normal, :pml, :skew_normal, :nongaussian_ml, :markov_switching, :garch, :smooth_transition, :external_volatility
Note: :smooth_transition requires transition_var kwarg. :external_volatility requires regime_indicator kwarg.
Returns
StructuralLP{T} with 3D IRFs, structural shocks, VAR model, and individual LP models.
References
Plagborg-Møller, M. & Wolf, C. K. (2021). "Local Projections and VARs Estimate the Same Impulse Responses." Econometrica, 89(2), 955–980.
LP-IV (Stock & Watson 2018)
MacroEconometricModels.estimate_lp_iv — Method
estimate_lp_iv(Y::AbstractMatrix{T}, shock_var::Int, instruments::AbstractMatrix{T},
horizon::Int; lags::Int=4, response_vars::Vector{Int}=collect(1:size(Y,2)),
cov_type::Symbol=:newey_west, bandwidth::Int=0) -> LPIVModel{T}Estimate LP with Instrumental Variables (Stock & Watson 2018) using 2SLS.
MacroEconometricModels.first_stage_regression — Method
first_stage_regression(endog::AbstractVector{T}, instruments::AbstractMatrix{T},
controls::AbstractMatrix{T}; h::Int=0) -> NamedTupleFirst-stage regression for 2SLS with HAC-robust F-statistic for instrument relevance.
At LP horizon h > 0, residuals have MA(h-1) autocorrelation by construction (Jordà 2005), so the F-statistic uses Newey-West HAC variance with bandwidth ≥ h+1.
MacroEconometricModels.lp_iv_irf — Method
lp_iv_irf(model::LPIVModel{T}; conf_level::Real=0.95) -> LPImpulseResponse{T}Extract IRF from LP-IV model.
MacroEconometricModels.sargan_test — Method
sargan_test(model::LPIVModel{T}, h::Int) -> NamedTupleSargan-Hansen J-test for overidentification at horizon h.
MacroEconometricModels.tsls_regression — Method
tsls_regression(Y::AbstractMatrix{T}, endog::AbstractVector{T},
endog_fitted::AbstractVector{T}, controls::AbstractMatrix{T};
cov_estimator::AbstractCovarianceEstimator=NeweyWestEstimator()) -> NamedTupleSecond-stage regression using fitted values from first stage.
MacroEconometricModels.weak_instrument_test — Method
weak_instrument_test(model::LPIVModel{T}; threshold::T=T(10.0)) -> NamedTupleTest for weak instruments using Stock-Yogo rule of thumb (F > 10).
Smooth LP (Barnichon & Brownlees 2019)
MacroEconometricModels.bspline_basis — Method
bspline_basis(horizons::AbstractVector{Int}, degree::Int, n_interior_knots::Int;
T::Type{<:AbstractFloat}=Float64) -> BSplineBasis{T}Construct B-spline basis matrix for given horizons.
MacroEconometricModels.bspline_basis_value — Method
bspline_basis_value(x::T, i::Int, degree::Int, knots::Vector{T}) where TEvaluate B-spline basis function using Cox-de Boor recursion.
MacroEconometricModels.compare_smooth_lp — Method
compare_smooth_lp(Y::AbstractMatrix{T}, shock_var::Int, horizon::Int;
lambda::T=T(1.0), kwargs...) -> NamedTupleCompare standard LP and smooth LP.
MacroEconometricModels.cross_validate_lambda — Method
cross_validate_lambda(Y::AbstractMatrix{T}, shock_var::Int, horizon::Int;
lambda_grid::Vector{T}=T.(10.0 .^ (-4:0.5:2)),
k_folds::Int=5, kwargs...) -> TSelect optimal λ via k-fold cross-validation.
MacroEconometricModels.estimate_smooth_lp — Method
estimate_smooth_lp(Y::AbstractMatrix{T}, shock_var::Int, horizon::Int;
degree::Int=3, n_knots::Int=4, lambda::T=T(0.0),
lags::Int=4, response_vars::Vector{Int}=collect(1:size(Y,2)),
cov_type::Symbol=:newey_west, bandwidth::Int=0) -> SmoothLPModel{T}Estimate Smooth LP with B-spline parameterization (Barnichon & Brownlees 2019).
MacroEconometricModels.roughness_penalty_matrix — Method
roughness_penalty_matrix(basis::BSplineBasis{T}) -> Matrix{T}Compute roughness penalty matrix R for B-splines (second derivative penalty).
MacroEconometricModels.smooth_lp_irf — Method
smooth_lp_irf(model::SmoothLPModel{T}; conf_level::Real=0.95) -> LPImpulseResponse{T}Extract smoothed IRF from SmoothLPModel.
State-Dependent LP (Auerbach & Gorodnichenko 2013)
MacroEconometricModels.estimate_state_lp — Method
estimate_state_lp(Y::AbstractMatrix{T}, shock_var::Int, state_var::AbstractVector{T},
horizon::Int; gamma::Union{T,Symbol}=:estimate, ...) -> StateLPModel{T}Estimate state-dependent LP (Auerbach & Gorodnichenko 2013).
MacroEconometricModels.estimate_transition_params — Method
estimate_transition_params(state_var::AbstractVector{T}, Y::AbstractMatrix{T},
shock_var::Int; method::Symbol=:nlls, ...) -> NamedTupleEstimate smooth transition parameters (γ, c).
MacroEconometricModels.exponential_transition — Method
exponential_transition(z::AbstractVector{T}, gamma::T, c::T) -> Vector{T}Exponential (symmetric) transition: F(z) = 1 - exp(-γ(z - c)²)
MacroEconometricModels.indicator_transition — Method
indicator_transition(z::AbstractVector{T}, c::T) -> Vector{T}Sharp indicator transition: F(z) = 1 if z ≥ c, else 0
MacroEconometricModels.logistic_transition — Method
logistic_transition(z::AbstractVector{T}, gamma::T, c::T) -> Vector{T}Logistic transition function: F(z) = exp(-γ(z - c)) / (1 + exp(-γ(z - c)))
MacroEconometricModels.state_irf — Method
state_irf(model::StateLPModel{T}; regime::Symbol=:both, conf_level::Real=0.95) -> NamedTupleExtract state-dependent IRFs.
MacroEconometricModels.test_regime_difference — Method
test_regime_difference(model::StateLPModel{T}; h::Union{Int,Nothing}=nothing) -> NamedTupleTest whether IRFs differ across regimes.
Propensity Score LP (Angrist et al. 2018)
MacroEconometricModels.doubly_robust_lp — Method
doubly_robust_lp(Y::AbstractMatrix{T}, treatment::AbstractVector{Bool},
covariates::AbstractMatrix{T}, horizon::Int; ...) -> PropensityLPModel{T}Doubly robust LP estimator combining IPW and regression adjustment.
MacroEconometricModels.estimate_propensity_lp — Method
estimate_propensity_lp(Y::AbstractMatrix{T}, treatment::AbstractVector{Bool},
covariates::AbstractMatrix{T}, horizon::Int; ...) -> PropensityLPModel{T}Estimate LP with Inverse Propensity Weighting (Angrist et al. 2018).
MacroEconometricModels.estimate_propensity_score — Method
estimate_propensity_score(treatment::AbstractVector{Bool}, X::AbstractMatrix{T};
method::Symbol=:logit) -> Vector{T}Estimate propensity scores P(D=1|X) via logit or probit.
MacroEconometricModels.inverse_propensity_weights — Method
inverse_propensity_weights(treatment::AbstractVector{Bool}, propensity::AbstractVector{T};
trimming::Tuple{T,T}=(T(0.01), T(0.99)), normalize::Bool=true) -> Vector{T}Compute IPW weights with optional trimming.
MacroEconometricModels.propensity_diagnostics — Method
propensity_diagnostics(model::PropensityLPModel{T}) -> NamedTuplePropensity score diagnostics (overlap, balance).
MacroEconometricModels.propensity_irf — Method
propensity_irf(model::PropensityLPModel{T}; conf_level::Real=0.95) -> LPImpulseResponse{T}Extract treatment effect (ATE) IRF from PropensityLPModel.
LP Forecasting
MacroEconometricModels._build_forecast_controls — Method
Build the control vector from LP model's last observations.
MacroEconometricModels._forecast_ci — Method
Compute forecast CIs from SEs using normal quantiles.
MacroEconometricModels._lp_forecast_bootstrap — Method
Bootstrap CIs for LP forecasts via residual resampling.
MacroEconometricModels.forecast — Method
forecast(lp::LPModel{T}, shock_path::AbstractVector{<:Real};
ci_method=:analytical, conf_level=0.95, n_boot=500) -> LPForecast{T}Compute direct multi-step LP forecasts given a shock trajectory.
For each horizon h=1,...,H, the forecast uses the LP regression coefficients: ŷ{T+h} = αh + βh·shockh + Γh·controlsT
where controls_T are the last lags observations of Y.
Arguments
lp: Estimated LP modelshock_path: Vector of length H with assumed future shock values
Keyword Arguments
ci_method::analytical(default),:bootstrap, or:noneconf_level: Confidence level (default: 0.95)n_boot: Number of bootstrap replications (default: 500)
Returns
LPForecast{T} with point forecasts, CIs, and standard errors.
MacroEconometricModels.forecast — Method
forecast(slp::StructuralLP{T}, shock_idx::Int, shock_path::AbstractVector{<:Real};
ci_method=:analytical, conf_level=0.95, n_boot=500) -> LPForecast{T}Compute direct multi-step forecast from a structural LP model using a specific orthogonalized shock.
Arguments
slp: Structural LP modelshock_idx: Index of the structural shock to use (1:n)shock_path: Vector of length H with assumed shock values
Keyword Arguments
ci_method::analytical(default),:bootstrap, or:noneconf_level: Confidence level (default: 0.95)n_boot: Number of bootstrap replications (default: 500)
LP-FEVD (Gorodnichenko & Lee 2019)
MacroEconometricModels._compute_lp_fevd_h — Method
Dispatch to R², LP-A, or LP-B estimator at horizon h.
MacroEconometricModels._lp_fevd_bootstrap — Method
Bootstrap bias correction and CIs for LP-FEVD.
- Fit bivariate VAR(L) on (z, y) with HQIC lag selection
- Compute 'true' FEVD from VAR (theoretical benchmark)
- Simulate B samples from VAR, compute LP-FEVD for each
- Bias = mean(bootstrap FEVD) - true FEVD
- Bias-corrected = raw - bias
- CIs from centered bootstrap distribution (Kilian 1998)
MacroEconometricModels._lp_fevd_lpa_h — Method
_lp_fevd_lpa_h(lp_model, shock, resp_idx, h) -> TLP-A FEVD: ŝh = (Σ{i=0}^{h} β̂₀^{i,LP}² σ̂z²) / Var(f̂{t+h|t-1}). Uses IRF coefficients directly — no R² regression needed.
MacroEconometricModels._lp_fevd_lpb_h — Method
_lp_fevd_lpb_h(f_hat, shock, lp_model, resp_idx, t_start, h) -> TLP-B FEVD: ŝh = numerator / (numerator + Var(ṽ{t+h|t-1})), where ṽ is the residual from the R²-regression (Eq. 6).
MacroEconometricModels._lp_fevd_r2_h — Method
_lp_fevd_r2_h(f_hat, shock, t_start, h) -> TR² FEVD at horizon h: regress forecast errors f̂ on shock leads [z{t+h},...,zt].
MacroEconometricModels._r2_on_shock_leads — Method
Regress fhat on [1, z{t+h}, z{t+h-1}, ..., zt] and return R².
MacroEconometricModels._r2_residual_variance — Method
Regress f_hat on shock leads and return Var(residuals).
MacroEconometricModels._scalar_lp_fevd_r2 — Method
Compute R²-based FEVD for scalar (z, y) pair at horizon h. Used in bootstrap bias correction.
MacroEconometricModels._simulate_from_var — Method
Simulate T_sim observations from a VAR model with burn-in.
MacroEconometricModels._var_theoretical_fevd — Method
Compute theoretical FEVD of variable 2 w.r.t. shock 1 from bivariate VAR.
MacroEconometricModels.fevd — Method
fevd(slp::StructuralLP{T}, horizon::Int; kwargs...) -> LPFEVD{T}Compute LP-based FEVD for structural LP results. Dispatches to lp_fevd.
See lp_fevd for full documentation.
MacroEconometricModels.lp_fevd — Method
lp_fevd(slp::StructuralLP{T}, horizon::Int; kwargs...) -> LPFEVD{T}Compute LP-based FEVD using the R²-based estimator of Gorodnichenko & Lee (2019).
At each horizon h, the share of variable i's forecast error variance due to shock j is estimated by regressing LP forecast error residuals on structural shock leads z{t+h}, z{t+h-1}, ..., z_t and computing R².
Arguments
slp: Structural LP result fromstructural_lp()horizon: Maximum FEVD horizon (capped at IRF horizon)
Keyword Arguments
method: Estimator (:r2, :lpa, :lpb). Default: :r2bias_correct: Apply VAR-based bootstrap bias correction. Default: truen_boot: Number of bootstrap replications. Default: 500conf_level: Confidence level for CIs. Default: 0.95var_lags: VAR lag order for bias correction (default: HQIC-selected)
Returns
LPFEVD{T} with raw proportions, bias-corrected values, SEs, and CIs.
Reference
Gorodnichenko, Y. & Lee, B. (2019). "Forecast Error Variance Decompositions with Local Projections." JBES, 38(4), 921–933.
Factor Models
Static Factor Model
MacroEconometricModels._estimate_restricted_em — Method
_estimate_restricted_em(X, r, blocks, standardize; max_iter=500, tol=1e-6) -> FactorModelEstimate block-restricted factor model via EM algorithm.
Each factor loads only on its assigned block of variables. The restriction mask R enforces zero loadings outside each block.
Algorithm
- Validate block structure (count, overlap, range, minimum size)
- Build N × r restriction mask R from block assignments
- Initialize Λ via block-wise PCA (first eigenvector per block)
- EM iteration:
- E-step: F = X Λ (Λ'Λ)⁻¹ (posterior mean of factors given loadings)
- M-step: Λ_new = (F'F)⁻¹ F'X, masked by R (zero out restricted entries)
- Convergence when max absolute change in Λ < tol
MacroEconometricModels.estimate_factors — Method
estimate_factors(X, r; standardize=true, blocks=nothing) -> FactorModelEstimate static factor model Xt = Λ Ft + e_t via Principal Component Analysis, or via block-restricted EM when blocks is provided.
Arguments
X: Data matrix (T × N), observations × variablesr: Number of factors to extract
Keyword Arguments
standardize::Bool=true: Standardize data before estimationblocks::Union{Nothing, Dict{Symbol, Vector{Int}}}=nothing: Block restriction map. When provided, each key is a block (factor) name and the value is a vector of variable indices that load on that factor. Variables not in a block have zero loadings on that factor. The number of blocks must equalr.
Returns
FactorModel containing factors, loadings, eigenvalues, and explained variance. When blocks is provided, block_names is set on the returned model.
Example
X = randn(200, 50) # 200 observations, 50 variables
fm = estimate_factors(X, 3) # Extract 3 factors via PCA
r2(fm) # R² for each variable
# Block-restricted estimation
blocks = Dict(:real => [1,2,3,4,5], :nominal => [6,7,8,9,10])
fm_restricted = estimate_factors(X, 2; blocks=blocks)MacroEconometricModels.forecast — Method
forecast(model::FactorModel, h; p=1, ci_method=:theoretical, conf_level=0.95, n_boot=1000)Forecast factors and observables h steps ahead from a static factor model.
Internally fits a VAR(p) on the extracted factors, then uses the VAR dynamics to produce multi-step forecasts and confidence intervals.
Arguments
model: Estimated static factor modelh: Forecast horizon
Keyword Arguments
p::Int=1: VAR lag order for factor dynamicsci_method::Symbol=:theoretical: CI method —:none,:theoretical, or:bootstrapconf_level::Real=0.95: Confidence level for intervalsn_boot::Int=1000: Number of bootstrap replications (ifci_method=:bootstrap)
Returns
FactorForecast with factor and observable forecasts (and CIs if requested).
MacroEconometricModels.ic_criteria — Method
ic_criteria(X, max_factors; standardize=true)Compute Bai-Ng (2002) information criteria IC1, IC2, IC3 for selecting the number of factors.
Arguments
X: Data matrix (T × N)max_factors: Maximum number of factors to consider
Returns
Named tuple with IC values and optimal factor counts:
IC1,IC2,IC3: Information criteria vectorsr_IC1,r_IC2,r_IC3: Optimal factor counts
Example
result = ic_criteria(X, 10)
println("Optimal factors: IC1=", result.r_IC1, ", IC2=", result.r_IC2, ", IC3=", result.r_IC3)MacroEconometricModels.scree_plot_data — Method
scree_plot_data(m::FactorModel)Return data for scree plot: factor indices, explained variance, cumulative variance.
Example
data = scree_plot_data(fm)
# Plot: data.factors vs data.explained_varianceStatsAPI.dof — Method
Degrees of freedom.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.predict — Method
Predicted values: F * Λ'.
StatsAPI.r2 — Method
R² for each variable.
StatsAPI.residuals — Method
Residuals: X - predicted.
Dynamic Factor Model
MacroEconometricModels._compute_dfm_loglikelihood — Method
Compute Gaussian log-likelihood given factors and parameters.
MacroEconometricModels._em_mstep — Method
M-step: update loadings, VAR coefficients, and covariances.
MacroEconometricModels._estimate_dfm_em — Method
EM algorithm for maximum likelihood estimation.
MacroEconometricModels._estimate_dfm_twostep — Method
Two-step estimation: PCA for factors, then VAR on extracted factors.
MacroEconometricModels.companion_matrix_factors — Method
companion_matrix_factors(model::DynamicFactorModel)Construct companion matrix for factor VAR dynamics.
The companion form converts VAR(p) to VAR(1): [Ft; F{t-1}; ...] = C [F{t-1}; F{t-2}; ...] + [η_t; 0; ...]
MacroEconometricModels.estimate_dynamic_factors — Method
estimate_dynamic_factors(X, r, p; method=:twostep, standardize=true, max_iter=100, tol=1e-6)Estimate dynamic factor model with VAR(p) factor dynamics.
Arguments
X: Data matrix (T × N)r: Number of factorsp: Number of lags in factor VAR
Keyword Arguments
method::Symbol=:twostep: Estimation method (:twostep or :em)standardize::Bool=true: Standardize datamax_iter::Int=100: Maximum EM iterations (if method=:em)tol::Float64=1e-6: Convergence tolerance (if method=:em)diagonal_idio::Bool=true: Assume diagonal idiosyncratic covariance
Returns
DynamicFactorModel with factors, loadings, VAR coefficients, and diagnostics.
Example
dfm = estimate_dynamic_factors(X, 3, 2) # 3 factors, VAR(2)
forecast(dfm, 12) # 12-step ahead forecastMacroEconometricModels.forecast — Method
forecast(model::DynamicFactorModel, h; ci_method=:theoretical, conf_level=0.95, n_boot=1000, ci=false, ci_level=0.95)Forecast factors and observables h steps ahead.
Arguments
model: Estimated dynamic factor modelh: Forecast horizon
Keyword Arguments
ci_method::Symbol=:theoretical: CI method —:none,:theoretical,:bootstrap, or:simulationconf_level::Real=0.95: Confidence level for intervalsn_boot::Int=1000: Bootstrap replications (for:bootstrapand:simulation)ci::Bool=false: Legacy keyword —ci=truemaps toci_method=:simulationci_level::Real=0.95: Legacy keyword — maps toconf_level
Returns
FactorForecast with factor and observable forecasts (and CIs if requested).
Example
fc = forecast(dfm, 12; ci_method=:theoretical)
fc.observables # h×N matrix of forecasts
fc.observables_lower # h×N lower CI boundsMacroEconometricModels.ic_criteria_dynamic — Method
ic_criteria_dynamic(X, max_r, max_p; standardize=true, method=:twostep)Select (r, p) via AIC/BIC grid search over factor and lag combinations.
Returns
Named tuple with AIC/BIC matrices and optimal (r, p) combinations.
MacroEconometricModels.is_stationary — Method
is_stationary(model::DynamicFactorModel) -> BoolCheck if factor dynamics are stationary (max |eigenvalue| < 1).
StatsAPI.aic — Method
Akaike Information Criterion.
StatsAPI.bic — Method
Bayesian Information Criterion.
StatsAPI.dof — Method
Degrees of freedom: Nr + r²p + r(r+1)/2 + N.
StatsAPI.loglikelihood — Method
Log-likelihood of the fitted model.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.predict — Method
Predicted values: F * Λ'.
StatsAPI.r2 — Method
R² for each variable.
StatsAPI.residuals — Method
Residuals: X - predicted.
Generalized Dynamic Factor Model
MacroEconometricModels._compute_common_spectral_density — Method
Compute spectral density of common component from loadings and eigenvalues.
MacroEconometricModels._compute_kernel_weights — Method
Compute kernel weights for spectral smoothing.
MacroEconometricModels._compute_variance_explained — Method
Compute variance explained by first q factors (averaged across frequencies).
MacroEconometricModels._estimate_spectral_density — Method
Estimate spectral density matrix with kernel smoothing.
MacroEconometricModels._extract_time_domain_factors — Method
Extract time-domain factors via frequency-domain projection.
MacroEconometricModels._forecast_factors_ar — Method
AR(1) forecast for each factor series.
MacroEconometricModels._reconstruct_time_domain — Method
Reconstruct common component in time domain via inverse FFT.
MacroEconometricModels._select_bandwidth — Method
Automatic bandwidth selection: T^(1/3).
MacroEconometricModels._spectral_eigendecomposition — Method
Eigendecomposition of spectral density at each frequency.
MacroEconometricModels.common_variance_share — Method
common_variance_share(model::GeneralizedDynamicFactorModel) -> VectorFraction of each variable's variance explained by the common component.
MacroEconometricModels.estimate_gdfm — Method
estimate_gdfm(X, q; standardize=true, bandwidth=0, kernel=:bartlett, r=0) -> GeneralizedDynamicFactorModelEstimate Generalized Dynamic Factor Model using spectral methods.
Arguments
X: Data matrix (T × N)q: Number of dynamic factors
Keyword Arguments
standardize::Bool=true: Standardize databandwidth::Int=0: Kernel bandwidth (0 = automatic selection)kernel::Symbol=:bartlett: Kernel for spectral smoothing (:bartlett, :parzen, :tukey)r::Int=0: Number of static factors (0 = same as q)
Returns
GeneralizedDynamicFactorModel with common/idiosyncratic components and spectral loadings.
Example
gdfm = estimate_gdfm(X, 3)
common_variance_share(gdfm) # Fraction of variance explained by common componentMacroEconometricModels.forecast — Method
forecast(model::GeneralizedDynamicFactorModel, h; method=:ar, ci_method=:theoretical, conf_level=0.95, n_boot=1000)Forecast h steps ahead using AR extrapolation of factors.
Arguments
model: Estimated GDFMh: Forecast horizon
Keyword Arguments
method::Symbol=:ar: Forecasting method (currently only:arsupported)ci_method::Symbol=:theoretical: CI method —:none,:theoretical, or:bootstrapconf_level::Real=0.95: Confidence level for intervalsn_boot::Int=1000: Bootstrap replications (for:bootstrap)
Returns
FactorForecast with factor and observable forecasts (and CIs if requested).
MacroEconometricModels.ic_criteria_gdfm — Method
ic_criteria_gdfm(X, max_q; standardize=true, bandwidth=0, kernel=:bartlett)Information criteria for selecting number of dynamic factors.
Uses eigenvalue ratio test and cumulative variance threshold.
Returns
Named tuple with:
eigenvalue_ratios: Ratios of consecutive eigenvaluescumulative_variance: Cumulative variance explainedq_ratio: Optimal q from eigenvalue ratioq_variance: Optimal q from 90% variance threshold
MacroEconometricModels.spectral_eigenvalue_plot_data — Method
spectral_eigenvalue_plot_data(model::GeneralizedDynamicFactorModel)Return data for plotting eigenvalues across frequencies.
StatsAPI.dof — Method
Degrees of freedom.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.predict — Method
Predicted values (common component).
StatsAPI.r2 — Method
R² for each variable.
StatsAPI.residuals — Method
Residuals (idiosyncratic component).
Panel VAR
Estimation
MacroEconometricModels.estimate_pvar — Function
estimate_pvar(d::PanelData{T}, p::Int; kwargs...) -> PVARModel{T}Estimate Panel VAR(p) via GMM.
Arguments
d::PanelData{T}— balanced panel data (usextsetto construct)p::Int— number of lags
Keyword Arguments
dependent_vars::Union{Vector{String},Nothing}=nothing— endogenous variable names (default: all)predet_vars::Vector{String}=String[]— predetermined variable namesexog_vars::Vector{String}=String[]— strictly exogenous variable namestransformation::Symbol=:fd—:fd(first-difference) or:fod(forward orthogonal deviations)steps::Symbol=:twostep—:onestep,:twostep, or:mstep(iterated)system_instruments::Bool=false— if true, use System GMM (Blundell-Bond)system_constant::Bool=true— include constant in level equation (System GMM)min_lag_endo::Int=2— minimum instrument lag for endogenous variablesmax_lag_endo::Int=99— maximum instrument lag (99 = all available)collapse::Bool=false— collapse instruments to limit proliferationpca_instruments::Bool=false— apply PCA reduction to instrumentspca_max_components::Int=0— max PCA components (0 = auto)max_iter::Int=100— max iterations for iterated GMM
Returns
PVARModel{T}with coefficient estimates, robust standard errors, and GMM internals
References
- Arellano, M. & Bond, S. (1991). Review of Economic Studies 58(2), 277-297.
- Blundell, R. & Bond, S. (1998). Journal of Econometrics 87(1), 115-143.
- Windmeijer, F. (2005). Journal of Econometrics 126(1), 25-51.
Examples
pd = xtset(df, :id, :time)
model = estimate_pvar(pd, 2; steps=:twostep)
model = estimate_pvar(pd, 1; system_instruments=true, steps=:twostep)MacroEconometricModels.estimate_pvar_feols — Function
estimate_pvar_feols(d::PanelData{T}, p::Int; kwargs...) -> PVARModel{T}Estimate Panel VAR(p) via Fixed Effects OLS (within estimator).
Simpler than GMM but subject to Nickell (1981) bias when T is small relative to N. Uses within-group demeaning to remove fixed effects, then pooled OLS with cluster-robust standard errors.
Arguments
d::PanelData{T}— panel datap::Int— number of lags
Keyword Arguments
dependent_vars::Union{Vector{String},Nothing}=nothing— endogenous variable namespredet_vars::Vector{String}=String[]— predetermined variable namesexog_vars::Vector{String}=String[]— strictly exogenous variable names
Examples
pd = xtset(df, :id, :time)
model = estimate_pvar_feols(pd, 2)Structural Analysis
MacroEconometricModels.pvar_oirf — Function
pvar_oirf(model::PVARModel{T}, H::Int) -> Array{T, 3}Orthogonalized impulse response functions via Cholesky decomposition.
Ψh = Φh P where P = chol(Σ) is the lower Cholesky factor.
Returns H+1 × m × m array: oirf[h+1, response, shock].
Arguments
model::PVARModel— estimated PVARH::Int— maximum horizon
Examples
oirf = pvar_oirf(model, 10)
oirf[1, :, :] # impact response (h=0)MacroEconometricModels.pvar_girf — Function
pvar_girf(model::PVARModel{T}, H::Int) -> Array{T, 3}Generalized impulse response functions (Pesaran & Shin, 1998).
GIRFh(j) = Φh Σ ej / √σjj
where ej is the j-th unit vector and σjj = Σ[j,j].
Returns H+1 × m × m array: girf[h+1, response, shock].
MacroEconometricModels.pvar_fevd — Function
pvar_fevd(model::PVARModel{T}, H::Int) -> Array{T, 3}Forecast error variance decomposition based on OIRF.
Ω[l, k, h] = Σ{j=0}^{h} (Ψj[l,k])² / MSE_h[l,l]
where MSEh = Σ{j=0}^{h} Φj Σ Φj'.
Returns H+1 × m × m array: fevd[h+1, variable, shock]. Each row sums to 1.
Examples
fv = pvar_fevd(model, 10)
sum(fv[11, 1, :]) # ≈ 1.0 (all shocks for var 1 at h=10)MacroEconometricModels.pvar_stability — Function
pvar_stability(model::PVARModel{T}) -> PVARStability{T}Check stability of the PVAR by computing eigenvalues of the companion matrix. The system is stable if all eigenvalue moduli are strictly less than 1.
Examples
stab = pvar_stability(model)
stab.is_stable # true if all |λ| < 1
stab.moduli # sorted eigenvalue moduliBootstrap
MacroEconometricModels.pvar_bootstrap_irf — Function
pvar_bootstrap_irf(model::PVARModel{T}, H::Int;
irf_type::Symbol=:oirf, n_draws::Int=500,
ci::Real=0.95, rng::AbstractRNG=Random.default_rng()) -> NamedTupleGroup-level block bootstrap for PVAR impulse response confidence intervals.
Resamples N groups with replacement → re-estimates PVAR → computes IRF → collects pointwise quantiles.
Arguments
model::PVARModel— estimated PVARH::Int— maximum IRF horizon
Keywords
irf_type::Symbol=:oirf—:oirfor:girfn_draws::Int=500— number of bootstrap replicationsci::Real=0.95— confidence levelrng::AbstractRNG— random number generator
Returns
NamedTuple with:
irf::Array{T,3}— point estimate (H+1 × m × m)lower::Array{T,3}— lower CI boundupper::Array{T,3}— upper CI bounddraws::Array{T,4}— all bootstrap draws (n_draws × H+1 × m × m)
Specification Tests
MacroEconometricModels.pvar_hansen_j — Function
pvar_hansen_j(model::PVARModel{T}) -> PVARTestResult{T}Hansen (1982) J-test for overidentifying restrictions.
J = (Σi Zi' ei)' W (Σi Zi' ei) ~ χ²(q - k)
where q = number of instruments, k = number of parameters per equation.
H0: All moment conditions are valid. H1: Some moment conditions are invalid.
Examples
j = pvar_hansen_j(model)
j.pvalue > 0.05 # fail to reject → instruments validMacroEconometricModels.pvar_mmsc — Function
pvar_mmsc(model::PVARModel{T}; hq_criterion::Real=2.1) -> NamedTupleAndrews-Lu (2001) Model and Moment Selection Criteria based on Hansen J-statistic.
MMSCBIC = J - (c - b) × log(n) MMSCAIC = J - (c - b) × 2 MMSC_HQIC = J - Q(c - b) × log(log(n))
Lower values are preferred.
Returns
NamedTuple (bic, aic, hqic) of MMSC values.
Examples
mmsc = pvar_mmsc(model)
mmsc.bic # MMSC-BIC valueMacroEconometricModels.pvar_lag_selection — Function
pvar_lag_selection(d::PanelData{T}, max_p::Int; kwargs...) -> NamedTupleSelect optimal PVAR lag order by estimating models for p = 1, ..., max_p and comparing Andrews-Lu MMSC criteria.
Returns
NamedTuple with:
table::Matrix— comparison table (max_p × 4: p, BIC, AIC, HQIC)best_bic::Int,best_aic::Int,best_hqic::Int— optimal lag ordersmodels::Vector{PVARModel}— estimated models
Examples
sel = pvar_lag_selection(pd, 4)
sel.best_bic # optimal lag by BICGMM Utilities
MacroEconometricModels.linear_gmm_solve — Function
linear_gmm_solve(S_ZX::Matrix{T}, S_Zy::AbstractVecOrMat{T},
W::Matrix{T}) -> Vector{T}Solve linear GMM analytically: E[Z'(y - Xβ)] = 0.
Given pre-aggregated cross-products SZX = Σi Zi'Xi and SZy = Σi Zi'yi:
β = (S_ZX' W S_ZX)⁻¹ S_ZX' W S_ZyArguments
S_ZX— q × k aggregated instrument-regressor cross-productS_Zy— q × 1 (or q-vector) aggregated instrument-response cross-productW— q × q weighting matrix
Returns
- Parameter vector β (length k)
MacroEconometricModels.gmm_sandwich_vcov — Function
gmm_sandwich_vcov(S_ZX::Matrix{T}, W::Matrix{T},
D_e::Matrix{T}) -> Matrix{T}Robust sandwich covariance for one-step GMM:
V = (S_ZX' W S_ZX)⁻¹ S_ZX' W D_e W S_ZX (S_ZX' W S_ZX)⁻¹where De = Σi (Zi ei)(Zi ei)' is the robust moment covariance.
Arguments
S_ZX— q × k aggregated instrument-regressor cross-productW— q × q weighting matrixD_e— q × q robust moment covariance
Returns
- k × k covariance matrix
MacroEconometricModels.andrews_lu_mmsc — Function
andrews_lu_mmsc(j_stat::T, n_instruments::Int, n_params::Int,
n_obs::Int; hq_criterion::Real=2.1) -> NamedTupleAndrews-Lu (2001) Model and Moment Selection Criteria based on Hansen J-statistic.
MMSC_BIC = J - (c - b) × log(n)
MMSC_AIC = J - (c - b) × 2
MMSC_HQIC = J - Q(c - b) × log(log(n))where c = moment conditions, b = parameters, n = observations. Lower values indicate better model specification.
Arguments
j_stat— Hansen J-test statisticn_instruments— number of moment conditions (c)n_params— number of parameters (b)n_obs— number of observations (n)hq_criterion— penalty parameter Q for HQIC (default 2.1)
Returns
NamedTuple (bic, aic, hqic).
References
- Andrews, D. & Lu, B. (2001). Journal of Econometrics 101(1), 123-164.
Difference-in-Differences
Estimation
MacroEconometricModels.estimate_did — Function
estimate_did(pd::PanelData{T}, outcome::Union{String,Symbol},
treatment::Union{String,Symbol};
method::Symbol=:twfe,
leads::Int=0, horizon::Int=5,
covariates::Vector{String}=String[],
control_group::Symbol=:never_treated,
cluster::Symbol=:unit,
conf_level::Real=0.95) where {T}Estimate a Difference-in-Differences model.
Arguments
pd: Panel data with outcome and treatment timing columnsoutcome: Name of outcome variabletreatment: Name of treatment timing variable (contains period of first treatment; 0 or NaN for never-treated units)method: Estimation method:twfe– Two-Way Fixed Effects event-study regression (default):callaway_santanna– Callaway & Sant'Anna (2021) group-time ATT:sun_abraham– Sun & Abraham (2021) interaction-weighted estimator:bjs– Borusyak, Jaravel & Spiess (2024) imputation estimator:did_multiplegt– de Chaisemartin & D'Haultfoeuille (2020)
Keyword Arguments
leads: Number of pre-treatment periods to estimate (default: 0)horizon: Post-treatment horizon (default: 5)covariates: Additional control variable namescontrol_group::never_treated(default) or:not_yet_treatedcluster: SE clustering::unit(default),:time,:twowayconf_level: Confidence level (default: 0.95)n_boot: Number of bootstrap replications for:did_multiplegt(default: 200)base_period::varying(default, Rdiddefault) or:universal. For:callaway_santannaonly.:varyinguses adjacent-period comparisons for pre-treatment cells;:universalalways usesg-1as base period
Returns
DIDResult{T} – unified result type for all methods.
Examples
# TWFE event study
did = estimate_did(pd, :gdp, :reform_year; method=:twfe, leads=3, horizon=5)
report(did)
# Callaway-Sant'Anna
did_cs = estimate_did(pd, :gdp, :reform_year; method=:callaway_santanna, leads=3, horizon=5)
plot_result(did_cs)References
- Callaway, B. & Sant'Anna, P. H. C. (2021). JoE 225(2), 200-230.
MacroEconometricModels.estimate_event_study_lp — Function
estimate_event_study_lp(pd::PanelData{T}, outcome::Union{String,Symbol},
treatment::Union{String,Symbol}, H::Int;
leads::Int=3, lags::Int=4,
covariates::Vector{String}=String[],
cluster::Symbol=:unit,
conf_level::Real=0.95) where {T}Estimate event study impulse responses using local projections with panel FE.
Uses the switching indicator ΔD_{it} (= 1 only at the treatment onset period) and time-only FE. Already-treated observations are excluded from the sample.
Arguments
pd: Panel dataoutcome: Outcome variable nametreatment: Treatment variable (binary 0/1 or timing column)H: Maximum post-treatment horizonleads: Number of pre-treatment leads to estimate (for pre-trends)lags: Number of outcome lags as controlscovariates: Additional control variable namescluster: Clustering level (:unit, :time, :twoway)conf_level: Confidence level (default: 0.95)
Returns
EventStudyLP{T} with dynamic treatment effect coefficients.
References
- Jordà, Ò. (2005). AER 95(1), 161-182.
- Acemoglu, D. et al. (2019). JPE 127(1), 47-100.
MacroEconometricModels.estimate_lp_did — Function
estimate_lp_did(pd::PanelData{T}, outcome, treatment, H; kwargs...) -> LPDiDResult{T}LP-DiD estimator with full feature parity to the Stata lpdid package v1.0.2.
Uses the switching indicator (ΔD_{it}) as treatment, clean control samples (CCS), and time-only fixed effects (long differencing absorbs unit FE).
Arguments
pd— panel dataoutcome— outcome variable (name or symbol)treatment— treatment variable (binary 0/1 or timing column)H— maximum horizon
Keyword Arguments
pre_window::Int=3— pre-treatment event-time windowpost_window::Int=H— post-treatment event-time windowylags::Int=0— number of outcome lags as controlsdylags::Int=0— number of ΔY lags as controlscovariates::Vector{String}=String[]— additional covariatesnonabsorbing::Union{Nothing,Int}=nothing— stabilization window L for non-absorbing treatmentnotyet::Bool=false— restrict controls to not-yet-treatednevertreated::Bool=false— restrict controls to never-treatedfirsttreat::Bool=false— use only first treatment event per unitoneoff::Bool=false— one-off treatment (requiresnonabsorbing)pmd::Union{Nothing,Symbol,Int}=nothing— pre-mean differencing (:max or integer k)reweight::Bool=false— IPW reweighting for equally weighted ATEnocomp::Bool=false— restrict to observations in CCS at all horizonscluster::Symbol=:unit— clustering level (:unit, :time, :twoway)conf_level::Real=0.95— confidence levelonly_pooled::Bool=false— skip event study, compute pooled onlyonly_event::Bool=false— skip pooled estimatespost_pooled::Union{Nothing,Tuple{Int,Int}}=nothing— pooled post-treatment window (start, end)pre_pooled::Union{Nothing,Tuple{Int,Int}}=nothing— pooled pre-treatment window (start, end)
References
- Dube, A., Girardi, D., Jordà, Ò. & Taylor, A.M. (2025). JAE.
- Acemoglu, D. et al. (2019). JPE 127(1), 47-100.
Diagnostics
MacroEconometricModels.bacon_decomposition — Function
bacon_decomposition(pd::PanelData{T}, outcome::Union{String,Symbol},
treatment::Union{String,Symbol}) where {T}Decompose the TWFE DiD estimator into a weighted average of all 2x2 DiD comparisons.
Each weight reflects the subsample size and variance of treatment within the comparison.
Returns
BaconDecomposition{T} with estimates, weights, and comparison types.
Reference
Goodman-Bacon, A. (2021). "Difference-in-Differences with Variation in Treatment Timing." JoE 225(2), 254-277.
MacroEconometricModels.pretrend_test — Function
pretrend_test(result::DIDResult{T}) where {T}
pretrend_test(result::EventStudyLP{T}) where {T}Joint F-test for parallel trends: H0: beta{-K} = beta{-K+1} = ... = beta_{-1} = 0.
Tests whether pre-treatment event-time coefficients are jointly zero. High p-value -> no evidence against parallel trends.
Returns
PretrendTestResult{T} with F-statistic and p-value.
MacroEconometricModels.negative_weight_check — Function
negative_weight_check(pd::PanelData{T}, treatment::Union{String,Symbol}) where {T}de Chaisemartin & D'Haultfoeuille (2020) negative weight diagnostic.
Checks whether the TWFE estimator assigns negative weights to some group-time cells. Negative weights can cause the overall DiD estimate to have the opposite sign of all underlying ATT(g,t).
Returns
NegativeWeightResult{T}.
Reference
de Chaisemartin, C. & D'Haultfoeuille, X. (2020). AER 110(9), 2964-2996.
Sensitivity Analysis
MacroEconometricModels.honest_did — Function
honest_did(result::DIDResult{T}; Mbar::Real=1.0, conf_level::Real=0.95) where {T}HonestDiD sensitivity analysis for a Difference-in-Differences result.
Constructs robust confidence intervals that account for bounded violations of the parallel trends assumption under the relative magnitudes restriction (Rambachan & Roth 2023).
Arguments
result::DIDResult{T}— DiD estimation result (fromestimate_didorcallaway_santanna)Mbar::Real=1.0— maximum violation bound (relative magnitudes parameter)conf_level::Real=0.95— confidence level for the robust CIs
Returns
HonestDiDResult{T} with robust CIs, breakdown value, and post-treatment estimates.
Example
did = estimate_did(pd, :y, :treat)
h = honest_did(did; Mbar=1.0)
h.breakdown_value # smallest Mbar that overturns significancehonest_did(result::EventStudyLP{T}; Mbar::Real=1.0, conf_level::Real=0.95) where {T}HonestDiD sensitivity analysis for an Event Study LP result.
Constructs robust confidence intervals that account for bounded violations of the parallel trends assumption under the relative magnitudes restriction (Rambachan & Roth 2023).
Arguments
result::EventStudyLP{T}— event study LP result (fromevent_study_lporlp_did)Mbar::Real=1.0— maximum violation bound (relative magnitudes parameter)conf_level::Real=0.95— confidence level for the robust CIs
Returns
HonestDiDResult{T} with robust CIs, breakdown value, and post-treatment estimates.
Example
eslp = event_study_lp(pd, :y, :treat, 5; leads=3, lags=2)
h = honest_did(eslp; Mbar=0.5)
h.robust_ci_lower # lower bounds accounting for trend violationsGMM Estimation
MacroEconometricModels.andrews_lu_mmsc — Method
andrews_lu_mmsc(j_stat::T, n_instruments::Int, n_params::Int,
n_obs::Int; hq_criterion::Real=2.1) -> NamedTupleAndrews-Lu (2001) Model and Moment Selection Criteria based on Hansen J-statistic.
MMSC_BIC = J - (c - b) × log(n)
MMSC_AIC = J - (c - b) × 2
MMSC_HQIC = J - Q(c - b) × log(log(n))where c = moment conditions, b = parameters, n = observations. Lower values indicate better model specification.
Arguments
j_stat— Hansen J-test statisticn_instruments— number of moment conditions (c)n_params— number of parameters (b)n_obs— number of observations (n)hq_criterion— penalty parameter Q for HQIC (default 2.1)
Returns
NamedTuple (bic, aic, hqic).
References
- Andrews, D. & Lu, B. (2001). Journal of Econometrics 101(1), 123-164.
MacroEconometricModels.estimate_gmm — Method
estimate_gmm(moment_fn::Function, theta0::AbstractVector{T}, data;
weighting::Symbol=:two_step, max_iter::Int=100,
tol::T=T(1e-8), hac::Bool=true, bandwidth::Int=0,
bounds::Union{Nothing,ParameterTransform}=nothing) -> GMMModel{T}Estimate parameters via Generalized Method of Moments.
Minimizes: Q(θ) = g(θ)'W g(θ) where g(θ) = (1/n) Σᵢ gᵢ(θ)
Arguments:
- moment_fn: Function (theta, data) -> Matrix of moment conditions (n × q)
- theta0: Initial parameter guess
- data: Data passed to moment function
- weighting: Weighting method (:identity, :optimal, :two_step, :iterated)
- max_iter: Maximum iterations for optimization and/or iterated GMM
- tol: Convergence tolerance
- hac: Use HAC correction for optimal weighting
- bandwidth: HAC bandwidth (0 = automatic)
- bounds: Parameter bounds via
ParameterTransform(default: nothing = unconstrained). When provided, optimization is performed in unconstrained space via bijective transforms, and standard errors are corrected via the delta method.
Returns:
- GMMModel with estimates, covariance, and J-test results
MacroEconometricModels.estimate_lp_gmm — Method
estimate_lp_gmm(Y::AbstractMatrix{T}, shock_var::Int, horizon::Int;
lags::Int=4, weighting::Symbol=:two_step) -> Vector{GMMModel{T}}Estimate Local Projection via GMM.
Returns a GMMModel for each horizon.
MacroEconometricModels.gmm_objective — Method
gmm_objective(theta::AbstractVector{T}, moment_fn::Function, data,
W::AbstractMatrix{T}) -> TCompute GMM objective: Q(θ) = g(θ)'W g(θ)
where g(θ) = (1/n) Σᵢ gᵢ(θ,data)
Arguments:
- theta: Parameter vector
- moment_fn: Function (theta, data) -> Matrix of moment conditions (n × q)
- data: Data passed to moment function
- W: Weighting matrix (q × q)
Returns:
- GMM objective value
MacroEconometricModels.gmm_sandwich_vcov — Method
gmm_sandwich_vcov(S_ZX::Matrix{T}, W::Matrix{T},
D_e::Matrix{T}) -> Matrix{T}Robust sandwich covariance for one-step GMM:
V = (S_ZX' W S_ZX)⁻¹ S_ZX' W D_e W S_ZX (S_ZX' W S_ZX)⁻¹where De = Σi (Zi ei)(Zi ei)' is the robust moment covariance.
Arguments
S_ZX— q × k aggregated instrument-regressor cross-productW— q × q weighting matrixD_e— q × q robust moment covariance
Returns
- k × k covariance matrix
MacroEconometricModels.gmm_summary — Method
gmm_summary(model::GMMModel{T}) -> NamedTupleSummary statistics for GMM estimation.
MacroEconometricModels.identity_weighting — Method
identity_weighting(n_moments::Int, ::Type{T}=Float64) -> Matrix{T}Identity weighting matrix (one-step GMM).
MacroEconometricModels.j_test — Method
j_test(model::GMMModel{T}) -> NamedTupleHansen's J-test for overidentifying restrictions.
H0: All moment conditions are valid (E[g(θ₀)] = 0) H1: Some moment conditions are violated
Returns:
- J_stat: Test statistic
- p_value: p-value from chi-squared distribution
- df: Degrees of freedom (nmoments - nparams)
- reject_05: Whether to reject at 5% level
MacroEconometricModels.linear_gmm_solve — Method
linear_gmm_solve(S_ZX::Matrix{T}, S_Zy::AbstractVecOrMat{T},
W::Matrix{T}) -> Vector{T}Solve linear GMM analytically: E[Z'(y - Xβ)] = 0.
Given pre-aggregated cross-products SZX = Σi Zi'Xi and SZy = Σi Zi'yi:
β = (S_ZX' W S_ZX)⁻¹ S_ZX' W S_ZyArguments
S_ZX— q × k aggregated instrument-regressor cross-productS_Zy— q × 1 (or q-vector) aggregated instrument-response cross-productW— q × q weighting matrix
Returns
- Parameter vector β (length k)
MacroEconometricModels.lp_gmm_moments — Method
lp_gmm_moments(Y::AbstractMatrix{T}, shock_var::Int, h::Int, theta,
lags::Int) -> Matrix{T}Construct moment conditions for LP estimated via GMM.
Moments: E[Zt * ε{t+h}] = 0 where ε{t+h} = y{t+h} - θ' * X_t and Z includes all exogenous variables.
This is useful when you need to impose cross-equation restrictions.
MacroEconometricModels.minimize_gmm — Method
minimize_gmm(moment_fn::Function, theta0::AbstractVector{T}, data,
W::AbstractMatrix{T}; max_iter::Int=100, tol::T=T(1e-8)) -> NamedTupleMinimize GMM objective using Optim.jl (LBFGS with NelderMead fallback).
Returns:
- theta: Minimizer
- objective: Final objective value
- converged: Convergence flag
- iterations: Number of iterations
MacroEconometricModels.numerical_gradient — Method
numerical_gradient(f::Function, x::AbstractVector{T}; eps::T=T(1e-7)) -> Matrix{T}Compute numerical gradient (Jacobian) of function f at point x using central differences.
Arguments:
- f: Function that takes vector x and returns vector (moment conditions)
- x: Point at which to evaluate gradient
- eps: Step size for finite differences
Returns:
- Jacobian matrix (nmoments × nparams)
MacroEconometricModels.optimal_weighting_matrix — Method
optimal_weighting_matrix(moment_fn::Function, theta::AbstractVector{T}, data;
hac::Bool=true, bandwidth::Int=0) -> Matrix{T}Compute optimal GMM weighting matrix: W = inv(Var(g)).
For i.i.d. data: W = inv((1/n) Σᵢ gᵢ gᵢ') For time series: Uses HAC estimation with Newey-West kernel.
Arguments:
- moment_fn: Moment function
- theta: Current parameter estimate
- data: Data
- hac: Use HAC correction for serial correlation
- bandwidth: HAC bandwidth (0 = automatic)
Returns:
- Optimal weighting matrix (q × q)
Simulated Method of Moments
MacroEconometricModels._moment_covariance — Method
_moment_covariance(data, moments_fn; hac, bandwidth) -> Matrix{T}Internal: Compute long-run covariance of per-observation moment contributions. Shared by smm_weighting_matrix (inverted) and smm_data_covariance (raw).
MacroEconometricModels.autocovariance_moments — Method
autocovariance_moments(data::AbstractMatrix{T}; lags::Int=1) -> Vector{T}Compute standard DSGE moment vector from data matrix.
Returns: [upper-triangle variance-covariance elements; diagonal autocovariances at each lag]
For k variables, lags L: k*(k+1)/2 + k*L moments total.
Arguments
data–- T_obs x k data matrixlags–- number of autocovariance lags (default: 1)
MacroEconometricModels.estimate_smm — Method
estimate_smm(simulator_fn, moments_fn, theta0, data;
sim_ratio=5, burn=100, weighting=:two_step,
bounds=nothing, hac=true, bandwidth=0,
max_iter=1000, tol=1e-8,
rng=Random.default_rng()) -> SMMModel{T}Estimate parameters via Simulated Method of Moments.
Minimizes Q(theta) = (m_data - m_sim(theta))' W (m_data - m_sim(theta)) where m_data are data moments and m_sim(theta) are simulated moments.
Arguments
simulator_fn(theta, T_periods, burn; rng)–- simulates T_periods obs after discarding burnmoments_fn(data) -> Vector{T}–- computes moment vector from any T x k data matrixtheta0–- initial parameter guessdata–- observed data matrix (T x k)
Keywords
sim_ratio::Int=5–- tau = simulation periods / data periodsburn::Int=100–- burn-in periods for simulatorweighting::Symbol=:two_step–-:identityor:two_stepbounds::Union{Nothing,ParameterTransform}=nothing–- parameter boundshac::Bool=true–- HAC for weighting matrixbandwidth::Int=0–- HAC bandwidth (0 = automatic)max_iter::Int=1000–- max optimizer iterationstol=1e-8–- convergence tolerancerng–- random number generator (copied inside objective for deterministic simulation)
References
- Ruge-Murcia (2012), Lee & Ingram (1991)
MacroEconometricModels.j_test — Method
j_test(m::SMMModel{T}) -> NamedTupleHansen's J-test for overidentifying restrictions on an SMM model.
H0: All moment conditions are valid (E[g(theta_0)] = 0) H1: Some moment conditions are violated
Returns:
- J_stat: Test statistic
- p_value: p-value from chi-squared distribution
- df: Degrees of freedom (nmoments - nparams)
- reject_05: Whether to reject at 5% level
MacroEconometricModels.smm_data_covariance — Method
smm_data_covariance(data::AbstractMatrix{T}, moments_fn::Function;
hac::Bool=true, bandwidth::Int=0) -> Matrix{T}Compute long-run covariance Ω of data moment contributions for sandwich SE formula.
MacroEconometricModels.smm_weighting_matrix — Method
smm_weighting_matrix(data::AbstractMatrix{T}, moments_fn::Function;
hac::Bool=true, bandwidth::Int=0) -> Matrix{T}Compute optimal SMM weighting matrix from data moment contributions. Centers the per-observation moment contributions and applies HAC with Bartlett kernel.
Arguments
data— T_obs × k data matrixmoments_fn— function computing moment vector from datahac— use HAC correction (default: true)bandwidth— HAC bandwidth, 0 = automatic:floor(4*(n/100)^(2/9))
Parameter Transforms
MacroEconometricModels.to_unconstrained — Function
to_unconstrained(pt::ParameterTransform, theta::AbstractVector) -> VectorMap parameters from constrained (model) space to unconstrained (optimizer) space.
MacroEconometricModels.to_constrained — Function
to_constrained(pt::ParameterTransform, phi::AbstractVector) -> VectorMap parameters from unconstrained (optimizer) space to constrained (model) space.
MacroEconometricModels.transform_jacobian — Function
transform_jacobian(pt::ParameterTransform, phi::AbstractVector) -> MatrixDiagonal Jacobian ∂θ/∂φ of the inverse transform (unconstrained → constrained). Used for delta method SE correction.
Unit Root and Cointegration Tests
MacroEconometricModels.adf_test — Method
adf_test(y; lags=:aic, max_lags=nothing, regression=:constant) -> ADFResultAugmented Dickey-Fuller test for unit root.
Tests H₀: y has a unit root (non-stationary) against H₁: y is stationary.
Arguments
y: Time series vectorlags: Number of augmenting lags, or :aic/:bic/:hqic for automatic selectionmax_lags: Maximum lags for automatic selection (default: floor(12*(T/100)^0.25))regression: Deterministic terms - :none, :constant (default), or :trend
Returns
ADFResult containing test statistic, p-value, critical values, etc.
Example
y = cumsum(randn(200)) # Random walk (has unit root)
result = adf_test(y)
result.pvalue > 0.05 # Should fail to reject H₀References
- Dickey, D. A., & Fuller, W. A. (1979). Distribution of the estimators for autoregressive time series with a unit root. JASA, 74(366), 427-431.
- MacKinnon, J. G. (2010). Critical values for cointegration tests. Queen's Economics Department Working Paper No. 1227.
MacroEconometricModels.kpss_test — Method
kpss_test(y; regression=:constant, bandwidth=:auto) -> KPSSResultKwiatkowski-Phillips-Schmidt-Shin test for stationarity.
Tests H₀: y is stationary against H₁: y has a unit root.
Arguments
y: Time series vectorregression: :constant (level stationarity) or :trend (trend stationarity)bandwidth: Bartlett kernel bandwidth, or :auto for Newey-West selection
Returns
KPSSResult containing test statistic, p-value, critical values, etc.
Example
y = randn(200) # Stationary series
result = kpss_test(y)
result.pvalue > 0.05 # Should fail to reject H₀ (stationarity)References
- Kwiatkowski, D., Phillips, P. C., Schmidt, P., & Shin, Y. (1992). Testing the null hypothesis of stationarity against the alternative of a unit root. Journal of Econometrics, 54(1-3), 159-178.
MacroEconometricModels.pp_test — Method
pp_test(y; regression=:constant, bandwidth=:auto) -> PPResultPhillips-Perron test for unit root with non-parametric correction.
Tests H₀: y has a unit root against H₁: y is stationary.
Arguments
y: Time series vectorregression: :none, :constant (default), or :trendbandwidth: Newey-West bandwidth, or :auto for automatic selection
Returns
PPResult containing test statistic (Zt), p-value, critical values, etc.
Example
y = cumsum(randn(200)) # Random walk
result = pp_test(y)
result.pvalue > 0.05 # Should fail to reject H₀References
- Phillips, P. C., & Perron, P. (1988). Testing for a unit root in time series regression. Biometrika, 75(2), 335-346.
MacroEconometricModels._za_ao_at_break — Method
AO (additive outlier) model for a single break candidate.
Step 1: Detrend y via OLS on deterministics with break dummies → residuals e. Step 2: ADF regression on e with pulse dummy D(TB)_t = 1{t == tb} and its lags.
Returns (tstatonelag, lags_used).
MacroEconometricModels._za_io_at_break — Method
IO (innovational outlier) model for a single break candidate.
Regression: Δyt = μ + β·t + θ·DUt(tb) [+ δ·DTt(tb)] + γ·y{t-1} + Σδj·Δy{t-j} + et where DUt = 1{t >= tb} and DT_t = max(0, t - tb + 1).
Returns (tstatongamma, lagsused).
MacroEconometricModels.za_test — Method
za_test(y; regression=:both, trim=0.15, lags=:aic, max_lags=nothing, outlier=:io) -> ZAResultZivot-Andrews test for unit root with endogenous structural break.
Tests H₀: y has a unit root without break against H₁: y is stationary with break.
Arguments
y: Time series vectorregression: Type of break - :constant (intercept), :trend (slope), or :bothtrim: Trimming fraction for break search (default 0.15)lags: Number of augmenting lags, or :aic/:bic for automatic selectionmax_lags: Maximum lags for selectionoutlier: Outlier model - :io (innovational outlier) or :ao (additive outlier)
Returns
ZAResult containing minimum t-statistic, break point, p-value, etc.
Example
# Series with structural break
y = vcat(randn(100), randn(100) .+ 2)
result = za_test(y; regression=:constant)
# Additive outlier model
result_ao = za_test(y; regression=:constant, outlier=:ao)References
- Zivot, E., & Andrews, D. W. K. (1992). Further evidence on the great crash, the oil-price shock, and the unit-root hypothesis. JBES, 10(3), 251-270.
MacroEconometricModels.ngperron_test — Method
ngperron_test(y; regression=:constant) -> NgPerronResultNg-Perron unit root tests with GLS detrending (MZα, MZt, MSB, MPT).
Tests H₀: y has a unit root against H₁: y is stationary. These tests have better size properties than ADF/PP in small samples.
Arguments
y: Time series vectorregression: :constant (default) or :trend
Returns
NgPerronResult containing MZα, MZt, MSB, MPT statistics and critical values.
Example
y = cumsum(randn(100))
result = ngperron_test(y)
# Check if MZt rejects at 5%
result.MZt < result.critical_values[:MZt][5]References
- Ng, S., & Perron, P. (2001). Lag length selection and the construction of unit root tests with good size and power. Econometrica, 69(6), 1519-1554.
MacroEconometricModels.johansen_test — Method
johansen_test(Y, p; deterministic=:constant) -> JohansenResultJohansen cointegration test for VAR system.
Tests for the number of cointegrating relationships among variables using trace and maximum eigenvalue tests.
Arguments
Y: Data matrix (T × n)p: Number of lags in the VECM representationdeterministic: Specification for deterministic terms- :none - No deterministic terms
- :constant - Constant in cointegrating relation (default)
- :trend - Linear trend in levels
Returns
JohansenResult containing trace and max-eigenvalue statistics, cointegrating vectors, adjustment coefficients, and estimated rank.
Example
# Generate cointegrated system
n, T = 3, 200
Y = randn(T, n)
Y[:, 2] = Y[:, 1] + 0.1 * randn(T) # Y2 cointegrated with Y1
result = johansen_test(Y, 2)
result.rank # Should detect 1 or 2 cointegrating relationsReferences
- Johansen, S. (1991). Estimation and hypothesis testing of cointegration vectors in Gaussian vector autoregressive models. Econometrica, 59(6), 1551-1580.
- Osterwald-Lenum, M. (1992). A note with quantiles of the asymptotic distribution of the ML cointegration rank test statistics. Oxford BEJM.
MacroEconometricModels._build_fourier_adf_X — Method
Build design matrix for Fourier ADF regression.
MacroEconometricModels._fourier_adf_regression — Method
ADF regression with optional Fourier terms; returns (SSR, t-stat on gamma, lags used).
MacroEconometricModels._select_fourier_adf_lags — Method
Select lag order for Fourier ADF regression using information criteria.
MacroEconometricModels.fourier_adf_test — Method
fourier_adf_test(y; regression=:constant, fmax=3, lags=:aic, max_lags=nothing, trim=0.15) -> FourierADFResultFourier ADF unit root test with flexible Fourier form (Enders & Lee 2012).
Tests H0: unit root against H1: stationary with smooth structural breaks captured by low-frequency Fourier components.
Arguments
y: Time series vectorregression::constantor:trendfmax: Maximum Fourier frequency (default 3, max 5)lags: Number of augmenting lags, or:aic/:bicfor automatic selectionmax_lags: Maximum lags for IC selection (default: floor(12*(T/100)^0.25))trim: Trimming fraction (default 0.15)
References
- Enders, W., & Lee, J. (2012). A unit root test using a Fourier series to approximate smooth breaks. Oxford Bulletin of Economics and Statistics, 74(4), 574-599.
MacroEconometricModels.fourier_kpss_test — Method
fourier_kpss_test(y; regression=:constant, fmax=3, bandwidth=nothing) -> FourierKPSSResultFourier KPSS stationarity test (Becker, Enders & Lee 2006).
Tests H0: stationary (with Fourier terms) against H1: unit root.
Arguments
y: Time series vectorregression::constantor:trendfmax: Maximum Fourier frequency (default 3, max 3 for KPSS tables)bandwidth: Bartlett kernel bandwidth (default: Newey-West)
References
- Becker, R., Enders, W., & Lee, J. (2006). A stationarity test in the presence of an unknown number of smooth breaks. Journal of Time Series Analysis, 27(3), 381-409.
MacroEconometricModels.dfgls_test — Method
dfgls_test(y; regression=:constant, lags=:aic, max_lags=nothing) -> DFGLSResultDF-GLS unit root test (Elliott, Rothenberg & Stock 1996).
Tests H₀: unit root against H₁: stationary using GLS-detrended data. Reports DF-GLS τ statistic, ERS Pt statistic, and MGLS statistics.
Arguments
y: Time series vectorregression::constantor:trendlags: Number of lags, or:aic/:bicfor automatic selectionmax_lags: Maximum lags for IC selection
References
- Elliott, G., Rothenberg, T. J., & Stock, J. H. (1996). Efficient tests for an autoregressive unit root. Econometrica, 64(4), 813-836.
- Ng, S., & Perron, P. (2001). Lag length selection and the construction of unit root tests with good size and power. Econometrica, 69(6), 1519-1554.
MacroEconometricModels.lm_unitroot_test — Method
lm_unitroot_test(y; breaks=0, regression=:level, lags=:aic, max_lags=nothing, trim=0.15) -> LMUnitRootResultLM unit root test (Schmidt-Phillips 1992; Lee-Strazicich 2003, 2013).
Tests H₀: unit root (with breaks under H₀) against H₁: stationary.
Arguments
y: Time series vectorbreaks: Number of structural breaks (0, 1, or 2)regression::levelfor intercept break,:bothfor intercept + trend breaklags: Number of augmenting lags, or:aic/:bicmax_lags: Maximum lags for IC selectiontrim: Trimming fraction (default 0.15)
References
- Schmidt, P., & Phillips, P. C. B. (1992). LM tests for a unit root in the presence of deterministic trends. Oxford Bulletin of Economics and Statistics, 54(3), 257-287.
- Lee, J., & Strazicich, M. C. (2003). Minimum Lagrange multiplier unit root test with two structural breaks. Review of Economics and Statistics, 85(4), 1082-1089.
- Lee, J., & Strazicich, M. C. (2013). Minimum LM unit root test with one structural break. Economics Bulletin, 33(4), 2483-2492.
MacroEconometricModels.adf_2break_test — Method
adf_2break_test(y; model=:level, lags=:aic, max_lags=nothing, trim=0.10) -> ADF2BreakResultADF unit root test with two structural breaks (Narayan & Popp 2010).
Tests H₀: unit root with two breaks against H₁: stationary with two breaks.
Arguments
y: Time series vectormodel::level(level shifts only) or:both(level + trend shifts)lags: Number of augmenting lags, or:aic/:bicmax_lags: Maximum lags for IC selectiontrim: Trimming fraction (default 0.10)
References
- Narayan, P. K., & Popp, S. (2010). A new unit root test with two structural breaks in level and slope at unknown time. Journal of Applied Statistics, 22(2), 206-233.
MacroEconometricModels.gregory_hansen_test — Method
gregory_hansen_test(Y; model=:C, lags=:aic, max_lags=nothing, trim=0.15) -> GregoryHansenResultGregory-Hansen cointegration test with structural break (Gregory & Hansen 1996).
Tests H₀: no cointegration against H₁: cointegration with a structural break.
Arguments
Y: T×n matrix where Y[:,1] is the dependent variable and Y[:,2:end] are regressorsmodel::C(level shift),:CT(level + trend shift),:CS(regime shift)lags: Number of augmenting lags for ADF, or:aic/:bicmax_lags: Maximum lags for IC selectiontrim: Trimming fraction (default 0.15)
References
- Gregory, A. W., & Hansen, B. E. (1996). Residual-based tests for cointegration in models with regime shifts. Journal of Econometrics, 70(1), 99-126.
MacroEconometricModels.is_stationary — Method
is_stationary(model::VARModel) -> VARStationarityResultCheck if estimated VAR model is stationary.
A VAR(p) is stationary if and only if all eigenvalues of the companion matrix have modulus strictly less than 1.
Returns
VARStationarityResult with:
is_stationary: Boolean indicating stationarityeigenvalues: Complex eigenvalues of companion matrixmax_modulus: Maximum eigenvalue moduluscompanion_matrix: The (np × np) companion form matrix
Example
model = estimate_var(Y, 2)
result = is_stationary(model)
if !result.is_stationary
println("Warning: VAR is non-stationary, max modulus = ", result.max_modulus)
endMacroEconometricModels.test_all_variables — Method
test_all_variables(Y; test=:adf, kwargs...) -> VectorApply unit root test to each column of Y.
Arguments
Y: Data matrix (T × n)test: Test to apply (:adf, :kpss, :pp, :za, :ngperron)kwargs...: Additional arguments passed to the test
Returns
Vector of test results, one per variable.
Example
Y = randn(200, 3)
Y[:, 1] = cumsum(Y[:, 1]) # Make first column non-stationary
results = test_all_variables(Y; test=:adf)
[r.pvalue for r in results] # P-values for each variableMacroEconometricModels.unit_root_summary — Method
unit_root_summary(y; tests=[:adf, :kpss, :pp], kwargs...) -> NamedTupleRun multiple unit root tests and return summary with PrettyTables output.
Arguments
y: Time series vectortests: Vector of test symbols to run (default: [:adf, :kpss, :pp])kwargs...: Additional arguments passed to individual tests
Returns
NamedTuple with test results, conclusion, and summary table.
Example
y = cumsum(randn(200))
summary = unit_root_summary(y)
summary.conclusion # Overall conclusionModel Comparison Tests
MacroEconometricModels.lr_test — Function
lr_test(m1, m2) -> LRTestResultLikelihood ratio test for nested models.
Computes LR = -2(ℓR - ℓU) where the restricted model has fewer parameters. Under H₀ (restricted model is correct), LR ~ χ²(df) where df = dofU - dofR.
Works for any two models implementing loglikelihood, dof, and nobs from StatsAPI. Automatically determines which model is restricted by comparing degrees of freedom.
Arguments
m1,m2: Two fitted models (order does not matter)
Returns
LRTestResult with test statistic, p-value, and model details.
Example
ar2 = estimate_ar(y, 2; method=:mle)
ar4 = estimate_ar(y, 4; method=:mle)
result = lr_test(ar2, ar4)MacroEconometricModels.lm_test — Function
lm_test(m1, m2) -> LMTestResultLagrange multiplier (score) test for nested models.
Evaluates the score of the unrestricted log-likelihood at the restricted parameter estimates. Under H₀, LM = s'(-H)⁻¹s ~ χ²(df) where df = dofU - dofR.
Automatically determines restricted/unrestricted by comparing dof. Dispatches to model-family specific implementations for ARIMA, VAR, and volatility models.
Supported model pairs
AbstractARIMAModel×AbstractARIMAModel(same differencing orderd)VARModel×VARModel(different lag orders, same data)ARCHModel×ARCHModel,GARCHModel×GARCHModelARCHModel×GARCHModel(cross-type nesting)EGARCHModel×EGARCHModel,GJRGARCHModel×GJRGARCHModel
Arguments
m1,m2: Two fitted models from the same family (order does not matter)
Returns
LMTestResult with test statistic, p-value, and score norm diagnostic.
Example
ar2 = estimate_ar(y, 2; method=:mle)
ar4 = estimate_ar(y, 4; method=:mle)
result = lm_test(ar2, ar4)Granger Causality Tests
MacroEconometricModels.granger_test — Function
granger_test(model::VARModel, cause::Int, effect::Int) -> GrangerCausalityResultTest whether variable cause Granger-causes variable effect in a VAR model.
H₀: A₁[effect, cause] = A₂[effect, cause] = ... = Aₚ[effect, cause] = 0 H₁: At least one lag coefficient is nonzero
Uses a Wald χ² test with df = p (number of lags).
Arguments
model: EstimatedVARModelcause: Index of the causing variable (1-based)effect: Index of the effect variable (1-based)
Returns
GrangerCausalityResult with Wald statistic, p-value, and test details.
Example
Y = randn(200, 3)
m = estimate_var(Y, 2)
g = granger_test(m, 1, 2) # does variable 1 Granger-cause variable 2?granger_test(model::VARModel, cause::Vector{Int}, effect::Int) -> GrangerCausalityResultTest whether a group of variables cause jointly Granger-cause variable effect.
H₀: All lag coefficients from cause variables to the effect equation are zero H₁: At least one lag coefficient is nonzero
Uses a Wald χ² test with df = p × length(cause).
Arguments
model: EstimatedVARModelcause: Indices of the causing variables (1-based)effect: Index of the effect variable (1-based)
Returns
GrangerCausalityResult with Wald statistic, p-value, and test details.
Example
Y = randn(200, 4)
m = estimate_var(Y, 2)
g = granger_test(m, [1, 2], 3) # do variables 1 and 2 jointly Granger-cause variable 3?MacroEconometricModels.granger_test_all — Function
granger_test_all(model::VARModel) -> Matrix{Union{GrangerCausalityResult, Nothing}}Compute pairwise Granger causality tests for all variable pairs in a VAR model.
Returns an n×n matrix where entry [i,j] tests whether variable j Granger-causes variable i. Diagonal entries are nothing.
Arguments
model: EstimatedVARModel
Returns
n×n matrix of GrangerCausalityResult (or nothing on diagonal).
Example
Y = randn(200, 3)
m = estimate_var(Y, 2)
results = granger_test_all(m)
results[2, 1] # does variable 1 Granger-cause variable 2?Volatility Models
ARCH Estimation and Diagnostics
MacroEconometricModels.estimate_arch — Function
estimate_arch(y, q; method=:mle) -> ARCHModelEstimate ARCH(q) model via Maximum Likelihood.
σ²ₜ = ω + α₁ε²ₜ₋₁ + ... + αqε²ₜ₋q
Uses two-stage optimization: NelderMead initialization → LBFGS refinement.
Arguments
y: Time series vectorq: ARCH order (≥ 1)method: Estimation method (currently only:mle)
Returns
ARCHModel with estimated parameters and conditional variances.
Example
y = randn(500)
model = estimate_arch(y, 1)
println("ω = ", model.omega, ", α₁ = ", model.alpha[1])MacroEconometricModels.arch_lm_test — Function
arch_lm_test(y_or_model, q=5)ARCH-LM test for conditional heteroskedasticity (Engle 1982).
H₀: No ARCH effects (α₁ = ... = αq = 0) H₁: ARCH(q) effects present
Test statistic: T·R² from regression of ε²ₜ on ε²ₜ₋₁,...,ε²ₜ₋q, distributed χ²(q).
Arguments
y_or_model: Raw data vector or AbstractVolatilityModel (uses standardized residuals)q: Number of lags (default 5)
Returns
Named tuple (statistic, pvalue, q).
Example
result = arch_lm_test(randn(500), 5)
println("p-value: ", result.pvalue)MacroEconometricModels.ljung_box_squared — Function
ljung_box_squared(z_or_model, K=10)Ljung-Box test on squared (standardized) residuals.
H₀: No serial correlation in z²ₜ H₁: Serial correlation present in z²ₜ
Test statistic: Q = n(n+2) Σₖ ρ̂²ₖ/(n-k), distributed χ²(K).
Arguments
z_or_model: Standardized residuals vector or AbstractVolatilityModelK: Number of lags (default 10)
Returns
Named tuple (statistic, pvalue, K).
GARCH Estimation and Diagnostics
MacroEconometricModels.estimate_garch — Function
estimate_garch(y, p=1, q=1; method=:mle) -> GARCHModelEstimate GARCH(p,q) model via Maximum Likelihood (Bollerslev 1986).
σ²ₜ = ω + α₁ε²ₜ₋₁ + ... + αqε²ₜ₋q + β₁σ²ₜ₋₁ + ... + βpσ²ₜ₋p
Arguments
y: Time series vectorp: GARCH order (default 1)q: ARCH order (default 1)method: Estimation method (currently only:mle)
Example
model = estimate_garch(y, 1, 1)
println("Persistence: ", persistence(model))MacroEconometricModels.estimate_egarch — Function
estimate_egarch(y, p=1, q=1; method=:mle) -> EGARCHModelEstimate EGARCH(p,q) model via Maximum Likelihood (Nelson 1991).
log(σ²ₜ) = ω + Σαᵢ(|zₜ₋ᵢ| - E|z|) + Σγᵢzₜ₋ᵢ + Σβⱼlog(σ²ₜ₋ⱼ)
The γ parameters capture leverage effects (typically γ < 0 for equities).
Arguments
y: Time series vectorp: GARCH order (default 1)q: ARCH order (default 1)method: Estimation method (currently only:mle)
Example
model = estimate_egarch(y, 1, 1)
println("Leverage: ", model.gamma[1])MacroEconometricModels.estimate_gjr_garch — Function
estimate_gjr_garch(y, p=1, q=1; method=:mle) -> GJRGARCHModelEstimate GJR-GARCH(p,q) model via Maximum Likelihood (Glosten, Jagannathan & Runkle 1993).
σ²ₜ = ω + Σ(αᵢ + γᵢI(εₜ₋ᵢ<0))ε²ₜ₋ᵢ + Σβⱼσ²ₜ₋ⱼ
γᵢ > 0 captures the asymmetric (leverage) effect.
Arguments
y: Time series vectorp: GARCH order (default 1)q: ARCH order (default 1)method: Estimation method (currently only:mle)
Example
model = estimate_gjr_garch(y, 1, 1)
println("Asymmetry: ", model.gamma[1])MacroEconometricModels.news_impact_curve — Function
news_impact_curve(m; range=(-3,3), n_points=200)Compute the news impact curve: how a shock εₜ₋₁ maps to σ²ₜ, holding all else at unconditional values.
Returns named tuple (shocks, variance) where both are vectors of length n_points.
Supported models
GARCHModel: Symmetric parabolaGJRGARCHModel: Asymmetric parabola (steeper for negative shocks)EGARCHModel: Asymmetric exponential curve
Stochastic Volatility
MacroEconometricModels.estimate_sv — Function
estimate_sv(y; n_samples=2000, burnin=1000,
dist=:normal, leverage=false,
quantile_levels=[0.025, 0.5, 0.975]) -> SVModelEstimate a Stochastic Volatility model via Kim-Shephard-Chib (1998) Gibbs sampler with Omori et al. (2007) 10-component mixture approximation.
Model
yₜ = exp(hₜ/2) εₜ, εₜ ~ N(0,1)
hₜ = μ + φ(hₜ₋₁ - μ) + σ_η ηₜ, ηₜ ~ N(0,1)Arguments
y: Time series vectorn_samples: Number of posterior samples to keep (default 2000)burnin: Number of burn-in iterations to discard (default 1000)dist: Error distribution (:normalor:studentt)leverage: Whether to include leverage effect (correlated innovations)quantile_levels: Quantile levels for volatility posterior
Example
y = randn(200) .* exp.(cumsum(0.1 .* randn(200)) ./ 2)
model = estimate_sv(y; n_samples=1000)
println("φ = ", mean(model.phi_post))Volatility Forecasting
MacroEconometricModels.forecast — Method
forecast(m::ARCHModel, h; conf_level=0.95, n_sim=10000) -> VolatilityForecastForecast conditional variance from an ARCH(q) model.
For h > q, the forecast converges to the unconditional variance. Confidence intervals are computed via simulation.
Arguments
m: Fitted ARCHModelh: Forecast horizonconf_level: Confidence level for intervals (default 0.95)n_sim: Number of simulation paths for CIs (default 10000)
MacroEconometricModels.forecast — Method
forecast(m::EGARCHModel, h; conf_level=0.95, n_sim=10000) -> VolatilityForecastForecast conditional variance from an EGARCH(p,q) model via simulation.
MacroEconometricModels.forecast — Method
forecast(m::GARCHModel, h; conf_level=0.95, n_sim=10000) -> VolatilityForecastForecast conditional variance from a GARCH(p,q) model.
Uses analytical iteration for point forecasts and simulation for CIs. Point forecasts converge to unconditional variance as h → ∞.
MacroEconometricModels.forecast — Method
forecast(m::GJRGARCHModel, h; conf_level=0.95, n_sim=10000) -> VolatilityForecastForecast conditional variance from a GJR-GARCH(p,q) model via simulation.
MacroEconometricModels.forecast — Method
forecast(m::SVModel, h; conf_level=0.95) -> VolatilityForecastPosterior predictive forecast of volatility from an SV model.
For each posterior draw (μ, φ, ση), simulates the log-volatility path forward h{T+1}, ..., h_{T+h} and returns quantiles of exp(hₜ).
Arguments
m: Fitted SVModelh: Forecast horizonconf_level: Confidence level for intervals (default 0.95)
Volatility Accessors
MacroEconometricModels.persistence — Function
Return persistence Σαᵢ for ARCH model.
MacroEconometricModels.halflife — Function
Return half-life of volatility shocks: log(0.5) / log(persistence).
MacroEconometricModels.unconditional_variance — Function
Return unconditional variance ω / (1 - Σαᵢ).
MacroEconometricModels.arch_order — Function
Return ARCH order q.
MacroEconometricModels.garch_order — Function
Return GARCH order p.
Volatility StatsAPI Interface
StatsAPI.nobs — Method
Number of observations.
StatsAPI.coef — Method
Coefficient vector [μ, ω, α₁, …, αq].
StatsAPI.residuals — Method
Raw residuals $\hat{\varepsilon}_t$.
StatsAPI.aic — Method
Akaike Information Criterion.
StatsAPI.bic — Method
Bayesian Information Criterion.
StatsAPI.dof — Method
Number of estimated parameters: 2 + q (μ + ω + q alphas).
StatsAPI.islinear — Method
false — ARCH models are nonlinear.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.coef — Method
Coefficient vector [μ, ω, α₁, …, αq, β₁, …, βp].
StatsAPI.residuals — Method
Raw residuals $\hat{\varepsilon}_t$.
StatsAPI.aic — Method
Akaike Information Criterion.
StatsAPI.bic — Method
Bayesian Information Criterion.
StatsAPI.dof — Method
Number of estimated parameters: 2 + q + p.
StatsAPI.islinear — Method
false — GARCH models are nonlinear.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.coef — Method
Coefficient vector [μ, ω, α₁, …, αq, γ₁, …, γq, β₁, …, βp].
StatsAPI.residuals — Method
Raw residuals $\hat{\varepsilon}_t$.
StatsAPI.aic — Method
Akaike Information Criterion.
StatsAPI.bic — Method
Bayesian Information Criterion.
StatsAPI.dof — Method
Number of estimated parameters: 2 + 2q + p.
StatsAPI.islinear — Method
false — EGARCH models are nonlinear.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.coef — Method
Coefficient vector [μ, ω, α₁, …, αq, γ₁, …, γq, β₁, …, βp].
StatsAPI.residuals — Method
Raw residuals $\hat{\varepsilon}_t$.
StatsAPI.aic — Method
Akaike Information Criterion.
StatsAPI.bic — Method
Bayesian Information Criterion.
StatsAPI.dof — Method
Number of estimated parameters: 2 + 2q + p.
StatsAPI.islinear — Method
false — GJR-GARCH models are nonlinear.
StatsAPI.nobs — Method
Number of observations.
StatsAPI.coef — Method
Posterior mean coefficients [μ, φ, σ_η].
StatsAPI.residuals — Method
Standardized residuals $y_t / \sqrt{\hat{\sigma}^2_t}$.
StatsAPI.islinear — Method
false — SV models are nonlinear.
StatsAPI.stderror — Method
StatsAPI.stderror(m::ARCHModel{T}) -> Vector{T}MLE standard errors for ARCH model via numerical Hessian. Returns SE vector matching coef(m) = [μ, ω, α₁, ..., αq].
StatsAPI.stderror(m::GARCHModel{T}) -> Vector{T}MLE standard errors for GARCH model via numerical Hessian + delta method. Returns SE vector matching coef(m) = [μ, ω, α₁..αq, β₁..βp].
StatsAPI.stderror(m::EGARCHModel{T}) -> Vector{T}MLE standard errors for EGARCH model via numerical Hessian. EGARCH params are unconstrained — no delta method needed. Returns SE vector matching coef(m) = [μ, ω, α₁..αq, γ₁..γq, β₁..βp].
StatsAPI.stderror(m::GJRGARCHModel{T}) -> Vector{T}MLE standard errors for GJR-GARCH model via numerical Hessian + delta method. Returns SE vector matching coef(m) = [μ, ω, α₁..αq, γ₁..γq, β₁..βp].
StatsAPI.confint — Method
Confidence intervals for volatility model parameters.
Nowcasting
Estimation
MacroEconometricModels.nowcast_dfm — Function
nowcast_dfm(Y, nM, nQ; r=2, p=1, idio=:ar1, blocks=nothing,
max_iter=100, thresh=1e-4) -> NowcastDFM{T}Estimate a dynamic factor model on mixed-frequency data with missing values.
The first nM columns of Y are monthly variables; the next nQ columns are quarterly variables (observed every 3rd month, NaN otherwise).
Arguments
Y::AbstractMatrix— T_obs × N data matrix (NaN for missing)nM::Int— number of monthly variablesnQ::Int— number of quarterly variables
Keyword Arguments
r::Int=2— number of factorsp::Int=1— VAR lags in factor dynamicsidio::Symbol=:ar1— idiosyncratic component (:ar1or:iid)blocks::Union{Matrix{Int},Nothing}=nothing— block structure (N × n_blocks)max_iter::Int=100— maximum EM iterationsthresh::Real=1e-4— convergence threshold (relative log-likelihood change)
Returns
NowcastDFM{T} with smoothed data, factors, and state-space parameters.
References
- Bańbura, M. & Modugno, M. (2014). Maximum Likelihood Estimation of Factor Models on Datasets with Arbitrary Pattern of Missing Data.
MacroEconometricModels.nowcast_bvar — Function
nowcast_bvar(Y, nM, nQ; lags=5, thresh=1e-6, max_iter=200,
lambda0=0.2, theta0=1.0, miu0=1.0, alpha0=2.0) -> NowcastBVAR{T}Estimate a large BVAR for mixed-frequency nowcasting.
The first nM columns are monthly variables; the next nQ columns are quarterly (observed every 3rd month). The BVAR is estimated on the complete (non-NaN) portion, then the Kalman smoother fills the ragged edge.
Arguments
Y::AbstractMatrix— T_obs × N data matrix (NaN for missing)nM::Int— number of monthly variablesnQ::Int— number of quarterly variables
Keyword Arguments
lags::Int=5— number of lagsthresh::Real=1e-6— optimization convergence thresholdmax_iter::Int=200— max optimization iterationslambda0::Real=0.2— initial overall shrinkagetheta0::Real=1.0— initial cross-variable shrinkagemiu0::Real=1.0— initial sum-of-coefficients weightalpha0::Real=2.0— initial co-persistence weight
Returns
NowcastBVAR{T} with smoothed data and posterior parameters.
References
- Cimadomo, J., Giannone, D., Lenza, M., Monti, F. & Sokol, A. (2022). Nowcasting with Large Bayesian Vector Autoregressions.
MacroEconometricModels.nowcast_bridge — Function
nowcast_bridge(Y, nM, nQ; lagM=1, lagQ=1, lagY=1) -> NowcastBridge{T}Estimate bridge equation combination nowcast.
Each bridge equation uses a pair of monthly indicators (aggregated to quarterly) plus optional lagged quarterly variables and autoregressive terms to predict the target quarterly variable (last column).
Arguments
Y::AbstractMatrix— T_obs × N data matrix (NaN for missing)nM::Int— number of monthly variablesnQ::Int— number of quarterly variables (lastnQcolumns)
Keyword Arguments
lagM::Int=1— lags for monthly indicators (after quarterly aggregation)lagQ::Int=1— lags for quarterly indicatorslagY::Int=1— autoregressive lags for target variable
Returns
NowcastBridge{T} with combined and individual nowcasts.
References
- Bańbura, M., Belousova, I., Bodnár, K. & Tóth, M. B. (2023). Nowcasting Employment in the Euro Area. ECB Working Paper No 2815.
Nowcast and Forecast
MacroEconometricModels.nowcast — Function
nowcast(model::AbstractNowcastModel; target_var=nothing) -> NowcastResult{T}Generate nowcast result from an estimated nowcasting model.
Returns the current-quarter nowcast and next-quarter forecast for the target variable (default: last quarterly variable).
Arguments
model::AbstractNowcastModel— estimated nowcast model
Keyword Arguments
target_var::Union{Int,Nothing}=nothing— target variable index (default: last column)
Returns
NowcastResult{T} with nowcast and forecast values.
MacroEconometricModels.forecast — Method
forecast(model::NowcastDFM, h; target_var=nothing) -> Vector{T}Generate h-step ahead monthly forecast from DFM nowcasting model.
Arguments
model::NowcastDFM— estimated modelh::Int— forecast horizon (months)
Keyword Arguments
target_var::Union{Int,Nothing}— variable to forecast (default: all)
Returns
Vector of h forecast values (if target_var specified) or Matrix h × N.
MacroEconometricModels.nowcast — Method
nowcast(model::AbstractNowcastModel; target_var=nothing) -> NowcastResult{T}Generate nowcast result from an estimated nowcasting model.
Returns the current-quarter nowcast and next-quarter forecast for the target variable (default: last quarterly variable).
Arguments
model::AbstractNowcastModel— estimated nowcast model
Keyword Arguments
target_var::Union{Int,Nothing}=nothing— target variable index (default: last column)
Returns
NowcastResult{T} with nowcast and forecast values.
News Decomposition
MacroEconometricModels.nowcast_news — Function
nowcast_news(X_new, X_old, model::NowcastDFM, target_period;
target_var=size(X_new,2), groups=nothing) -> NowcastNews{T}Compute news decomposition between two data vintages.
Identifies new data releases (positions where X_old is NaN but X_new is not), computes their individual impacts on the nowcast via Kalman gain weights, and decomposes the total revision.
Arguments
X_new::AbstractMatrix— new data vintage (T_obs × N)X_old::AbstractMatrix— old data vintage (same size, more NaN)model::NowcastDFM— estimated DFM modeltarget_period::Int— time period for which to compute nowcast
Keyword Arguments
target_var::Int— target variable index (default: last column)groups::Union{Vector{Int},Nothing}— group assignment per variable (for aggregation)
Returns
NowcastNews{T} with per-release impacts and total decomposition.
References
- Bańbura, M. & Modugno, M. (2014). Maximum Likelihood Estimation of Factor Models on Datasets with Arbitrary Pattern of Missing Data.
Panel Balancing
MacroEconometricModels.balance_panel — Function
balance_panel(pd::PanelData; method=:dfm, r=3, p=2) -> PanelDataBalance a panel dataset by filling missing values (NaN) using DFM-based nowcasting to estimate missing observations.
For each group with missing data, runs nowcast_dfm treating all variables as monthly (nM = n_vars, nQ = 0) to obtain Kalman-smoothed estimates.
Arguments
pd::PanelData— input panel data (may be unbalanced or have NaN)
Keyword Arguments
method::Symbol=:dfm— fill method (currently only:dfm)r::Int=3— number of factors for DFMp::Int=2— VAR lags in DFM factor dynamics
Returns
New PanelData with NaN filled and balanced=true if applicable.
Examples
pd = xtset(df, :id, :t)
pd_bal = balance_panel(pd; r=2, p=1)
isbalanced(pd_bal)Nowcast Display
MacroEconometricModels.report — Method
report(m::AbstractNowcastModel)Print comprehensive nowcasting model summary.
DSGE Models
Specification
MacroEconometricModels.@dsge — Macro
@dsge begin ... endParse a DSGE model specification block into a DSGESpec{Float64}.
Declaration syntax
spec = @dsge begin
parameters: ρ = 0.9, σ = 0.01
endogenous: C, K, Y, A
exogenous: ε_A
C[t] + K[t] = (1-δ)*K[t-1] + K[t-1]^α
A[t] = ρ * A[t-1] + σ * ε_A[t]
endTime references: var[t] (current), var[t-1] (lagged), var[t+1] (lead). Expectations operator: E[t](expr) is stripped under rational expectations.
Returns a DSGESpec{Float64} with callable residual functions f(y_t, y_lag, y_lead, ε, θ) → scalar.
Steady State
MacroEconometricModels.compute_steady_state — Function
compute_steady_state(spec::DSGESpec{T}; initial_guess=nothing, method=:auto,
ss_fn=nothing, constraints=DSGEConstraint[],
solver=nothing, algorithm=nothing) → DSGESpec{T}Compute the deterministic steady state: f(yss, yss, y_ss, 0, θ) = 0.
Returns a new DSGESpec with the steady_state field filled.
Keywords
initial_guess::Vector{T}— starting point (default: ones)method::Symbol—:auto(NonlinearSolve),:analyticalss_fn::Function— for:analytical, a functionθ → y_ss::Vectorconstraints::Vector{<:DSGEConstraint}— variable bounds and nonlinear inequalitiessolver::Symbol—:nonlinearsolve(default),:optim(Fminbox),:nlopt(SLSQP),:ipopt(NLP), or:path(MCP); auto-detected if not specifiedalgorithm— NonlinearSolve.jl algorithm (default:TrustRegion()); passed through to chosen backend
MacroEconometricModels.linearize — Function
linearize(spec::DSGESpec{T}) → LinearDSGE{T}Linearize a DSGE model around its steady state using numerical Jacobians.
The model f(y_t, y_{t-1}, y_{t+1}, ε, θ) = 0 is expanded to first order. Rearranging into Sims form: Γ₀·y_t = Γ₁·y_{t-1} + C + Ψ·ε_t + Π·η_t.
Requires compute_steady_state to have been called first.
Solution Methods
MacroEconometricModels.solve — Function
solve(spec::DSGESpec{T}; method=:gensys, kwargs...) -> DSGESolution or PerfectForesightPath or PerturbationSolutionSolve a DSGE model.
Methods
:gensys– Sims (2002) QZ decomposition (default):blanchard_kahn– Blanchard-Kahn (1980) eigenvalue counting:klein– Klein (2000) generalized Schur decomposition:perturbation– Higher-order perturbation (Schmitt-Grohe & Uribe 2004); passorder=2for second-order:projection– Chebyshev collocation (Judd 1998); passdegree=5for polynomial degree:pfi– Policy Function Iteration / Time Iteration (Coleman 1990); passdegree=5,damping=1.0:vfi– Value Function Iteration (Stokey-Lucas-Prescott 1989); passdegree=5,howard_steps=0:perfect_foresight– deterministic Newton solver
MacroEconometricModels.gensys — Function
gensys(Gamma0, Gamma1, C, Psi, Pi; div=1.0+1e-8) -> NamedTupleSolve the linear RE system via QZ decomposition (Sims 2002).
Returns (G1, impact, C_sol, eu, eigenvalues) where:
eu = [exist, unique]: 1=yes, 0=nodivis the dividing line between stable (|lambda| < div) and unstable eigenvalues.
MacroEconometricModels.blanchard_kahn — Function
blanchard_kahn(ld::LinearDSGE{T}, spec::DSGESpec{T}) -> DSGESolution{T}Solve the linearized DSGE model via the Blanchard-Kahn method.
The BK condition requires that the number of eigenvalues with modulus > 1 equals the number of forward-looking (non-predetermined) variables.
MacroEconometricModels.klein — Function
klein(Gamma0, Gamma1, C, Psi, n_predetermined; div=1.0) → NamedTupleSolve the linear RE system via the Klein (2000) QZ decomposition method.
The system is in Sims canonical form: Gamma0 * y_t = Gamma1 * y_{t-1} + C + Psi * eps_t + Pi * eta_t
Klein computes the generalized Schur decomposition of the pencil (Gamma0, Gamma1), reorders eigenvalues so stable roots (|λ| < div) come first, and checks the Blanchard-Kahn condition: nstable == npredetermined.
Arguments
Gamma0— n × n coefficient on y_tGamma1— n × n coefficient on y_{t-1}C— n × 1 constant vectorPsi— n × n_shocks shock loading matrixn_predetermined— number of predetermined (state) variables
Keywords
div::Real=1.0— dividing line for stable vs unstable eigenvalues
Returns
Named tuple (G1, impact, C_sol, eu, eigenvalues) where:
G1— n × n state transition matriximpact— n × n_shocks impact matrixC_sol— n × 1 constantseu—[existence, uniqueness]: 1=yes, 0=noeigenvalues— generalized eigenvalues from QZ decomposition
MacroEconometricModels.perturbation_solver — Function
perturbation_solver(spec::DSGESpec{T}; order::Int=2, method::Symbol=:gensys) → PerturbationSolution{T}Compute a perturbation approximation to the policy functions of a DSGE model.
Arguments
spec— DSGE model specification (must have computed steady state)
Keywords
order::Int=2— perturbation order (1, 2, or 3)method::Symbol=:gensys— first-order solver (:gensysor:blanchard_kahn)
Returns
A PerturbationSolution{T} containing the policy function coefficients:
- Order 1:
gx(ny x nv),hx(nx x nv) where nv = nx + n_epsilon - Order 2: additionally
gxx,hxx(nv^2 columns),g_sigma_sigma,h_sigma_sigma - Order 3: additionally
gxxx,hxxx(nv^3 columns),gσσx,hσσx,gσσσ,hσσσ
Algorithm
- Solve the first-order system via gensys/BK to get G1, impact
- Partition variables into states (x) and controls (y) via Gamma1
- Build the innovations vector v = [x{t-1}; epsilont] and mapping matrices
- For order >= 2: compute Hessians, assemble the Kronecker system, solve for f_vv
- Solve the sigma^2 correction: fsigmasigma
References
- Schmitt-Grohe & Uribe (2004), JEDC 28(4), 755-775.
- Kim, Kim, Schaumburg & Sims (2008), JEDC 32(11), 3397-3414.
MacroEconometricModels.collocation_solver — Function
collocation_solver(spec::DSGESpec{T}; kwargs...) -> ProjectionSolution{T}Solve DSGE model via Chebyshev collocation (projection method).
Keyword Arguments
degree::Int=5: Chebyshev polynomial degreegrid::Symbol=:auto::tensor,:smolyak, or:autosmolyak_mu::Int=3: Smolyak exactness levelquadrature::Symbol=:auto::gauss_hermite,:monomial, or:auton_quad::Int=5: quadrature nodes per shock dimensionscale::Real=3.0: state bounds = SS +/- scale * sigmatol::Real=1e-8: Newton convergence tolerancemax_iter::Int=100: maximum Newton iterationsthreaded::Bool=false: enable multi-threaded Jacobian evaluationverbose::Bool=false: print iteration infoinitial_coeffs::Union{Nothing,AbstractMatrix{<:Real}}=nothing: warm-start coefficients (nvars x nbasis)
MacroEconometricModels.pfi_solver — Function
pfi_solver(spec::DSGESpec{T}; kwargs...) -> ProjectionSolution{T}Solve DSGE model via Policy Function Iteration (Time Iteration).
At each iteration: (1) compute expected next-period values using quadrature, (2) solve Euler equation at each grid point via Newton, (3) refit Chebyshev coefficients via least squares.
Keyword Arguments
degree::Int=5: Chebyshev polynomial degreegrid::Symbol=:auto::tensor,:smolyak, or:autosmolyak_mu::Int=3: Smolyak exactness levelquadrature::Symbol=:auto::gauss_hermite,:monomial, or:auton_quad::Int=5: quadrature nodes per shock dimensionscale::Real=3.0: state bounds = SS ± scale × σtol::Real=1e-8: sup-norm convergence tolerancemax_iter::Int=500: maximum PFI iterationsdamping::Real=1.0: policy mixing factor (1.0 = no damping)anderson_m::Int=0: Anderson acceleration depth (0 = disabled)threaded::Bool=false: enable multi-threaded grid evaluationverbose::Bool=false: print iteration info
MacroEconometricModels.perfect_foresight — Function
perfect_foresight(spec::DSGESpec{FT}; T_periods=100, shock_path=nothing,
max_iter=100, tol=1e-8, constraints=DSGEConstraint[],
solver=nothing, algorithm=nothing) → PerfectForesightPath{FT}Solve for the deterministic perfect foresight path given a sequence of shocks.
Uses NonlinearSolve.jl as the default Newton solver with block-tridiagonal sparse Jacobian.
Keywords
T_periods::Int=100— number of simulation periodsshock_path::Matrix— Tperiods × nexog matrix of shock realizationsmax_iter::Int=100— Newton iteration limittol::Real=1e-8— convergence tolerance (max abs residual)constraints::Vector{<:DSGEConstraint}— variable bounds and nonlinear inequalitiessolver::Symbol—:nonlinearsolve(default),:nlopt(SLSQP),:ipopt(NLP), or:path(MCP); auto-detectedalgorithm— NonlinearSolve.jl algorithm (default:NewtonRaphson()); passed through to chosen backend
MacroEconometricModels.evaluate_policy — Function
evaluate_policy(sol::ProjectionSolution{T}, x_state::AbstractVector) -> Vector{T}Evaluate the global policy function at a state vector. x_state should be an nx-vector of state variable levels. Returns n_vars-vector of all endogenous variable levels.
evaluate_policy(sol::ProjectionSolution{T}, X_states::AbstractMatrix) -> Matrix{T}Evaluate at multiple state points. Xstates is npoints x nx. Returns npoints x nvars matrix of levels.
MacroEconometricModels.max_euler_error — Function
max_euler_error(sol::ProjectionSolution{T}; n_test::Int=1000, rng=Random.default_rng()) -> TCompute maximum Euler equation error on random test points within the state domain.
DSGE IRF and FEVD
MacroEconometricModels.fevd — Method
fevd(sol::DSGESolution{T}, horizon::Int) -> FEVD{T}Compute forecast error variance decomposition from a solved DSGE model.
Uses the analytical IRFs from the solution to compute the proportion of h-step forecast error variance attributable to each structural shock.
Returns a FEVD{T} compatible with plot_result().
MacroEconometricModels.irf — Method
irf(sol::DSGESolution{T}, horizon::Int; kwargs...) -> ImpulseResponse{T}Compute analytical impulse responses from a solved DSGE model.
At horizon h for shock j: Phi_h[:,j] = G1^(h-1) * impact[:,j].
Returns an ImpulseResponse{T} compatible with plot_result().
Arguments
sol: solved DSGE modelhorizon: number of IRF periods
Keyword Arguments
ci_type::Symbol=:none: confidence interval type (:nonefor analytical DSGE)
MacroEconometricModels.irf — Method
irf(sol::ProjectionSolution{T}, horizon::Int; kwargs...) -> ImpulseResponse{T}Monte Carlo IRF: compare paths with/without initial shock.
Arguments
sol: projection solution from Chebyshev collocationhorizon: number of IRF periods
Keyword Arguments
n_sim::Int=500: number of simulation paths for averagingshock_size::Real=1.0: impulse size in standard deviationsci_type::Symbol=:none: confidence interval type
MacroEconometricModels.simulate — Method
simulate(sol::DSGESolution{T}, T_periods::Int;
shock_draws=nothing, rng=Random.default_rng()) -> Matrix{T}Simulate the solved DSGE model: y_t = G1 * y_{t-1} + impact * e_t + C_sol.
Returns T_periods x n_endog matrix of levels (steady state + deviations).
Arguments
sol: solved DSGE modelT_periods: number of periods to simulate
Keyword Arguments
shock_draws:T_periods x n_shocksmatrix of pre-drawn shocks (default:nothing, draws from N(0,1))rng: random number generator (default:Random.default_rng())
MacroEconometricModels.simulate — Method
simulate(sol::ProjectionSolution{T}, T_periods::Int; kwargs...) -> Matrix{T}Simulate using the global policy function from projection solution. Returns T_periods x n_vars matrix of levels.
Arguments
sol: projection solution from Chebyshev collocationT_periods: number of periods to simulate
Keyword Arguments
shock_draws:T_periods x n_shocksmatrix of pre-drawn shocks (default:nothing, draws from N(0,1))rng: random number generator (default:Random.default_rng())
MacroEconometricModels._analytical_moments_gmm — Method
_analytical_moments_gmm(sol::PerturbationSolution{T}; lags::Int=1) → Vector{T}Compute GMM-format moment vector: means + product moments + diagonal autocovariances.
For order >= 2, uses closed-form augmented Lyapunov. For order 1, uses standard Lyapunov (means are zero).
MacroEconometricModels._augmented_moments_2nd — Method
_augmented_moments_2nd(sol::PerturbationSolution{T};
lags::Vector{Int}=[1]) → Dict{Symbol, Any}Compute closed-form unconditional moments for a 2nd-order perturbation solution using the augmented-state Lyapunov approach (Andreasen et al. 2018).
The augmented state is z = [xf; xs; vec(xf⊗xf)] of dimension 2nx + nx². The system is z(t+1) = A·z(t) + c + u(t) where u(t) captures stochastic innovations from the pruned dynamics.
Returns moments for ALL n = nx + ny variables, in the original variable ordering (matching sol.state_indices and sol.control_indices).
Returns a Dict with keys:
:E_y— n-vector of unconditional means (deviations from SS):Var_y— n×n unconditional variance-covariance:Cov_y— n×n×max_lag autocovariance tensor:E_z,:Var_z— augmented state moments (for diagnostics)
MacroEconometricModels._augmented_moments_3rd — Method
_augmented_moments_3rd(sol::PerturbationSolution{T};
lags::Vector{Int}=[1]) → Dict{Symbol, Any}Compute closed-form unconditional moments for a 3rd-order perturbation solution using the augmented-state Lyapunov approach (Andreasen et al. 2018).
The augmented state is z = [xf; xs; vec(xf⊗xf); xrd; vec(xf⊗xs); vec(xf⊗xf⊗xf)] of dimension 3nx + 2nx² + nx³. The system is z(t+1) = A·z(t) + c + u(t).
Returns a Dict with keys:
:E_y— n-vector of unconditional means (deviations from SS):Var_y— n×n unconditional variance-covariance:Cov_y— n×n×max_lag autocovariance tensor:E_z,:Var_z— augmented state moments (for diagnostics)
MacroEconometricModels._dlyap_doubling — Method
_dlyap_doubling(A::AbstractMatrix{T}, B::AbstractMatrix{T};
tol::Real=1e-12, maxiter::Int=500) -> Matrix{T}Solve the discrete Lyapunov equation Σ = A·Σ·A' + B via the doubling algorithm.
More numerically stable than Kronecker vectorization for large systems (O(n³) per iteration vs O(n⁶) for the direct solve), and typically converges in O(log(1/ρ(A))) iterations where ρ(A) is the spectral radius.
Algorithm (Smith 1991):
Aₖ = A, Bₖ = B
repeat:
Bₖ₊₁ = Aₖ · Bₖ · Aₖ' + Bₖ
Aₖ₊₁ = Aₖ · Aₖ
until converged
return (Bₖ₊₁ + Bₖ₊₁') / 2Convergence is declared when maximum(abs.(Bₖ₊₁ - Bₖ)) < tol or norm(Aₖ) < tol.
MacroEconometricModels._extract_xx_block — Method
_extract_xx_block(Mvv::Matrix{T}, nx::Int, nv::Int) → Matrix{T}Extract the (xf⊗xf) sub-block from a matrix with nv² columns (Kronecker ordering of v = [x; ε]). Returns a matrix with nx² columns corresponding to the state×state indices only.
MacroEconometricModels._extract_xxx_block — Method
_extract_xxx_block(Mvvv::Matrix{T}, nx::Int, nv::Int) → Matrix{T}Extract the (xf⊗xf⊗xf) sub-block from a matrix with nv³ columns (Kronecker ordering of v = [x; ε]). Returns a matrix with nx³ columns corresponding to the state×state×state indices only.
MacroEconometricModels._girf — Method
_girf(sol::PerturbationSolution{T}, horizon::Int;
n_draws::Int=500, shock_size::T=one(T)) -> ImpulseResponse{T}Compute Generalized Impulse Response Functions via Monte Carlo simulation.
GIRF = E[y{t+h} | epst = shock] - E[y{t+h} | epst = 0], averaged over n_draws random draws of future shocks.
MacroEconometricModels._innovation_variance_2nd — Method
_innovation_variance_2nd(hx_state, eta_x, Var_xf, nx, n_eps;
vectorMom3=nothing, vectorMom4=nothing) → Matrix{T}Compute the innovation covariance matrix for the 2nd-order augmented state z = [xf; xs; vec(xf⊗xf)].
Follows UnconditionalMoments_2nd_Lyap.m from the GMMThirdOrderv2 MATLAB reference code (Andreasen 2015).
Arguments:
hx_state: nx × nx state transitioneta_x: nx × n_eps shock loadingVar_xf: nx × nx unconditional variance of xf (from first-order Lyapunov)vectorMom3: n_eps vector of 3rd moments (default: zeros for symmetric shocks)vectorMom4: n_eps vector of 4th moments (default: 3s for Gaussian shocks)
MacroEconometricModels._innovation_variance_3rd_sim — Method
_innovation_variance_3rd_sim(A, c, hx_state, hxx_xx, eta_x, hσσ, Var_xf,
nx, n_eps, nz, r1, r2, r3, r4, r5, r6;
n_sim=500_000) → Matrix{T}Compute the innovation covariance for the 3rd-order augmented state system via Monte Carlo simulation. This avoids the complex analytical Gaussian moment formulas (which involve up to 6th moments) while providing accurate results.
The innovation u(t) = z(t+1) - A·z(t) - c is computed from simulated paths of the first-order state xf and shocks ε, then Var_inov = E[u·u'].
MacroEconometricModels._simulation_moments — Method
_simulation_moments(sol::PerturbationSolution{T}; lags::Int=1) -> Vector{T}Compute moments via pruned simulation for higher-order perturbation solutions.
Uses a fixed RNG seed (12345) for reproducibility and T=100,000 simulation periods.
MacroEconometricModels.analytical_moments — Method
analytical_moments(sol::PerturbationSolution{T}; lags::Int=1,
format::Symbol=:covariance) -> Vector{T}Compute analytical moment vector from a perturbation solution.
Keyword Arguments
lags::Int=1— number of autocovariance lagsformat::Symbol=:covariance— moment format::covariance(default): upper-triangle of var-cov + diagonal autocov (backward compatible with DSGESolution format):gmm: means + upper-triangle product moments + diagonal autocov (for GMM estimation with higher-order perturbation)
For order 1 with :covariance format, uses the doubling Lyapunov solver. For order ≥ 2 with :covariance format, uses simulation-based moments. For :gmm format at any order, uses closed-form augmented Lyapunov (order ≥ 2) or standard Lyapunov (order 1).
MacroEconometricModels.fevd — Method
fevd(sol::PerturbationSolution{T}, horizon::Int) -> FEVD{T}Compute forecast error variance decomposition from a perturbation solution.
Uses the analytical first-order IRFs to compute the proportion of h-step forecast error variance attributable to each structural shock. This follows the same IRF-based computation as fevd(::DSGESolution, ...).
MacroEconometricModels.irf — Method
irf(sol::PerturbationSolution{T}, horizon::Int;
irf_type::Symbol=:analytical, n_draws::Int=500,
shock_size::Real=1.0, ci_type::Symbol=:none) -> ImpulseResponse{T}Compute impulse responses from a perturbation solution.
For irf_type=:analytical (default), computes the standard first-order analytical IRFs: Phi_h[:,j] = hx_state^(h-1) * eta * e_j (same as DSGESolution).
For irf_type=:girf, computes Generalized IRFs via Monte Carlo simulation, which captures second-order effects.
Keyword Arguments
irf_type::Symbol=:analytical::analyticalfor first-order,:girffor simulation-basedn_draws::Int=500: number of Monte Carlo draws for GIRFshock_size::Real=1.0: size of the impulse (in standard deviations)ci_type::Symbol=:none: confidence interval type
MacroEconometricModels.simulate — Method
simulate(sol::PerturbationSolution{T}, T_periods::Int;
shock_draws=nothing, rng=Random.default_rng(),
antithetic::Bool=false) -> Matrix{T}Simulate a higher-order perturbation solution using Kim et al. (2008) pruning.
For order 1, this is the standard linear simulation. For order 2, the pruned simulation tracks first-order and second-order state components separately to prevent the explosive sample paths that arise from naive simulation of second-order decision rules.
Arguments
sol: perturbation solutionT_periods: number of periods to simulate
Keyword Arguments
shock_draws:T_periods x n_shocksmatrix of pre-drawn shocks (default: N(0,1))rng: random number generatorantithetic::Bool=false: if true, use antithetic variates (negate second half of shocks)
Returns
T_periods x n_vars matrix of levels (steady state + deviations).
Simulation and Analysis
MacroEconometricModels.simulate — Function
simulate(sol::DSGESolution{T}, T_periods::Int;
shock_draws=nothing, rng=Random.default_rng()) -> Matrix{T}Simulate the solved DSGE model: y_t = G1 * y_{t-1} + impact * e_t + C_sol.
Returns T_periods x n_endog matrix of levels (steady state + deviations).
Arguments
sol: solved DSGE modelT_periods: number of periods to simulate
Keyword Arguments
shock_draws:T_periods x n_shocksmatrix of pre-drawn shocks (default:nothing, draws from N(0,1))rng: random number generator (default:Random.default_rng())
simulate(sol::ProjectionSolution{T}, T_periods::Int; kwargs...) -> Matrix{T}Simulate using the global policy function from projection solution. Returns T_periods x n_vars matrix of levels.
Arguments
sol: projection solution from Chebyshev collocationT_periods: number of periods to simulate
Keyword Arguments
shock_draws:T_periods x n_shocksmatrix of pre-drawn shocks (default:nothing, draws from N(0,1))rng: random number generator (default:Random.default_rng())
simulate(sol::PerturbationSolution{T}, T_periods::Int;
shock_draws=nothing, rng=Random.default_rng(),
antithetic::Bool=false) -> Matrix{T}Simulate a higher-order perturbation solution using Kim et al. (2008) pruning.
For order 1, this is the standard linear simulation. For order 2, the pruned simulation tracks first-order and second-order state components separately to prevent the explosive sample paths that arise from naive simulation of second-order decision rules.
Arguments
sol: perturbation solutionT_periods: number of periods to simulate
Keyword Arguments
shock_draws:T_periods x n_shocksmatrix of pre-drawn shocks (default: N(0,1))rng: random number generatorantithetic::Bool=false: if true, use antithetic variates (negate second half of shocks)
Returns
T_periods x n_vars matrix of levels (steady state + deviations).
simulate(result::BayesianDSGE{T}, T_periods::Int;
n_draws::Int=200,
quantiles::Vector{<:Real}=[0.05, 0.16, 0.84, 0.95],
solver::Symbol=:gensys,
solver_kwargs::NamedTuple=NamedTuple(),
rng::AbstractRNG=Random.default_rng()) → BayesianDSGESimulation{T}Simulate from the posterior predictive distribution with credible bands.
For each of n_draws randomly selected posterior parameter draws, re-solves the DSGE model and simulates T_periods forward. Reports pointwise posterior median and quantile bands.
Default quantiles give dual 68% (16th–84th) and 90% (5th–95th) credible bands.
MacroEconometricModels.solve_lyapunov — Function
solve_lyapunov(G1::AbstractMatrix{T}, impact::AbstractMatrix{T}) -> Matrix{T}Solve the discrete Lyapunov equation: Sigma = G1 * Sigma * G1' + impact * impact'.
Uses Kronecker vectorization: vec(Sigma) = (I - G1 kron G1)^{-1} * vec(impact * impact').
Returns the unconditional covariance matrix Sigma (n x n, symmetric positive semi-definite).
Throws ArgumentError if G1 is not stable (max |eigenvalue| >= 1).
MacroEconometricModels.analytical_moments — Function
analytical_moments(sol::DSGESolution{T}; lags::Int=1) -> Vector{T}Compute analytical moment vector from a solved DSGE model.
Uses the discrete Lyapunov equation to compute the unconditional covariance, then extracts the same moment format as autocovariance_moments:
- Upper-triangle of variance-covariance matrix: k*(k+1)/2 elements
- Diagonal autocovariances at each lag: k elements per lag
Arguments
sol– solved DSGE model (must be stable/determined)lags– number of autocovariance lags (default: 1)
analytical_moments(sol::PerturbationSolution{T}; lags::Int=1,
format::Symbol=:covariance) -> Vector{T}Compute analytical moment vector from a perturbation solution.
Keyword Arguments
lags::Int=1— number of autocovariance lagsformat::Symbol=:covariance— moment format::covariance(default): upper-triangle of var-cov + diagonal autocov (backward compatible with DSGESolution format):gmm: means + upper-triangle product moments + diagonal autocov (for GMM estimation with higher-order perturbation)
For order 1 with :covariance format, uses the doubling Lyapunov solver. For order ≥ 2 with :covariance format, uses simulation-based moments. For :gmm format at any order, uses closed-form augmented Lyapunov (order ≥ 2) or standard Lyapunov (order 1).
Global Solution Methods
MacroEconometricModels.vfi_solver — Function
vfi_solver(spec::DSGESpec{T}; kwargs...) -> ProjectionSolution{T}Solve DSGE model via Value Function Iteration.
Iterates on the Bellman operator using Euler equation residuals: at each grid point, solve for the policy via Newton on residual_fns, then update the value (Chebyshev coefficients) and check sup-norm convergence on the policy function.
Keyword Arguments
degree::Int=5: Chebyshev polynomial degreegrid::Symbol=:auto::tensor,:smolyak, or:autosmolyak_mu::Int=3: Smolyak exactness levelquadrature::Symbol=:auto::gauss_hermite,:monomial, or:auton_quad::Int=5: quadrature nodes per shock dimensionscale::Real=3.0: state bounds = SS ± scale × σtol::Real=1e-8: sup-norm convergence tolerance on value functionmax_iter::Int=1000: maximum VFI iterationsdamping::Real=1.0: coefficient mixing factor (1.0 = no damping)howard_steps::Int=0: Howard improvement steps per iteration (0 = pure VFI)anderson_m::Int=0: Anderson acceleration depth (0 = disabled)threaded::Bool=false: enable multi-threaded grid evaluationverbose::Bool=false: print iteration infoinitial_coeffs: warm-start coefficients (nvars × nbasis)
DSGE GMM Estimation
MacroEconometricModels.estimate_dsge — Function
estimate_dsge(spec, data, param_names; method=:irf_matching, ...) -> DSGEEstimationEstimate DSGE deep parameters via GMM.
Arguments
spec::DSGESpec{T}– model specification (initial param values as starting point)data::AbstractMatrix– Tobs x nvars data matrixparam_names::Vector{Symbol}– which parameters to estimate
Keywords
method::Symbol–:irf_matchingor:euler_gmmtarget_irfs::ImpulseResponse– pre-computed target IRFs (optional, for IRF matching)var_lags::Int=4– lag order for VAR when computing target IRFsirf_horizon::Int=20– horizon for IRF matchingweighting::Symbol=:two_step– GMM weightingn_lags_instruments::Int=4– instrument lags for Euler equation GMM
References
- Christiano, L., Eichenbaum, M., & Evans, C. (2005). "Nominal Rigidities and the Dynamic Effects of a Shock to Monetary Policy." Journal of Political Economy, 113(1), 1-45.
- Hansen, L. P. & Singleton, K. J. (1982). "Generalized Instrumental Variables Estimation of Nonlinear Rational Expectations Models." Econometrica, 50(5), 1269-1286.
DSGE Bayesian Estimation
MacroEconometricModels.estimate_dsge_bayes — Function
estimate_dsge_bayes(spec, data, θ0; priors, method=:smc, ...) → BayesianDSGEBayesian estimation of DSGE model parameters via Sequential Monte Carlo (SMC), SMC², or Random-Walk Metropolis-Hastings (RWMH).
Arguments
spec::DSGESpec{T}— model specification from@dsgemacrodata::AbstractMatrix— observed data (Tobs × nobs or nobs × Tobs, auto-detected)θ0::AbstractVector{<:Real}— initial parameter guess (length must match number of priors)
Keywords
priors::Dict{Symbol,<:Distribution}— prior distributions keyed by parameter namemethod::Symbol=:smc— estimation method::smc,:smc2, or:mhobservables::Vector{Symbol}=Symbol[]— which endogenous variables are observed (default: allspec.endog)n_smc::Int=5000— number of SMC particles (for:smcand:smc2)n_particles::Int=500— number of PF particles (for:smc2only)n_mh_steps::Int=1— MH mutation steps per SMC stagen_draws::Int=10000— total draws for:mh(including burnin)burnin::Int=5000— burnin draws for:mhess_target::Float64=0.5— target ESS fraction for adaptive temperingmeasurement_error::Union{Nothing,Vector{<:Real}}=nothing— measurement error SDslikelihood::Symbol=:auto— likelihood evaluation method (currently auto = Kalman)solver::Symbol=:gensys— DSGE solver methodsolver_kwargs::NamedTuple=NamedTuple()— additional solver keyword argumentsdelayed_acceptance::Bool=false— enable two-stage delayed acceptance MH for:smc2(Christen & Fox 2005). Pre-screens proposals with a cheap bootstrap PF to avoid expensive CSMC evaluations on proposals that would be rejected. Exact posterior.n_screen::Int=200— particles for screening PF (only used whendelayed_acceptance=true)rng::AbstractRNG=Random.default_rng()— random number generator
Returns
BayesianDSGE{T} containing posterior draws, log posterior, marginal likelihood, etc.
References
- Herbst, E. & Schorfheide, F. (2014). Sequential Monte Carlo Sampling for DSGE Models. Journal of Applied Econometrics, 29(7), 1073-1098.
- An, S. & Schorfheide, F. (2007). Bayesian Analysis of DSGE Models. Econometric Reviews, 26(2-4), 113-172.
MacroEconometricModels.posterior_summary — Function
posterior_summary(result::BayesianDSGE{T}) → Dict{Symbol, Dict{Symbol, T}}Compute posterior summary statistics for each estimated parameter.
Returns a dictionary keyed by parameter name, each containing:
:mean— posterior mean:median— posterior median (50th percentile):std— posterior standard deviation:ci_lower— 2.5th percentile (lower bound of 95% credible interval):ci_upper— 97.5th percentile (upper bound of 95% credible interval)
MacroEconometricModels.marginal_likelihood — Function
marginal_likelihood(result::BayesianDSGE) → TReturn the log marginal likelihood (model evidence) from Bayesian estimation.
For SMC methods, this is the normalizing constant estimate from the adaptive tempering schedule. For RWMH, this is an approximation.
MacroEconometricModels.bayes_factor — Function
bayes_factor(r1::BayesianDSGE, r2::BayesianDSGE) → TCompute the log Bayes factor comparing model 1 to model 2: log BF₁₂ = log p(Y|M₁) - log p(Y|M₂).
A positive value favors model 1; negative favors model 2. Following Kass & Raftery (1995), 2 * log BF > 6 is strong evidence.
References
- Kass, R. E. & Raftery, A. E. (1995). Bayes Factors. Journal of the American Statistical Association, 90(430), 773-795.
MacroEconometricModels.prior_posterior_table — Function
prior_posterior_table(result::BayesianDSGE{T}) → Vector{NamedTuple}Generate rows for a prior-posterior comparison table.
Each row contains:
param— parameter nameprior_dist— prior distribution typeprior_mean— prior meanprior_std— prior standard deviationpost_mean— posterior meanpost_std— posterior standard deviationci_lower— posterior 2.5th percentileci_upper— posterior 97.5th percentile
MacroEconometricModels.posterior_predictive — Function
posterior_predictive(result::BayesianDSGE{T}, n_sim::Int;
T_periods::Int=100,
rng::AbstractRNG=Random.default_rng()) → Array{T,3}Simulate from the posterior predictive distribution.
For n_sim randomly selected posterior draws, solves the model at those parameter values and simulates forward T_periods periods.
Arguments
result— Bayesian estimation resultn_sim— number of simulated paths
Keywords
T_periods::Int=100— number of periods per simulationrng::AbstractRNG— random number generator
Returns
n_sim × T_periods × n_vars array of simulated paths.
Occasionally Binding Constraints
MacroEconometricModels.parse_constraint — Function
parse_constraint(expr::Expr, spec::DSGESpec{T}) → OccBinConstraint{T}Parse a constraint expression of the form :(var[t] >= bound) or :(var[t] <= bound).
Arguments
expr— constraint expression, e.g.:(i[t] >= 0)or:(y[t] <= 1.0)spec— DSGE model specification (used to validate variable names)
Returns
An OccBinConstraint{T} with extracted variable, bound, and direction.
Throws
ArgumentErrorif the variable is not found inspec.endogArgumentErrorif the expression is not a valid constraint format
MacroEconometricModels.occbin_solve — Function
occbin_solve(spec::DSGESpec{T}, constraint::OccBinConstraint{T};
shock_path::Matrix{T}=zeros(T, 40, spec.n_exog),
nperiods::Int=size(shock_path, 1),
maxiter::Int=100) → OccBinSolution{T}Solve a DSGE model with a single occasionally binding constraint using the piecewise-linear algorithm of Guerrieri & Iacoviello (2015).
The algorithm:
- Solve the unconstrained (reference) model via gensys → P, Q
- Derive the alternative (binding) regime by replacing the constraint equation
- Extract linearized coefficient matrices for both regimes
- Run the guess-and-verify loop to find the piecewise-linear solution
Arguments
spec— DSGE model specification (must have steady state computed)constraint— the occasionally binding constraint
Keyword Arguments
shock_path— Tperiods × nexog matrix of shock realizationsnperiods— number of periods to simulate (default: rows of shock_path)maxiter— maximum guess-and-verify iterations (default: 100)
Returns
An OccBinSolution{T} with linear and piecewise-linear paths.
occbin_solve(spec::DSGESpec{T}, constraint::OccBinConstraint{T},
alt_spec::DSGESpec{T}; kwargs...) → OccBinSolution{T}Variant that accepts an explicit alternative regime specification instead of deriving it automatically from the constraint.
occbin_solve(spec::DSGESpec{T}, c1::OccBinConstraint{T}, c2::OccBinConstraint{T};
shock_path, nperiods, maxiter, curb_retrench) → OccBinSolution{T}Solve a DSGE model with two occasionally binding constraints using the piecewise-linear algorithm of Guerrieri & Iacoviello (2015).
The algorithm generalizes the one-constraint solver to 4 regimes:
- Neither constraint binds (reference)
- Only constraint 1 binds (alt1)
- Only constraint 2 binds (alt2)
- Both constraints bind (alt12)
Arguments
spec— DSGE model specification (must have steady state computed)c1— first occasionally binding constraintc2— second occasionally binding constraint
Keyword Arguments
shock_path— Tperiods × nexog matrix of shock realizationsnperiods— number of periods to simulate (default: rows of shock_path)maxiter— maximum guess-and-verify iterations (default: 100)curb_retrench— limit constraint relaxation to one period per iteration (default: false)
Returns
An OccBinSolution{T} with linear and piecewise-linear paths and a nperiods × 2 regime history matrix.
occbin_solve(spec::DSGESpec{T}, c1::OccBinConstraint{T}, c2::OccBinConstraint{T},
alt_specs::Dict; kwargs...) → OccBinSolution{T}Variant that accepts explicit alternative regime specifications as a Dict mapping regime indicators to DSGESpec:
(1,0)→ alt1_spec (constraint 1 binding only)(0,1)→ alt2_spec (constraint 2 binding only)(1,1)→ alt12_spec (both constraints binding)
MacroEconometricModels.occbin_irf — Function
occbin_irf(spec::DSGESpec{T}, constraint::OccBinConstraint{T},
shock_idx::Int, horizon::Int;
magnitude::Real=one(T), maxiter::Int=100) → OccBinIRF{T}Compute impulse response functions under an occasionally binding constraint.
Compares the unconstrained linear IRF with the piecewise-linear OccBin IRF.
Arguments
spec— DSGE model specificationconstraint— the occasionally binding constraintshock_idx— index of the shock to perturb (1-based)horizon— number of periods for the IRF
Keyword Arguments
magnitude— size of the shock (default: 1.0)maxiter— max guess-and-verify iterations (default: 100)
occbin_irf(spec::DSGESpec{T}, c1::OccBinConstraint{T}, c2::OccBinConstraint{T},
shock_idx::Int, horizon::Int;
magnitude::Real=one(T), maxiter::Int=100,
curb_retrench::Bool=false) → OccBinIRF{T}Two-constraint variant of OccBin IRF.
Constraint Constructors
MacroEconometricModels.variable_bound — Function
variable_bound(var::Symbol; lower=nothing, upper=nothing) -> VariableBound{Float64}Create a variable bound constraint.
Examples
variable_bound(:i, lower=0.0) # ZLB: i_t >= 0
variable_bound(:c, lower=0.0) # positivity
variable_bound(:h, lower=0.0, upper=1.0) # hours in [0, 1]MacroEconometricModels.nonlinear_constraint — Function
nonlinear_constraint(fn::Function; label="constraint") -> NonlinearConstraint{Float64}Create a nonlinear inequality constraint fn(y, y_lag, y_lead, e, theta) <= 0.
Examples
# Collateral constraint: debt <= 0.8 * capital
nonlinear_constraint((y, y_lag, y_lead, e, theta) -> y[3] - 0.8 * y[1]; label="collateral")Display and References
MacroEconometricModels._coef_table — Method
_coef_table(io, title, names, coefs, se; dist=:z, dof_r=0, level=0.95)Publication-quality 7-column coefficient table (Stata/EViews style).
Columns: Name | Coef. | Std.Err. | z/t | P>|z/t| | [95% CI lower | CI upper] | stars
MacroEconometricModels._matrix_table — Method
Print a labeled matrix as a PrettyTables table.
MacroEconometricModels._pretty_table — Method
_pretty_table(io::IO, data; kwargs...)Central PrettyTables wrapper that respects the global display backend.
For :text backend, applies _TEXT_TABLE_FORMAT automatically. For :latex and :html backends, omits text-only formatting options.
MacroEconometricModels._select_horizons — Method
Select representative horizons for display.
MacroEconometricModels._sig_legend — Method
Print significance legend footer.
MacroEconometricModels.get_display_backend — Method
get_display_backend() -> SymbolReturn the current PrettyTables display backend (:text, :latex, or :html).
MacroEconometricModels.set_display_backend — Method
set_display_backend(backend::Symbol)Set the PrettyTables output backend. Options: :text (default), :latex, :html.
Examples
set_display_backend(:latex) # all show() methods now emit LaTeX
set_display_backend(:html) # switch to HTML tables
set_display_backend(:text) # back to terminal-friendly textMacroEconometricModels.refs — Function
refs([io::IO], x; format=get_display_backend())Print bibliographic references for a model, result, or method.
Supports four output formats via the format keyword:
:text— AEA plain text (default, followsget_display_backend()):latex—\bibitem{}entries:bibtex— BibTeX@article{}/@book{}entries:html— HTML with clickable DOI links
Dispatch
- Instance dispatch:
refs(model)prints references for the model type - Symbol dispatch:
refs(:fastica)prints references for a method name
Examples
model = estimate_var(Y, 2)
refs(model) # AEA text to stdout
refs(model; format=:bibtex) # BibTeX entries
refs(:johansen) # Johansen (1991)
refs(:fastica; format=:latex) # Hyvärinen (1999) as \bibitemOutput Tables
MacroEconometricModels.table — Function
table(irf::ImpulseResponse, var, shock; horizons=nothing) -> MatrixExtract IRF values for a variable-shock pair. Returns matrix with columns: [Horizon, IRF] or [Horizon, IRF, CIlo, CIhi].
table(irf::BayesianImpulseResponse, var, shock; horizons=nothing) -> MatrixExtract Bayesian IRF values. Returns [Horizon, Mean, Q1, Q2, ...].
table(f::FEVD, var; horizons=nothing) -> MatrixExtract FEVD proportions for a variable. Returns [Horizon, Shock1, Shock2, ...].
table(f::BayesianFEVD, var; horizons=nothing, stat=:mean) -> MatrixExtract Bayesian FEVD values. stat can be :mean or quantile index.
table(hd::HistoricalDecomposition, var; periods=nothing) -> MatrixExtract HD contributions for a variable. Returns [Period, Actual, Shock1, ..., ShockN, Initial].
table(hd::BayesianHistoricalDecomposition, var; periods=nothing, stat=:mean) -> MatrixExtract Bayesian HD contributions. stat can be :mean or quantile index.
table(fc::VolatilityForecast) -> MatrixExtract volatility forecast data. Returns matrix with columns: [Horizon, Forecast, CIlo, CIhi, SE].
table(fc::ARIMAForecast) -> MatrixExtract ARIMA forecast data. Returns matrix with columns: [Horizon, Forecast, CIlo, CIhi, SE].
table(fc::FactorForecast, var_idx::Int; type=:observable) -> MatrixExtract factor forecast data for a single variable. type=:observable returns observable forecasts, type=:factor returns factor forecasts. Returns matrix with columns: [Horizon, Forecast, CIlo, CIhi].
table(irf::LPImpulseResponse, var_idx::Int) -> MatrixExtract LP IRF values for a response variable. Returns matrix with columns: [Horizon, IRF, SE, CIlo, CIhi].
MacroEconometricModels.print_table — Function
print_table([io], irf::ImpulseResponse, var, shock; horizons=nothing)Print formatted IRF table.
print_table([io], f::FEVD, var; horizons=nothing)Print formatted FEVD table.
print_table([io], hd::HistoricalDecomposition, var; periods=nothing)Print formatted HD table.
print_table([io], slp::StructuralLP, var, shock; horizons=nothing)Print formatted IRF table for a specific variable-shock pair from structural LP.
print_table([io], fc::LPForecast)Print formatted LP forecast table.
print_table([io], f::LPFEVD, var_idx; horizons=...)Print formatted LP-FEVD table for variable var_idx.
print_table([io], fc::VolatilityForecast)Print formatted volatility forecast table.
print_table([io], fc::ARIMAForecast)Print formatted ARIMA forecast table.
print_table([io], fc::FactorForecast, var_idx; type=:observable)Print formatted factor forecast table for a single variable.
print_table([io], irf::LPImpulseResponse, var_idx)Print formatted LP IRF table for a response variable.
Non-Gaussian Identification
Normality Tests
MacroEconometricModels.jarque_bera_test — Function
jarque_bera_test(model::VARModel; method=:multivariate) -> NormalityTestResult
jarque_bera_test(U::AbstractMatrix; method=:multivariate) -> NormalityTestResultMultivariate Jarque-Bera test for normality of VAR residuals.
Methods:
:multivariate— joint test based on multivariate skewness and kurtosis (Lütkepohl 2005):component— component-wise univariate JB tests on standardized residuals
Reference: Jarque & Bera (1980), Lütkepohl (2005, §4.5)
MacroEconometricModels.mardia_test — Function
mardia_test(model::VARModel; type=:both) -> NormalityTestResult
mardia_test(U::AbstractMatrix; type=:both) -> NormalityTestResultMardia's tests for multivariate normality based on multivariate skewness and kurtosis.
Types:
:skewness— tests multivariate skewness b₁,ₖ:kurtosis— tests multivariate kurtosis b₂,ₖ:both— combined test (sum of both statistics)
Under H₀: T·b₁,ₖ/6 ~ χ²(k(k+1)(k+2)/6), (b₂,ₖ - k(k+2)) / √(8k(k+2)/T) ~ N(0,1).
Reference: Mardia (1970)
MacroEconometricModels.doornik_hansen_test — Function
doornik_hansen_test(model::VARModel) -> NormalityTestResult
doornik_hansen_test(U::AbstractMatrix) -> NormalityTestResultDoornik-Hansen omnibus test for multivariate normality.
Applies the Bowman-Shenton transformation to each component's skewness and kurtosis, then sums z₁² + z₂² across components. Under H₀: DH ~ χ²(2k).
Reference: Doornik & Hansen (2008)
MacroEconometricModels.henze_zirkler_test — Function
henze_zirkler_test(model::VARModel) -> NormalityTestResult
henze_zirkler_test(U::AbstractMatrix) -> NormalityTestResultHenze-Zirkler test for multivariate normality based on the empirical characteristic function.
The test statistic is:
\[T_{\beta} = \frac{1}{n} \sum_{i,j} e^{-\beta^2 D_{ij}/2} - 2(1+\beta^2)^{-k/2} \sum_i e^{-\beta^2 d_i^2/(2(1+\beta^2))} + n(1+2\beta^2)^{-k/2}\]
where $D_{ij} = (z_i - z_j)'(z_i - z_j)$ and $d_i = z_i' z_i$.
Reference: Henze & Zirkler (1990)
MacroEconometricModels.normality_test_suite — Function
normality_test_suite(model::VARModel) -> NormalityTestSuite
normality_test_suite(U::AbstractMatrix) -> NormalityTestSuiteRun all available multivariate normality tests and return a NormalityTestSuite.
Tests included:
- Multivariate Jarque-Bera
- Component-wise Jarque-Bera
- Mardia skewness
- Mardia kurtosis
- Mardia combined
- Doornik-Hansen
- Henze-Zirkler
ICA-based Identification
MacroEconometricModels.identify_fastica — Function
identify_fastica(model::VARModel; contrast=:logcosh, approach=:deflation,
max_iter=200, tol=1e-6) -> ICASVARResultIdentify SVAR via FastICA (Hyvärinen 1999).
Recovers independent non-Gaussian structural shocks by maximizing non-Gaussianity of the recovered sources.
Arguments:
contrast— non-Gaussianity measure::logcosh(default, robust),:exp,:kurtosisapproach—:deflation(one-by-one) or:symmetric(simultaneous)max_iter— maximum iterations per componenttol— convergence tolerance
Reference: Hyvärinen (1999)
MacroEconometricModels.identify_jade — Function
identify_jade(model::VARModel; max_iter=100, tol=1e-6) -> ICASVARResultIdentify SVAR via JADE (Joint Approximate Diagonalization of Eigenmatrices).
Uses fourth-order cumulant matrices and joint diagonalization via Jacobi rotations.
Reference: Cardoso & Souloumiac (1993)
MacroEconometricModels.identify_sobi — Function
identify_sobi(model::VARModel; lags=1:12, max_iter=100, tol=1e-6) -> ICASVARResultIdentify SVAR via SOBI (Second-Order Blind Identification).
Uses autocovariance matrices at multiple lags and joint diagonalization. Exploits temporal structure rather than higher-order statistics.
Reference: Belouchrani et al. (1997)
MacroEconometricModels.identify_dcov — Function
identify_dcov(model::VARModel; max_iter=200, tol=1e-6) -> ICASVARResultIdentify SVAR by minimizing pairwise distance covariance between recovered shocks.
Distance covariance (Székely et al. 2007) is zero iff the variables are independent, making it a natural criterion for ICA.
Reference: Matteson & Tsay (2017)
MacroEconometricModels.identify_hsic — Function
identify_hsic(model::VARModel; kernel=:gaussian, sigma=1.0,
max_iter=200, tol=1e-6) -> ICASVARResultIdentify SVAR by minimizing pairwise HSIC between recovered shocks.
HSIC with a characteristic kernel (Gaussian) is zero iff variables are independent.
Reference: Gretton et al. (2005)
Non-Gaussian ML Identification
MacroEconometricModels.identify_student_t — Function
identify_student_t(model::VARModel; max_iter=500, tol=1e-6) -> NonGaussianMLResultIdentify SVAR assuming Student-t distributed structural shocks.
Each shock εⱼ ~ t(νⱼ) (standardized to unit variance). Identification is achieved when at most one νⱼ = ∞ (Gaussian).
Reference: Lanne, Meitz & Saikkonen (2017)
MacroEconometricModels.identify_mixture_normal — Function
identify_mixture_normal(model::VARModel; n_components=2, max_iter=500, tol=1e-6) -> NonGaussianMLResultIdentify SVAR assuming mixture-of-normals distributed structural shocks.
Each shock εⱼ ~ pj N(0,σ₁ⱼ²) + (1-pj) N(0,σ₂ⱼ²) with unit variance constraint.
Reference: Lanne & Lütkepohl (2010)
MacroEconometricModels.identify_pml — Function
identify_pml(model::VARModel; max_iter=500, tol=1e-6) -> NonGaussianMLResultIdentify SVAR via Pseudo Maximum Likelihood using Pearson Type IV distributions.
Allows both skewness and excess kurtosis in the structural shocks.
Reference: Herwartz (2018)
MacroEconometricModels.identify_skew_normal — Function
identify_skew_normal(model::VARModel; max_iter=500, tol=1e-6) -> NonGaussianMLResultIdentify SVAR assuming skew-normal distributed structural shocks.
Each shock εⱼ has pdf f(x) = 2 φ(x) Φ(αⱼ x), where αⱼ controls skewness.
Reference: Azzalini (1985)
MacroEconometricModels.identify_nongaussian_ml — Function
identify_nongaussian_ml(model::VARModel; distribution=:student_t,
max_iter=500, tol=1e-6) -> NonGaussianMLResultUnified non-Gaussian ML SVAR identification dispatcher.
Supported distributions:
:student_t— independent Student-t shocks (Lanne, Meitz & Saikkonen 2017):mixture_normal— mixture of two normals (Lanne & Lütkepohl 2010):pml— Pearson Type IV / Pseudo-ML (Herwartz 2018):skew_normal— skew-normal (Azzalini 1985)
Heteroskedasticity Identification
MacroEconometricModels.identify_markov_switching — Function
identify_markov_switching(model::VARModel; n_regimes=2, max_iter=500, tol=1e-6) -> MarkovSwitchingSVARResultIdentify SVAR via Markov-switching heteroskedasticity (Lanne & Lütkepohl 2008).
Estimates regime-specific covariance matrices Σ₁, Σ₂, ..., Σ_K via EM algorithm, then identifies B₀ from the eigendecomposition of Σ₁⁻¹ Σ₂.
Identification requires that the relative variance ratios (eigenvalues) are distinct.
Reference: Lanne & Lütkepohl (2008), Rigobon (2003)
MacroEconometricModels.identify_garch — Function
identify_garch(model::VARModel; max_iter=500, tol=1e-6) -> GARCHSVARResultIdentify SVAR via GARCH-based heteroskedasticity (Normandin & Phaneuf 2004).
Iterative procedure:
- Start with Cholesky B₀
- Compute structural shocks εt = B₀⁻¹ ut
- Fit GARCH(1,1) to each ε_j,t
- Use conditional covariances to re-estimate B₀
- Repeat until convergence
Reference: Normandin & Phaneuf (2004)
MacroEconometricModels.identify_smooth_transition — Function
identify_smooth_transition(model::VARModel, transition_var::AbstractVector;
max_iter=500, tol=1e-6) -> SmoothTransitionSVARResultIdentify SVAR via smooth-transition heteroskedasticity (Lütkepohl & Netšunajev 2017).
The covariance matrix varies smoothly between two regimes:
\[\Sigma_t = B_0 [I + G(s_t)(\Lambda - I)] B_0'\]
where G(st) = 1/(1 + exp(-γ(st - c))) is the logistic transition function.
Arguments:
transition_var— the transition variable s_t (e.g., a lagged endogenous variable)
Reference: Lütkepohl & Netšunajev (2017)
MacroEconometricModels.identify_external_volatility — Function
identify_external_volatility(model::VARModel, regime_indicator::AbstractVector{Int};
regimes=2) -> ExternalVolatilitySVARResultIdentify SVAR via externally specified volatility regimes (Rigobon 2003).
Uses a known regime indicator (e.g., NBER recessions, financial crises) to split the sample and estimate regime-specific covariance matrices.
Arguments:
regime_indicator— integer vector of regime labels (1, 2, ..., K)regimes— number of distinct regimes (default: 2)
Reference: Rigobon (2003)
Identifiability Tests
MacroEconometricModels.test_identification_strength — Function
test_identification_strength(model::VARModel; method=:fastica,
n_bootstrap=999) -> IdentifiabilityTestResultTest the strength of non-Gaussian identification via bootstrap.
Resamples residuals with replacement, re-estimates B₀, and computes the Procrustes distance between bootstrap and original B₀. Small distances indicate strong identification.
Returns: test statistic = median Procrustes distance, p-value from distribution.
MacroEconometricModels.test_shock_gaussianity — Function
test_shock_gaussianity(result::ICASVARResult) -> IdentifiabilityTestResult
test_shock_gaussianity(result::NonGaussianMLResult) -> IdentifiabilityTestResultTest whether recovered structural shocks are non-Gaussian using univariate JB tests.
Non-Gaussian identification requires at most one shock to be Gaussian. This test checks each shock individually and reports the joint result.
At most one Gaussian shock → identification holds.
MacroEconometricModels.test_gaussian_vs_nongaussian — Function
test_gaussian_vs_nongaussian(model::VARModel; distribution=:student_t) -> IdentifiabilityTestResultLikelihood ratio test: H₀ Gaussian vs H₁ non-Gaussian structural shocks.
Under H₀, the LR statistic LR = 2(ℓ₁ - ℓ₀) ~ χ²(nextraparams).
MacroEconometricModels.test_shock_independence — Function
test_shock_independence(result::ICASVARResult; max_lag=10) -> IdentifiabilityTestResult
test_shock_independence(result::NonGaussianMLResult; max_lag=10) -> IdentifiabilityTestResultTest independence of recovered structural shocks.
Uses both cross-correlation (portmanteau) and distance covariance tests. Independence is a necessary condition for valid identification.
MacroEconometricModels.test_overidentification — Function
test_overidentification(model::VARModel, result::AbstractNonGaussianSVAR;
restrictions=nothing, n_bootstrap=499) -> IdentifiabilityTestResultTest overidentifying restrictions for non-Gaussian SVAR.
When additional restrictions beyond non-Gaussianity are imposed (e.g., zero restrictions on B₀), this test checks whether those restrictions are consistent with the data.
Uses a bootstrap approach: compares the restricted log-likelihood to bootstrap distribution.
Covariance Estimators
MacroEconometricModels.newey_west — Function
newey_west(X::AbstractMatrix{T}, residuals::AbstractVector{T};
bandwidth::Int=0, kernel::Symbol=:bartlett, prewhiten::Bool=false,
XtX_inv::Union{Nothing,AbstractMatrix{T}}=nothing) -> Matrix{T}Compute Newey-West HAC covariance matrix.
V_NW = (X'X)^{-1} S (X'X)^{-1} where S = Γ₀ + Σⱼ₌₁ᵐ w(j) (Γⱼ + Γⱼ')
Arguments
X: Design matrix (n × k)residuals: Residuals vector (n × 1)bandwidth: Truncation lag (0 = automatic selection)kernel: Kernel functionprewhiten: Use AR(1) prewhiteningXtX_inv: Pre-computed (X'X)^{-1} for performance (optional)
Returns
Robust covariance matrix (k × k)
Performance
Pass XtX_inv when calling multiple times with the same X to avoid recomputation.
newey_west(X::AbstractMatrix{T}, residuals::AbstractMatrix{T}; ...) -> Matrix{T}Multivariate version for systems of equations.
MacroEconometricModels.white_vcov — Function
white_vcov(X::AbstractMatrix{T}, residuals::AbstractVector{T}; variant::Symbol=:hc0,
XtX_inv::Union{Nothing,AbstractMatrix{T}}=nothing) -> Matrix{T}White heteroscedasticity-robust covariance estimator.
Variants: :hc0, :hc1, :hc2, :hc3
Arguments
X: Design matrix (n × k)residuals: Residuals vector (n × 1)variant: HC variant (:hc0 = standard, :hc1 = small sample, :hc2/:hc3 = leverage-adjusted)XtX_inv: Pre-computed (X'X)^{-1} for performance (optional)
Returns
Robust covariance matrix (k × k)
Performance
Pass XtX_inv when calling multiple times with the same X to avoid recomputation.
white_vcov(X::AbstractMatrix{T}, residuals::AbstractMatrix{T}; ...) -> Matrix{T}Multivariate version.
MacroEconometricModels.driscoll_kraay — Function
driscoll_kraay(X::AbstractMatrix{T}, u::AbstractVector{T};
bandwidth::Int=0, kernel::Symbol=:bartlett,
XtX_inv::Union{Nothing,AbstractMatrix{T}}=nothing) -> Matrix{T}Driscoll-Kraay standard errors for time series regression.
In a pure time series context, this is equivalent to Newey-West HAC estimation applied to the moment conditions X'u. For panel data applications, it would average across cross-sectional units first, but here we treat the data as a single time series.
Arguments
X: Design matrix (T × k)u: Residuals vector (T × 1)bandwidth: Bandwidth for kernel. If 0, uses optimal bandwidth selection.kernel: Kernel function (:bartlett, :parzen, :quadraticspectral, :tukeyhanning)XtX_inv: Pre-computed (X'X)^{-1} for performance (optional)
Returns
Robust covariance matrix (k × k)
References
- Driscoll, J. C., & Kraay, A. C. (1998). Consistent covariance matrix estimation with spatially dependent panel data. Review of Economics and Statistics.
Performance
Pass XtX_inv when calling multiple times with the same X to avoid recomputation.
driscoll_kraay(X::AbstractMatrix{T}, U::AbstractMatrix{T};
bandwidth::Int=0, kernel::Symbol=:bartlett) -> Matrix{T}Driscoll-Kraay standard errors for multi-equation system.
MacroEconometricModels.robust_vcov — Function
robust_vcov(X::AbstractMatrix{T}, residuals::AbstractVecOrMat{T},
estimator::AbstractCovarianceEstimator) -> Matrix{T}Dispatch to appropriate covariance estimator based on estimator type.
MacroEconometricModels.long_run_variance — Function
long_run_variance(x::AbstractVector{T}; bandwidth::Int=0, kernel::Symbol=:bartlett) -> TEstimate long-run variance: S = Σⱼ₌₋∞^∞ γⱼ
Used for unit root tests, cointegration tests, and other applications requiring consistent variance estimation under serial correlation.
Arguments
x: Time series vectorbandwidth: Truncation lag (0 = automatic)kernel: Kernel function
Returns
Long-run variance estimate (scalar)
MacroEconometricModels.long_run_covariance — Function
long_run_covariance(X::AbstractMatrix{T}; bandwidth::Int=0, kernel::Symbol=:bartlett) -> Matrix{T}Estimate long-run covariance matrix of multivariate time series.
Arguments
X: Multivariate time series (T × k)bandwidth: Truncation lag (0 = automatic)kernel: Kernel function
Returns
Long-run covariance matrix (k × k)
Performance
Uses BLAS matrix operations for lag autocovariance computation.
MacroEconometricModels.optimal_bandwidth_nw — Function
optimal_bandwidth_nw(residuals::AbstractVector{T}) -> IntCompute optimal bandwidth using Newey-West (1994) automatic selection.
optimal_bandwidth_nw(residuals::AbstractMatrix{T}) -> IntMultivariate version: average optimal bandwidth across columns.
MacroEconometricModels.register_cov_estimator! — Function
register_cov_estimator!(name::Symbol, ::Type{T}) where {T<:AbstractCovarianceEstimator}Register a custom covariance estimator type for use in LP and other estimators.
Example
struct MyCovEstimator <: AbstractCovarianceEstimator end
register_cov_estimator!(:my_cov, MyCovEstimator)Plotting
Core Plot Functions
MacroEconometricModels.save_plot — Function
save_plot(p::PlotOutput, path::String)Write the HTML visualization to a file.
Example
p = plot_result(irf_result)
save_plot(p, "irf_plot.html")MacroEconometricModels.display_plot — Function
display_plot(p::PlotOutput)Open the HTML visualization in the system default browser.
Plot Dispatches
MacroEconometricModels.plot_result — Method
plot_result(r::BayesianImpulseResponse; var=nothing, shock=nothing, ncols=0, title="", save_path=nothing)Plot Bayesian IRF with posterior mean and quantile bands.
MacroEconometricModels.plot_result — Method
plot_result(r::ImpulseResponse; var=nothing, shock=nothing, ncols=0, title="", save_path=nothing)Plot frequentist impulse response functions with confidence bands.
var: Select response variable (index or name).nothing= all.shock: Select shock (index or name).nothing= all.ncols: Number of grid columns (0 = auto).
MacroEconometricModels.plot_result — Method
plot_result(r::LPImpulseResponse; var=nothing, ncols=0, title="", save_path=nothing)Plot LP impulse responses with robust CI bands.
MacroEconometricModels.plot_result — Method
plot_result(slp::StructuralLP; kwargs...)Plot structural LP impulse responses (delegates to ImpulseResponse plot).
MacroEconometricModels.plot_result — Method
plot_result(f::BayesianFEVD; var=nothing, stat=:mean, ncols=0, title="", save_path=nothing)Plot Bayesian FEVD (uses posterior mean by default).
f.point_estimate is H × nvars × nshocks.
MacroEconometricModels.plot_result — Method
plot_result(f::FEVD; var=nothing, ncols=0, title="", save_path=nothing)Plot forecast error variance decomposition as stacked area charts.
f.proportions is nvars × nshocks × H.
MacroEconometricModels.plot_result — Method
plot_result(f::LPFEVD; var=nothing, bias_corrected=true, ncols=0, title="", save_path=nothing)Plot LP-FEVD (Gorodnichenko & Lee 2019).
f.proportions and f.bias_corrected are nvars × nshocks × H.
MacroEconometricModels.plot_result — Method
plot_result(hd::BayesianHistoricalDecomposition; var=nothing, stat=:mean, ncols=0, title="", save_path=nothing)Plot Bayesian historical decomposition (uses posterior mean by default).
MacroEconometricModels.plot_result — Method
plot_result(hd::HistoricalDecomposition; var=nothing, ncols=0, title="", save_path=nothing)Plot historical decomposition: stacked bar of shock contributions + actual line.
var: Variable index or name.nothing= all variables.
MacroEconometricModels._plot_filter_panels — Method
Generate 2-panel Figure for a filter result: (1) Original + Trend, (2) Cycle.
tr: trend componentcyc: cycle componentfilter_name: display nameoriginal: original series (optional, reconstructed from trend+cycle if nil)offset: index offset for shorter filters (Hamilton, BK)T_obs: original series length
MacroEconometricModels.plot_result — Method
plot_result(r::BaxterKingResult; original=nothing, title="", save_path=nothing)Plot BK band-pass filter.
MacroEconometricModels.plot_result — Method
plot_result(r::BeveridgeNelsonResult; title="", save_path=nothing)Plot BN decomposition: permanent+original and transitory.
MacroEconometricModels.plot_result — Method
plot_result(r::BoostedHPResult; title="", save_path=nothing)Plot boosted HP filter.
MacroEconometricModels.plot_result — Method
plot_result(r::HPFilterResult; title="", save_path=nothing)Plot HP filter: original+trend and cycle.
MacroEconometricModels.plot_result — Method
plot_result(r::HamiltonFilterResult; original=nothing, title="", save_path=nothing)Plot Hamilton filter: original+trend and cycle.
Pass the original series via original kwarg since HamiltonFilterResult doesn't store it.
MacroEconometricModels.plot_result — Method
plot_result(fc::ARIMAForecast; history=nothing, n_history=50, title="", save_path=nothing)Plot ARIMA forecast with CI fan. Pass original series as history to show context.
MacroEconometricModels.plot_result — Method
plot_result(fc::BVARForecast; var=nothing, ncols=0, title="", save_path=nothing)Plot Bayesian VAR forecast with posterior credible bands.
MacroEconometricModels.plot_result — Method
plot_result(fc::FactorForecast; type=:both, var=nothing, ncols=0, title="",
n_obs=6, save_path=nothing)Plot factor model forecast.
type=:both: plot factor forecasts and top observable forecasts (default)type=:factor: plot factor forecasts onlytype=:observable: plot observable forecasts onlyn_obs: max number of observables to show whentype=:both(default 6)
MacroEconometricModels.plot_result — Method
plot_result(fc::LPForecast; var=nothing, ncols=0, title="", save_path=nothing)Plot LP direct multi-step forecast.
MacroEconometricModels.plot_result — Method
plot_result(fc::VARForecast; var=nothing, ncols=0, title="", save_path=nothing)Plot VAR forecast with bootstrap CI bands.
MacroEconometricModels.plot_result — Method
plot_result(fc::VECMForecast; var=nothing, ncols=0, title="", save_path=nothing)Plot VECM forecast in levels with CI bands.
MacroEconometricModels.plot_result — Method
plot_result(fc::VolatilityForecast; history=nothing, n_history=50, title="", save_path=nothing)Plot volatility forecast (conditional variance).
MacroEconometricModels._plot_volatility_diagnostics — Method
Generate 3-panel volatility diagnostic Figure:
- Returns
- Conditional volatility (σₜ)
- Standardized residuals (with ±2σ reference lines)
MacroEconometricModels._render_occbin_panel_js — Method
Render a single OccBin panel with linear (dashed) vs piecewise (solid) lines, shaded binding-period rectangles, and zero reference line.
Data format: [{h, lin, pw, bind}, ...] where bind is 0 or 1.
MacroEconometricModels.plot_result — Method
plot_result(m::ARCHModel; title="", save_path=nothing)Plot ARCH model diagnostics: returns, conditional volatility, standardized residuals.
MacroEconometricModels.plot_result — Method
plot_result(result::BayesianDSGE; title="", save_path=nothing, ncols=0)Plot prior vs posterior density for each estimated parameter. Each panel shows the prior density curve (dashed) and a kernel density estimate of the posterior draws (solid), with a vertical line at the posterior mean.
MacroEconometricModels.plot_result — Method
plot_result(m::BayesianFAVAR; title="", save_path=nothing)Plot Bayesian FAVAR: posterior mean factor series with 68% credible intervals.
MacroEconometricModels.plot_result — Method
plot_result(fm::DynamicFactorModel; title="", save_path=nothing)Plot dynamic factor model: scree + factor series.
MacroEconometricModels.plot_result — Method
plot_result(m::EGARCHModel; title="", save_path=nothing)Plot EGARCH model diagnostics.
MacroEconometricModels.plot_result — Method
plot_result(m::FAVARModel; title="", save_path=nothing)Plot FAVAR model: extracted factor series.
MacroEconometricModels.plot_result — Method
plot_result(fm::FactorModel; title="", save_path=nothing)Plot factor model: scree plot (eigenvalues) + extracted factor series.
MacroEconometricModels.plot_result — Method
plot_result(m::GARCHModel; title="", save_path=nothing)Plot GARCH model diagnostics.
MacroEconometricModels.plot_result — Method
plot_result(m::GJRGARCHModel; title="", save_path=nothing)Plot GJR-GARCH model diagnostics.
MacroEconometricModels.plot_result — Method
plot_result(oirf::OccBinIRF; title="", save_path=nothing)Plot OccBin IRF comparison: linear (dashed) vs piecewise-linear (solid) with shaded binding-period rectangles for each variable.
MacroEconometricModels.plot_result — Method
plot_result(sol::OccBinSolution; title="", save_path=nothing)Plot OccBin solution comparison: linear (dashed) vs piecewise-linear (solid) with shaded binding-period rectangles for each variable.
MacroEconometricModels.plot_result — Method
plot_result(d::PanelData; vars=nothing, ncols=0, title="", save_path=nothing)Plot panel data: one panel per variable, with lines for each group.
MacroEconometricModels.plot_result — Method
plot_result(m::SVModel; title="", save_path=nothing)Plot SV model diagnostics with posterior quantile bands on volatility.
MacroEconometricModels.plot_result — Method
plot_result(m::StructuralDFM; title="", save_path=nothing, var=nothing, ncols=0)Plot Structural DFM: structural IRFs for panel variables.
MacroEconometricModels.plot_result — Method
plot_result(d::TimeSeriesData; vars=nothing, ncols=0, title="", save_path=nothing)Plot time series data: one panel per variable (capped at 12).
vars: Variable indices or names to plot.nothing= all (up to 12).
MacroEconometricModels.plot_result — Method
plot_result(nn::NowcastNews; title="", save_path=nothing)Plot nowcast news decomposition: horizontal bar chart of per-release impact.
MacroEconometricModels.plot_result — Method
plot_result(nr::NowcastResult; ncols=0, title="", save_path=nothing)Plot nowcast result: smoothed data for target variable with nowcast/forecast values.
MacroEconometricModels._render_scatter_js — Method
Generate D3.js code for a scatter plot with color-coded groups and optional horizontal reference lines.
id: SVG container element IDdata_json: JSON array of {x, y, group} data pointsgroups_json: JSON array of {name, color} group configsref_lines_json: JSON array of {value, color, dash, axis} reference lines (axis = "x" or "y", default "y")xlabel,ylabel: axis labels
MacroEconometricModels.plot_result — Method
plot_result(bd::BaconDecomposition; title="", save_path=nothing)Plot Bacon decomposition as a scatter plot.
X-axis = 2x2 DiD estimate, Y-axis = weight, colored by comparison type. Horizontal dashed line at the overall TWFE estimate.
MacroEconometricModels.plot_result — Method
plot_result(did::DIDResult; title="", save_path=nothing)Plot DiD event study coefficients with confidence bands.
Displays ATT coefficients by event time with CI bands, a vertical dashed line at treatment time (event time = 0), a horizontal zero reference line, and the reference period marker.
MacroEconometricModels.plot_result — Method
plot_result(eslp::EventStudyLP; title="", save_path=nothing)Plot LP-based event study dynamic treatment effects with confidence bands.
Same style as DIDResult but uses coefficients from LP regressions. Title includes "(LP-DiD)" if clean_controls is true, else "(Event Study LP)".
MacroEconometricModels.plot_result — Method
plot_result(hd::HonestDiDResult; title="", save_path=nothing)Plot HonestDiD sensitivity analysis with dual CI bands.
Shows original confidence intervals (narrow) and robust confidence intervals (wide, accounting for parallel trends violations), with breakdown value annotated.
MacroEconometricModels._plot_binary_choice — Method
Generate 2-panel binary choice model diagnostic plot:
- Sorted predicted probabilities colored by outcome
- Distribution of predicted probabilities by outcome (grouped bar)
MacroEconometricModels._render_coef_plot_js — Method
Generate D3.js code for a horizontal coefficient plot with CI error bars.
id: SVG container element IDdata_json: JSON array of {name, effect, cilo, cihi} objectsxlabel,ylabel: axis labels
MacroEconometricModels.plot_result — Method
plot_result(m::LogitModel{T}; title="", save_path=nothing)Plot logit model diagnostics: sorted predicted probabilities by outcome and distribution of predictions by outcome group.
MacroEconometricModels.plot_result — Method
plot_result(me::MarginalEffects{T}; title="", save_path=nothing)Plot marginal effects as a horizontal coefficient plot with CI error bars.
MacroEconometricModels.plot_result — Method
plot_result(m::ProbitModel{T}; title="", save_path=nothing)Plot probit model diagnostics: sorted predicted probabilities by outcome and distribution of predictions by outcome group.
MacroEconometricModels.plot_result — Method
plot_result(m::RegModel{T}; title="", save_path=nothing)Plot OLS/WLS/IV regression diagnostics: residuals vs fitted, residual histogram, and Q-Q plot.
Utility Functions
MacroEconometricModels._default_names — Method
Generate default names: ["prefix 1", "prefix 2", ...]
MacroEconometricModels._suppress_warnings — Method
Suppress all log messages (warnings, info) within f(). Used in bootstrap loops.
MacroEconometricModels._validate_data — Function
Validate data contains no NaN or Inf values.
MacroEconometricModels._validate_narrative_data — Method
Validate that narrative method has required data matrix.
MacroEconometricModels._validate_var_shock_indices — Method
Resolve variable/shock names to indices, throwing on invalid names.
MacroEconometricModels.companion_matrix — Method
Construct companion matrix F for VAR(p) → VAR(1) representation.
MacroEconometricModels.construct_var_matrices — Method
Construct VAR design matrices: Yeff = X * B + U. Returns (Yeff, X) where X = [1, Y{t-1}, ..., Y{t-p}].
MacroEconometricModels.extract_ar_coefficients — Method
Extract AR coefficient matrices [A₁, ..., Aₚ] from stacked B matrix.
MacroEconometricModels.logdet_safe — Method
Log determinant with eigenvalue fallback for numerical issues.
MacroEconometricModels.robust_inv — Method
Compute inverse with fallback to pseudo-inverse for singular matrices. Pass silent=true to suppress the warning (e.g., in internal loops where singularity is expected).
MacroEconometricModels.safe_cholesky — Method
Cholesky decomposition with automatic jitter for numerical stability. Pass silent=true to suppress the jitter warning.
MacroEconometricModels.univariate_ar_variance — Method
AR(1) residual standard deviation for Minnesota prior scaling.
MacroEconometricModels.validate_dynamic_factor_inputs — Method
Validate dynamic factor model inputs.
MacroEconometricModels.validate_factor_inputs — Method
Validate factor model inputs: 1 ≤ r ≤ min(T, N).
MacroEconometricModels.validate_horizon — Method
Validate horizon: h ≥ min_val (default 1).
MacroEconometricModels.validate_in_range — Method
Validate lo ≤ value ≤ hi.
MacroEconometricModels.validate_lags — Method
Validate lag order: p ≥ 1.
MacroEconometricModels.validate_nonnegative — Method
Validate value ≥ 0.
MacroEconometricModels.validate_option — Method
Validate symbol is in valid_options.
MacroEconometricModels.validate_positive — Method
Validate value > 0.
MacroEconometricModels.validate_var_inputs — Method
Validate VAR inputs: p ≥ 1, T > p + minobsfactor, n ≥ 1.
Panel Regression
Panel Linear Models
MacroEconometricModels.estimate_xtreg — Function
estimate_xtreg(pd::PanelData{T}, depvar::Symbol, indepvars::Vector{Symbol};
model=:fe, twoway=false, cov_type=:cluster, bandwidth=nothing) -> PanelRegModel{T}Estimate a linear panel regression model.
Arguments
pd::PanelData{T}— panel data container (created viaxtset)depvar::Symbol— dependent variable nameindepvars::Vector{Symbol}— independent variable names
Keyword Arguments
model::Symbol—:fe,:re,:fd,:between, or:cre(default::fe)twoway::Bool— include time fixed effects (FE only, default:false)cov_type::Symbol— covariance type::ols,:cluster(default),:twoway,:driscoll_kraaybandwidth::Union{Nothing,Int}— Driscoll-Kraay bandwidth (default: auto)
Returns
PanelRegModel{T} with estimated coefficients, variance components, and R-squared variants.
Examples
using DataFrames
df = DataFrame(id=repeat(1:50, inner=20), t=repeat(1:20, 50),
x1=randn(1000), x2=randn(1000))
df.y = repeat(randn(50), inner=20) .+ 1.5 .* df.x1 .- 0.8 .* df.x2 .+ 0.5 .* randn(1000)
pd = xtset(df, :id, :t)
m_fe = estimate_xtreg(pd, :y, [:x1, :x2])
m_re = estimate_xtreg(pd, :y, [:x1, :x2]; model=:re)
m_fd = estimate_xtreg(pd, :y, [:x1, :x2]; model=:fd)
m_be = estimate_xtreg(pd, :y, [:x1, :x2]; model=:between)
m_cre = estimate_xtreg(pd, :y, [:x1, :x2]; model=:cre)References
- Baltagi, B. H. (2021). Econometric Analysis of Panel Data. 6th ed. Springer.
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press.
- Swamy, P. A. V. B. & Arora, S. S. (1972). Econometrica 40(2), 311-323.
- Mundlak, Y. (1978). Econometrica 46(1), 69-85.
Panel Instrumental Variables
MacroEconometricModels.estimate_xtiv — Function
estimate_xtiv(pd::PanelData{T}, depvar::Symbol, exog::Vector{Symbol}, endog::Vector{Symbol};
instruments::Vector{Symbol}, model::Symbol=:fe, cov_type::Symbol=:cluster,
time_invariant_exog::Vector{Symbol}=Symbol[],
time_invariant_endog::Vector{Symbol}=Symbol[]) -> PanelIVModel{T}Estimate a panel instrumental-variables regression model.
Arguments
pd::PanelData{T}— panel data container (created viaxtset)depvar::Symbol— dependent variable nameexog::Vector{Symbol}— exogenous regressors (time-varying for Hausman-Taylor)endog::Vector{Symbol}— endogenous regressors (time-varying for Hausman-Taylor)
Keyword Arguments
instruments::Vector{Symbol}— excluded instrumentsmodel::Symbol—:fe(FE-IV),:re(EC2SLS),:fd(FD-IV),:hausman_taylorcov_type::Symbol—:ols,:cluster(default)time_invariant_exog::Vector{Symbol}— time-invariant exogenous (Hausman-Taylor only)time_invariant_endog::Vector{Symbol}— time-invariant endogenous (Hausman-Taylor only)
Returns
PanelIVModel{T} with estimated coefficients, first-stage F, and Sargan test.
Methods
- FE-IV (
model=:fe): Within-transform then 2SLS. No intercept. - RE-IV / EC2SLS (
model=:re): Quasi-demean then 2SLS with [Z̃, Z̄ᵢ] instruments. - FD-IV (
model=:fd): First-difference then 2SLS with intercept. - Hausman-Taylor (
model=:hausman_taylor): GLS-IV using within-deviations of time-varying exogenous as instruments for time-invariant endogenous.
Examples
using DataFrames
df = DataFrame(id=repeat(1:50, inner=20), t=repeat(1:20, 50),
x=randn(1000), z=randn(1000))
df.x_endog = 0.5 .* df.z .+ randn(1000)
df.y = repeat(randn(50), inner=20) .+ 1.5 .* df.x .+ 2.0 .* df.x_endog .+ randn(1000)
pd = xtset(df, :id, :t)
m = estimate_xtiv(pd, :y, [:x], [:x_endog]; instruments=[:z])References
- Baltagi, B. H. (2021). Econometric Analysis of Panel Data. 6th ed. Springer, ch. 7.
- Hausman, J. A. & Taylor, W. E. (1981). Econometrica 49(6), 1377-1398.
- Baltagi, B. H. (1981). Econometrica 49(4), 1049-1054. (EC2SLS)
Panel Discrete Choice
MacroEconometricModels.estimate_xtlogit — Function
estimate_xtlogit(pd, depvar, indepvars; model=:pooled, cov_type=:cluster,
maxiter=200, tol=1e-8, n_quadrature=12) -> PanelLogitModel{T}Estimate a panel logistic regression model.
Arguments
pd::PanelData{T}– panel data container (created viaxtset)depvar::Symbol– binary dependent variable (0/1)indepvars::Vector{Symbol}– independent variable names
Keyword Arguments
model::Symbol–:pooled,:fe,:re, or:cre(default::pooled)cov_type::Symbol– covariance type::ols,:cluster(default)maxiter::Int– maximum iterations (default 200)tol– convergence tolerance (default 1e-8)n_quadrature::Int– Gauss-Hermite quadrature points for RE/CRE (default 12)
Returns
PanelLogitModel{T} with estimated coefficients and diagnostics.
Examples
using DataFrames
df = DataFrame(id=repeat(1:50, inner=10), t=repeat(1:10, 50),
x1=randn(500), x2=randn(500))
df.y = Float64.(rand(500) .< 1 ./ (1 .+ exp.(-1.0 .* df.x1 .+ 0.5 .* df.x2)))
pd = xtset(df, :id, :t)
m = estimate_xtlogit(pd, :y, [:x1, :x2])
m_fe = estimate_xtlogit(pd, :y, [:x1, :x2]; model=:fe)
m_re = estimate_xtlogit(pd, :y, [:x1, :x2]; model=:re)References
- Chamberlain, G. (1980). Review of Economic Studies 47(1), 225-238.
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press.
MacroEconometricModels.estimate_xtprobit — Function
estimate_xtprobit(pd, depvar, indepvars; model=:pooled, cov_type=:cluster,
maxiter=200, tol=1e-8, n_quadrature=12) -> PanelProbitModel{T}Estimate a panel probit regression model.
Arguments
pd::PanelData{T}– panel data container (created viaxtset)depvar::Symbol– binary dependent variable (0/1)indepvars::Vector{Symbol}– independent variable names
Keyword Arguments
model::Symbol–:pooled,:re, or:cre(default::pooled). No:fe— the incidental parameters problem has no conditioning trick for probit.cov_type::Symbol– covariance type::ols,:cluster(default)maxiter::Int– maximum iterations (default 200)tol– convergence tolerance (default 1e-8)n_quadrature::Int– Gauss-Hermite quadrature points for RE/CRE (default 12)
Returns
PanelProbitModel{T} with estimated coefficients and diagnostics.
Examples
using DataFrames, Distributions
df = DataFrame(id=repeat(1:50, inner=10), t=repeat(1:10, 50),
x1=randn(500), x2=randn(500))
p = cdf.(Normal(), 0.8 .* df.x1 .- 0.5 .* df.x2)
df.y = Float64.(rand(500) .< p)
pd = xtset(df, :id, :t)
m = estimate_xtprobit(pd, :y, [:x1, :x2])
m_re = estimate_xtprobit(pd, :y, [:x1, :x2]; model=:re)References
- Wooldridge, J. M. (2010). Econometric Analysis of Cross Section and Panel Data. 2nd ed. MIT Press.
Panel Specification Tests
MacroEconometricModels.hausman_test — Function
hausman_test(fe::PanelRegModel, re::PanelRegModel) -> PanelTestResult{T}Hausman specification test for fixed vs random effects.
H0: Random effects is consistent (both FE and RE consistent under H0). H1: Random effects is inconsistent (only FE consistent).
Computes chi2 = (betaFE - betaRE)' (VFE - VRE)^{-1} (betaFE - betaRE) on the common slope coefficients (intercept excluded from RE).
Arguments
fe::PanelRegModel— fixed effects modelre::PanelRegModel— random effects model
Returns
PanelTestResult{T} with chi-squared statistic and p-value.
References
- Hausman, J. A. (1978). Econometrica 46(6), 1251-1271.
MacroEconometricModels.breusch_pagan_test — Function
breusch_pagan_test(re::PanelRegModel) -> PanelTestResult{T}Breusch-Pagan Lagrange multiplier test for random effects.
H0: sigmau^2 = 0 (pooled OLS is adequate). H1: sigmau^2 > 0 (random effects needed).
LM = (nT / (2(T-1))) * [sumi (sumt eit)^2 / (sumi sumt eit^2) - 1]^2
Arguments
re::PanelRegModel— random effects model (pooled OLS residuals computed internally)
Returns
PanelTestResult{T} with chi-squared(1) statistic and p-value.
References
- Breusch, T. S. & Pagan, A. R. (1980). Review of Economic Studies 47(1), 239-253.
MacroEconometricModels.pesaran_cd_test — Function
pesaran_cd_test(m::PanelRegModel) -> PanelTestResult{T}Pesaran CD test for cross-sectional dependence in panel residuals.
H0: No cross-sectional dependence. H1: Cross-sectional dependence present.
CD = sqrt(2 / (N(N-1))) * sum{i<j} sqrt(Tij) * rho_ij
where rho_ij is the pairwise residual correlation for groups i, j over their overlapping time periods.
Arguments
m::PanelRegModel— any panel regression model (FE, RE, etc.)
Returns
PanelTestResult{T} with standard normal test statistic and p-value.
References
- Pesaran, M. H. (2004). Cambridge Working Papers in Economics No. 0435.
- Pesaran, M. H. (2015). Econometrica 83(4), 1481-1507.
MacroEconometricModels.wooldridge_ar_test — Function
wooldridge_ar_test(fe::PanelRegModel) -> PanelTestResult{T}Wooldridge test for first-order serial correlation in FE panel residuals.
H0: No serial correlation in idiosyncratic errors. H1: AR(1) serial correlation present.
Procedure:
- Compute first-differences of FE residuals within each group
- Regress Deltaeit on Deltaei,t-1 (pooled OLS)
- Test H0: coefficient = -0.5 (under no serial correlation, first-differenced iid errors have autocorrelation -0.5)
Arguments
fe::PanelRegModel— fixed effects model
Returns
PanelTestResult{T} with F(1, N-1) statistic and p-value.
References
- Wooldridge, J. M. (2002). Econometric Analysis of Cross Section and Panel Data. MIT Press. Ch. 10.
- Drukker, D. M. (2003). Stata Journal 3(2), 168-177.
MacroEconometricModels.modified_wald_test — Function
modified_wald_test(fe::PanelRegModel) -> PanelTestResult{T}Modified Wald test for groupwise heteroskedasticity in FE panel residuals.
H0: sigma_i^2 = sigma^2 for all i (homoskedasticity across groups). H1: At least one group has different error variance.
W = sumi (sigmai^2 - sigma^2)^2 / (2 * sigmai^4 / Ti)
Arguments
fe::PanelRegModel— fixed effects model
Returns
PanelTestResult{T} with chi-squared(N) statistic and p-value.
References
- Greene, W. H. (2018). Econometric Analysis. 8th ed. Pearson. Ch. 9.
- Baum, C. F. (2001). Stata Journal 1(1), 101-104.
MacroEconometricModels.f_test_fe — Function
f_test_fe(fe::PanelRegModel) -> PanelTestResult{T}F-test for joint significance of all entity fixed effects.
H0: all alphai = 0 (pooled OLS is adequate). H1: at least one alphai != 0 (entity effects present).
F = ((SSRpooled - SSRFE) / (N-1)) / (SSR_FE / (NT - N - K))
Arguments
fe::PanelRegModel— fixed effects model
Returns
PanelTestResult{T} with F(N-1, NT-N-K) statistic and p-value.
References
- Baltagi, B. H. (2021). Econometric Analysis of Panel Data. 6th ed. Springer. Ch. 4.
Spectral Analysis
Spectral Estimation
MacroEconometricModels.periodogram — Function
periodogram(y::AbstractVector; window::Symbol=:rectangular, conf_level::Real=0.95) -> SpectralDensityResultCompute the raw periodogram of y.
Arguments
y— time series vectorwindow— data window/taper (default::rectangular; see_spectral_window)conf_level— confidence level for chi-squared CI (default: 0.95)
Returns
SpectralDensityResult with frequency grid, density, and confidence bounds.
MacroEconometricModels.spectral_density — Function
spectral_density(y::AbstractVector; method::Symbol=:welch, kwargs...) -> SpectralDensityResultEstimate the spectral density of y.
Methods
:welch— Welch's averaged modified periodogram (default):smoothed— kernel-smoothed periodogram (Daniell kernel):ar— AR parametric spectrum via Burg's method
Common Keyword Arguments
window::Symbol=:hann— data windowconf_level::Real=0.95— confidence level
Method-Specific Keywords
:welch
segment_length::Int=0— segment length (default: n ÷ 4, minimum 16)overlap::Real=0.5— fraction overlap ∈ [0, 1)
:smoothed
bandwidth::Int=0— kernel half-width (default: ⌊√n⌋)
:ar
order::Int=0— AR order (default: AIC-selected)n_freq::Int=256— number of frequency grid points
MacroEconometricModels.cross_spectrum — Function
cross_spectrum(x::AbstractVector, y::AbstractVector;
window::Symbol=:hann, segment_length::Int=0,
overlap::Real=0.5) -> CrossSpectrumResultEstimate the cross-spectral density between x and y using Welch's method.
Arguments
x,y— time series vectors (same length)window— data window (default::hann)segment_length— segment length (default: n ÷ 4)overlap— fraction overlap (default: 0.5)
Returns
CrossSpectrumResult with co-spectrum, quadrature spectrum, coherence, phase, and gain.
Autocorrelation Functions
MacroEconometricModels.acf — Function
acf(y::AbstractVector; lags::Int=0, conf_level::Real=0.95) -> ACFResultCompute the sample autocorrelation function.
Arguments
y— time series vectorlags— maximum lag (default: min(n-1, 10*log10(n)))conf_level— confidence level for the white-noise band (default: 0.95)
Returns
ACFResult with ACF values, empty PACF, Ljung-Box Q-stats, and p-values.
Example
result = acf(randn(200), lags=20)
result.acf # autocorrelation at lags 1:20
result.q_pvalues # Ljung-Box p-valuesMacroEconometricModels.pacf — Function
pacf(y::AbstractVector; lags::Int=0, method::Symbol=:levinson, conf_level::Real=0.95) -> ACFResultCompute the sample partial autocorrelation function.
Arguments
y— time series vectorlags— maximum lag (default: min(n-1, 10*log10(n)))method—:levinson(Levinson-Durbin, default) or:olsconf_level— confidence level for the white-noise band (default: 0.95)
Returns
ACFResult with PACF values, empty ACF, and no Q-stats.
MacroEconometricModels.ccf — Function
ccf(x::AbstractVector, y::AbstractVector; lags::Int=0, conf_level::Real=0.95) -> ACFResultCompute the cross-correlation function between x and y.
Returns CCF(k) = Cor(x{t+k}, yt) for k = -lags:lags, stored in the ccf field. Positive lags mean x leads y.
Arguments
x,y— time series vectors (same length)lags— maximum lag (default: min(n-1, 10*log10(n)))conf_level— confidence level (default: 0.95)
Returns
ACFResult with ccf field populated. The lags field runs from -lags to +lags.
MacroEconometricModels.acf_pacf — Function
acf_pacf(y::AbstractVector; lags::Int=0, method::Symbol=:levinson, conf_level::Real=0.95) -> ACFResultCompute both ACF and PACF in a single pass.
Arguments
Same as acf() / pacf().
Returns
ACFResult with both acf and pacf fields populated, plus Ljung-Box Q-stats.
Spectral Diagnostics
MacroEconometricModels.coherence — Function
coherence(x::AbstractVector, y::AbstractVector; kwargs...) -> Tuple{Vector, Vector}Compute squared coherence between x and y. Returns (freq, coherence).
MacroEconometricModels.phase — Function
phase(x::AbstractVector, y::AbstractVector; kwargs...) -> Tuple{Vector, Vector}Compute phase spectrum between x and y. Returns (freq, phase).
MacroEconometricModels.gain — Function
gain(x::AbstractVector, y::AbstractVector; kwargs...) -> Tuple{Vector, Vector}Compute gain (amplitude ratio) between x and y. Returns (freq, gain).
MacroEconometricModels.band_power — Function
band_power(result::SpectralDensityResult, f_low::Real, f_high::Real) -> RealCompute the power (integrated spectral density) in frequency band [flow, fhigh].
Frequencies are in radians ∈ [0, π].
Arguments
result— aSpectralDensityResultfromperiodogramorspectral_densityf_low— lower frequency bound (radians)f_high— upper frequency bound (radians)
Returns
Integrated spectral density in the specified band.
MacroEconometricModels.ideal_bandpass — Function
ideal_bandpass(y::AbstractVector, f_low::Real, f_high::Real) -> VectorApply an ideal (brick-wall) bandpass filter in the frequency domain.
Retains frequency components in flow, fhigh and zeroes everything else. Implements via FFT → zero outside band → IFFT.
Arguments
y— time series vectorf_low— lower cutoff frequency (radians)f_high— upper cutoff frequency (radians)
Returns
Filtered series (real-valued vector of same length as y).
Example
# Extract business-cycle frequencies (6-32 quarters)
y_bc = ideal_bandpass(gdp, 2π/32, 2π/6)MacroEconometricModels.transfer_function — Function
transfer_function(filter::Symbol; lambda::Real=1600, K::Int=12,
h::Int=8, n_freq::Int=256) -> TransferFunctionResultCompute the frequency response (gain and phase) of a time-series filter.
Arguments
filter— filter type::hp,:bk, or:hamiltonlambda— HP filter smoothing parameter (default: 1600 for quarterly)K— Baxter-King half-window length (default: 12)h— Hamilton filter horizon (default: 8)n_freq— number of frequency grid points (default: 256)
Returns
TransferFunctionResult with gain and phase at each frequency.
Example
tf = transfer_function(:hp, lambda=1600)
tf.gain # HP filter gain at each frequencyPortmanteau and Serial Correlation Tests
MacroEconometricModels.ljung_box_test — Function
ljung_box_test(y::AbstractVector; lags::Int=0, fitdf::Int=0) -> LjungBoxResultLjung-Box Q test for serial correlation (H₀: no autocorrelation up to lag lags).
Arguments
y— time series or residualslags— number of lags (default: min(n-1, 10*log10(n)))fitdf— number of fitted parameters to subtract from DOF (e.g., p+q for ARMA(p,q))
Returns
LjungBoxResult with Q-statistic and p-value.
MacroEconometricModels.box_pierce_test — Function
box_pierce_test(y::AbstractVector; lags::Int=0, fitdf::Int=0) -> BoxPierceResultBox-Pierce Q₀ test for serial correlation. Simpler (unweighted) version of Ljung-Box.
Arguments
Same as ljung_box_test.
MacroEconometricModels.durbin_watson_test — Function
durbin_watson_test(resid::AbstractVector) -> DurbinWatsonResultDurbin-Watson test for first-order autocorrelation in residuals.
DW ≈ 2(1 - ρ̂₁). Values near 2 indicate no autocorrelation; near 0 indicates positive autocorrelation; near 4 indicates negative.
Arguments
resid— regression residuals
Returns
DurbinWatsonResult with DW statistic and approximate p-value.
MacroEconometricModels.bartlett_white_noise_test — Function
bartlett_white_noise_test(y::AbstractVector) -> BartlettWhiteNoiseResultBartlett's cumulative periodogram test for white noise.
Under H₀ (white noise), the cumulative normalized periodogram should follow a uniform distribution. The KS statistic measures the maximum deviation.
Arguments
y— time series vector
Returns
BartlettWhiteNoiseResult with KS statistic and p-value.
MacroEconometricModels.fisher_test — Function
fisher_test(y::AbstractVector) -> FisherTestResultFisher's exact test for hidden periodicities.
Tests H₀: y is white noise (no dominant frequency) against H₁: there exists a periodic component. The test statistic is g = max(I(ωⱼ)) / Σ I(ωⱼ).
Arguments
y— time series vector
Returns
FisherTestResult with test statistic and p-value.
Structural Break Tests
MacroEconometricModels.andrews_test — Function
andrews_test(y, X; test=:supwald, trimming=0.15) -> AndrewsResultAndrews (1993) / Andrews-Ploberger (1994) structural break test for a single unknown break point in a linear regression model y = X*beta + u.
Tests H0: no structural break vs H1: single structural break at unknown date.
Arguments
y::AbstractVector: Dependent variable (n x 1)X::AbstractMatrix: Regressor matrix (n x k)test::Symbol: Test variant. One of::supwald,:suplr,:suplm— supremum (Andrews 1993):expwald,:explr,:explm— exponential average (Andrews-Ploberger 1994):meanwald,:meanlr,:meanlm— simple average (Andrews-Ploberger 1994)
trimming::Real: Fraction of sample to trim from each end (default: 0.15)
Returns
AndrewsResult{T} with test statistic, p-value, estimated break date, and full sequence of statistics across candidate break dates.
Example
X = hcat(ones(100), randn(100))
y = X * [1.0, 2.0] + randn(100) * 0.5
y[51:end] .+= X[51:end, 2] .* 3.0 # introduce break at t=50
result = andrews_test(y, X; test=:supwald)
result.pvalue < 0.05 # should reject H0References
- Andrews, D. W. K. (1993). Tests for parameter instability and structural change with unknown change point. Econometrica, 61(4), 821-856.
- Andrews, D. W. K., & Ploberger, W. (1994). Optimal tests when a nuisance parameter is present only under the alternative. Econometrica, 62(6), 1383-1414.
- Hansen, B. E. (1997). Approximate asymptotic p values for structural-change tests. Journal of Business & Economic Statistics, 15(1), 60-67.
MacroEconometricModels.bai_perron_test — Function
bai_perron_test(y, X; max_breaks=5, trimming=0.15, criterion=:bic) -> BaiPerronResultBai-Perron (1998, 2003) test for multiple structural breaks in a linear regression.
Tests for m unknown structural break points in the linear model y = X β + u, where regression coefficients are allowed to change at each break date. Uses dynamic programming to find globally optimal break dates minimizing total sum of squared residuals. Break number is selected by BIC or LWZ information criteria.
Arguments
y::AbstractVector: Dependent variable (length n)X::AbstractMatrix: Regressor matrix (n × k)max_breaks::Int=5: Maximum number of breaks to considertrimming::Real=0.15: Minimum fraction of observations per segmentcriterion::Symbol=:bic: Information criterion for break selection (:bicor:lwz)
Returns
BaiPerronResult{T} containing estimated break dates, regime coefficients, sup-F and sequential test statistics, BIC/LWZ values, and confidence intervals.
Example
T = 200
X = ones(T, 1)
y = vcat(ones(100) * 2.0, ones(100) * 5.0) + randn(T) * 0.5
result = bai_perron_test(y, X; max_breaks=3)
result.n_breaks # Should detect 1 break
result.break_dates # Approximately [100]References
- Bai, J., & Perron, P. (1998). Estimating and testing linear models with multiple structural changes. Econometrica, 66(1), 47-78.
- Bai, J., & Perron, P. (2003). Computation and analysis of multiple structural change models. Journal of Applied Econometrics, 18(1), 1-22.
MacroEconometricModels.factor_break_test — Function
factor_break_test(X, r; method=:breitung_eickmeier) -> FactorBreakResult
factor_break_test(fm::FactorModel; method=:breitung_eickmeier) -> FactorBreakResult
factor_break_test(X; method=:chen_dolado_gonzalo) -> FactorBreakResultTest for structural breaks in factor models.
Methods
:breitung_eickmeier— Breitung & Eickmeier (2011) loading stability CUSUM test:chen_dolado_gonzalo— Chen, Dolado & Gonzalo (2014) change in number of factors:han_inoue— Han & Inoue (2015) sup-Wald loading instability test
Arguments
X: Data matrix (T × N), observations × variablesr: Number of factors (required for :breitungeickmeier and :haninoue)fm: EstimatedFactorModel(alternative to providing X and r)
Returns
FactorBreakResult{T} with test statistic, p-value, estimated break date, and method.
Examples
X = randn(200, 50)
result = factor_break_test(X, 3; method=:breitung_eickmeier)
result.pvalue < 0.05 && println("Reject loading stability at 5%")
# Using FactorModel dispatch
fm = estimate_factors(X, 3)
result = factor_break_test(fm; method=:han_inoue)
# Chen-Dolado-Gonzalo does not require r
result = factor_break_test(X; method=:chen_dolado_gonzalo)Panel Unit Root Tests
MacroEconometricModels.panic_test — Function
panic_test(X::AbstractMatrix{T}; r=:auto, method=:pooled) -> PANICResult{T}Bai-Ng (2004, 2010) PANIC panel unit root test.
Decomposes panel data X (T x N) into common factors and idiosyncratic errors via PCA, then tests each component for unit roots.
Arguments
X: Panel data matrix (T x N), time in rows, units in columns
Keyword Arguments
r::Union{Int,Symbol}=:auto: Number of common factors (:autouses IC criteria)method::Symbol=:pooled: Pooling method (:pooledor:individual)
Returns
PANICResult{T} with factor ADF statistics, individual unit statistics, and pooled test statistic.
Example
X = randn(100, 20)
result = panic_test(X; r=1)
result.pooled_pvalue # p-value for pooled idiosyncratic unit root testReferences
- Bai, J., & Ng, S. (2004). Econometrica, 72(4), 1127-1177.
- Bai, J., & Ng, S. (2010). Econometric Theory, 26(4), 1088-1114.
MacroEconometricModels.pesaran_cips_test — Function
pesaran_cips_test(X::AbstractMatrix{T}; lags=:auto, deterministic=:constant) -> PesaranCIPSResult{T}Pesaran (2007) CIPS panel unit root test.
Augments individual ADF regressions with cross-sectional averages to account for cross-sectional dependence.
Arguments
X: Panel data matrix (T x N), time in rows, units in columns
Keyword Arguments
lags::Union{Int,Symbol}=:auto: Number of augmenting lags (:autoselects via floor(T^(1/3)))deterministic::Symbol=:constant: Deterministic terms (:none,:constant,:trend)
Returns
PesaranCIPSResult{T} with CIPS statistic, individual CADF statistics, critical values, and p-value.
Example
X = randn(50, 20)
result = pesaran_cips_test(X; lags=1)
result.pvalue # p-value for panel unit root testReferences
- Pesaran, M. H. (2007). Journal of Applied Econometrics, 22(2), 265-312.
MacroEconometricModels.moon_perron_test — Function
moon_perron_test(X::AbstractMatrix{T}; r=:auto) -> MoonPerronResult{T}Moon-Perron (2004) panel unit root test with factor adjustment.
Projects out common factors from panel data, then constructs modified pooled t-statistics with bias and variance corrections.
Arguments
X: Panel data matrix (T x N), time in rows, units in columns
Keyword Arguments
r::Union{Int,Symbol}=:auto: Number of common factors (:autouses IC criteria)
Returns
MoonPerronResult{T} with two modified t-statistics (ta^*, tb^*) and their p-values (standard normal under H0).
Example
X = randn(80, 15)
result = moon_perron_test(X; r=1)
result.pvalue_a # p-value for t_a^* statistic
result.pvalue_b # p-value for t_b^* statisticReferences
- Moon, H. R., & Perron, B. (2004). Journal of Econometrics, 122(1), 81-126.
MacroEconometricModels.panel_unit_root_summary — Function
panel_unit_root_summary(X; r=:auto, lags=:auto) -> NothingPrint a summary of three panel unit root tests: PANIC (Bai-Ng 2004), Pesaran CIPS (2007), and Moon-Perron (2004).
Arguments
X::AbstractMatrix: Panel data (T × N)r: Number of factors for PANIC and Moon-Perron (:autofor IC selection)lags: Number of lags for CIPS (:autofor T^{1/3} rule)
Example
X = randn(100, 20)
panel_unit_root_summary(X; r=1)FAVAR
MacroEconometricModels.estimate_favar — Function
estimate_favar(X, Y_key, r, p; method=:two_step, panel_varnames=nothing) -> FAVARModel
estimate_favar(X, key_indices::Vector{Int}, r, p; ...) -> FAVARModelEstimate a Factor-Augmented VAR (Bernanke, Boivin & Eliasz, 2005).
Two-Step Algorithm (BBE 2005)
- Extract
rfactors from panelXvia PCA (estimate_factors) - Remove double-counting: regress each factor on
Y_key, use residuals as slow-moving factorsF_tilde - Estimate VAR(p) on augmented system
[F_tilde, Y_key]
Arguments
X: Panel data matrix (T x N) — large cross-section of macroeconomic variablesY_key: Key observed variables (T x n_key) or column indices into Xr: Number of latent factors to extractp: VAR lag order
Keyword Arguments
method::Symbol=:two_step: Estimation method (currently only:two_step)panel_varnames::Union{Nothing, Vector{String}}=nothing: Names for the N panel variablesn_draws::Int=5000: Number of posterior draws (for Bayesian, reserved for future use)burnin::Int=1000: Burn-in draws (for Bayesian, reserved for future use)
Returns
FAVARModel{T} with estimated VAR on [Ftilde, Ykey], factor loadings, and panel variable metadata for panel-wide IRF mapping.
Example
X = randn(200, 50) # 200 obs, 50 variables
Y_key = X[:, [1, 5]] # 2 key variables
favar = estimate_favar(X, Y_key, 3, 2)
# Or using column indices:
favar = estimate_favar(X, [1, 5], 3, 2)
# IRFs (via to_var delegation):
irf_result = irf(favar, 20)
# Panel-wide IRFs (all 50 variables):
panel_irfs = favar_panel_irf(favar, irf_result)estimate_favar(X, key_indices::Vector{Int}, r, p; kwargs...) -> FAVARModel or BayesianFAVAREstimate FAVAR where key variables are specified as column indices of X.
MacroEconometricModels.favar_panel_irf — Function
favar_panel_irf(favar::FAVARModel, irf_result::ImpulseResponse) -> ImpulseResponseMap factor-space IRFs to all N panel variables using the factor loadings.
For each panel variable i and shock j: panelirf[h, i, j] = sumk Lambda[i, k] * irf_result.values[h, k, j]
where Lambda is the N x r loading matrix from PCA.
Key variables (those in Y_key_indices) use their direct VAR IRF responses instead of the factor mapping, providing exact impulse responses for the variables that enter the FAVAR directly.
Arguments
favar: Estimated FAVAR modelirf_result: IRF computed on the FAVAR's augmented VAR system
Returns
ImpulseResponse{T} with N panel variables as the response dimension.
Example
favar = estimate_favar(X, [1, 5], 3, 2)
irf_aug = irf(favar, 20) # IRF in factor space (r + n_key vars)
irf_panel = favar_panel_irf(favar, irf_aug) # IRF for all N panel varsfavar_panel_irf(bfavar::BayesianFAVAR, irf_result::BayesianImpulseResponse) -> BayesianImpulseResponseMap Bayesian factor-space IRFs to all N panel variables using posterior mean loadings.
For each panel variable i and shock j: panelirf[h, i, j] = sumk Lambdamean[i, k] * irfresult.point_estimate[h, k, j]
Key variables use their direct VAR IRF responses.
Arguments
bfavar: Estimated Bayesian FAVAR modelirf_result: Bayesian IRF computed on the FAVAR's augmented VAR system
Returns
BayesianImpulseResponse{T} with N panel variables as the response dimension.
MacroEconometricModels.favar_panel_forecast — Function
favar_panel_forecast(favar::FAVARModel, fc::VARForecast) -> VARForecastMap factor-space forecasts to all N panel variables using the factor loadings.
Key variables use their direct VAR forecast; other variables are mapped through Lambda * F_forecast.
Arguments
favar: Estimated FAVAR modelfc: Forecast from the augmented VAR (viaforecast(favar, h))
Returns
VARForecast{T} with N panel variable forecasts.
Structural Dynamic Factor Models
MacroEconometricModels.estimate_structural_dfm — Function
estimate_structural_dfm(X, q; identification=:cholesky, p=1, H=40, sign_check=nothing, max_draws=1000) -> StructuralDFMEstimate a Structural DFM from raw panel data.
This is a one-step convenience wrapper that first estimates a GDFM via estimate_gdfm(X, q), then applies structural identification to the factor dynamics.
Arguments
X: Panel data matrix (T x N)q: Number of dynamic factors
Keyword Arguments
identification::Symbol=:cholesky: Identification method (:cholesky or :sign)p::Int=1: VAR lag order on factorsH::Int=40: IRF horizonsign_check::Union{Nothing,Function}=nothing: Sign restriction check function (required for :sign)max_draws::Int=1000: Maximum draws for sign restriction searchstandardize::Bool=true: Standardize data for GDFM estimationbandwidth::Int=0: GDFM kernel bandwidth (0 = automatic)kernel::Symbol=:bartlett: GDFM spectral kernel
Returns
StructuralDFM{T} with identified factor IRFs mapped to all N panel variables.
Example
using FFTW
X = randn(200, 50)
sdfm = estimate_structural_dfm(X, 3; identification=:cholesky, p=2, H=20)
irf_result = irf(sdfm, 20) # panel-wide structural IRFsReferences
- Forni, M., Giannone, D., Lippi, M., & Reichlin, L. (2009). Opening the Black Box: Structural Factor Models with Large Cross-Sections. Econometric Theory, 25(5), 1319-1347.
estimate_structural_dfm(gdfm::GeneralizedDynamicFactorModel; identification=:cholesky, p=1, H=40, sign_check=nothing, max_draws=1000) -> StructuralDFMEstimate a Structural DFM from an existing GDFM estimation.
Arguments
gdfm: Pre-estimated GDFM
Keyword Arguments
identification::Symbol=:cholesky: Identification method (:cholesky or :sign)p::Int=1: VAR lag order on factorsH::Int=40: IRF horizonsign_check::Union{Nothing,Function}=nothing: Sign restriction check function (required for :sign)max_draws::Int=1000: Maximum draws for sign restriction search
Returns
StructuralDFM{T} with identified factor IRFs mapped to all N panel variables.
MacroEconometricModels.sdfm_panel_irf — Function
sdfm_panel_irf(sdfm::StructuralDFM, H::Int) -> ImpulseResponse{T}Compute panel-wide structural IRFs by projecting factor-space IRFs to all N observable variables via the time-domain loading matrix.
Internally computes factor IRFs from the factor VAR using the stored identification matrix Q, then applies Λ * factor_irf at each horizon.
Arguments
sdfm: Estimated Structural DFMH: IRF horizon
Returns
ImpulseResponse{T} with dimensions (H, N, q) — N observable responses to q structural shocks.
sdfm_panel_irf(sdfm::StructuralDFM, irf_result::ImpulseResponse) -> ImpulseResponse{T}Project an existing factor-space ImpulseResponse to all N observable panel variables via the time-domain loading matrix.
Analogous to favar_panel_irf: takes factor-space IRFs (from the factor VAR with any identification) and maps them to observable space.
Arguments
sdfm: Estimated Structural DFM (provides loadings)irf_result: Factor-space IRF (H x q x q)
Returns
ImpulseResponse{T} with dimensions (H, N, q).
Panel Data Utilities
MacroEconometricModels.panel_lag — Function
panel_lag(pd::PanelData{T}, var::Union{String,Symbol}, k::Int=1) -> Vector{T}Compute within-group lag of variable var by k periods.
Returns a vector of length T_obs with NaN where the lag is unavailable (first k observations per group, or when there is a time gap).
Examples
pd = load_example(:ddcg)
lag1_y = panel_lag(pd, :y, 1) # L.y
lag4_y = panel_lag(pd, :y, 4) # L4.yMacroEconometricModels.panel_lead — Function
panel_lead(pd::PanelData{T}, var::Union{String,Symbol}, k::Int=1) -> Vector{T}Compute within-group lead of variable var by k periods. NaN where the lead is unavailable.
Examples
pd = load_example(:ddcg)
lead1_y = panel_lead(pd, :y, 1) # F.yMacroEconometricModels.panel_diff — Function
panel_diff(pd::PanelData{T}, var::Union{String,Symbol}) -> Vector{T}Compute within-group first difference: D.var = var_t - var_{t-1}. NaN at the first observation of each group or when there is a time gap.
Examples
pd = load_example(:ddcg)
d_dem = panel_diff(pd, :dem) # D.dem (switching indicator)MacroEconometricModels.add_panel_lag — Function
add_panel_lag(pd::PanelData{T}, var::Union{String,Symbol}, k::Int=1) -> PanelData{T}Return a new PanelData with a "lag{k}_{var}" column appended.
MacroEconometricModels.add_panel_lead — Function
add_panel_lead(pd::PanelData{T}, var::Union{String,Symbol}, k::Int=1) -> PanelData{T}Return a new PanelData with a "lead{k}_{var}" column appended.
MacroEconometricModels.add_panel_diff — Function
add_panel_diff(pd::PanelData{T}, var::Union{String,Symbol}) -> PanelData{T}Return a new PanelData with a "d_{var}" column appended.