favar 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- favar-0.1.0/LICENSE +21 -0
- favar-0.1.0/PKG-INFO +631 -0
- favar-0.1.0/README.md +598 -0
- favar-0.1.0/pyproject.toml +46 -0
- favar-0.1.0/setup.cfg +4 -0
- favar-0.1.0/src/favar/__init__.py +8 -0
- favar-0.1.0/src/favar/factor.py +105 -0
- favar-0.1.0/src/favar/model.py +240 -0
- favar-0.1.0/src/favar/order_selection.py +71 -0
- favar-0.1.0/src/favar/results.py +332 -0
- favar-0.1.0/src/favar/summary.py +160 -0
- favar-0.1.0/src/favar.egg-info/PKG-INFO +631 -0
- favar-0.1.0/src/favar.egg-info/SOURCES.txt +15 -0
- favar-0.1.0/src/favar.egg-info/dependency_links.txt +1 -0
- favar-0.1.0/src/favar.egg-info/requires.txt +15 -0
- favar-0.1.0/src/favar.egg-info/top_level.txt +1 -0
- favar-0.1.0/tests/test_favar.py +158 -0
favar-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jonas Santos Siqueira
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
favar-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: favar
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Factor-Augmented Vector Autoregression (FAVAR) for empirical macroeconomic research
|
|
5
|
+
Author: Jonas Santos Siqueira
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Jonas-Santos-Siqueira/FAVAR
|
|
8
|
+
Project-URL: Repository, https://github.com/Jonas-Santos-Siqueira/FAVAR
|
|
9
|
+
Project-URL: Issues, https://github.com/Jonas-Santos-Siqueira/FAVAR/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: numpy>=1.22
|
|
21
|
+
Requires-Dist: pandas>=1.5
|
|
22
|
+
Requires-Dist: scipy>=1.9
|
|
23
|
+
Requires-Dist: statsmodels>=0.14
|
|
24
|
+
Provides-Extra: plot
|
|
25
|
+
Requires-Dist: matplotlib>=3.7; extra == "plot"
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# favar
|
|
35
|
+
|
|
36
|
+
[](https://pypi.org/project/favar/)
|
|
37
|
+
[](https://pypi.org/project/favar/)
|
|
38
|
+
[](LICENSE)
|
|
39
|
+
[](https://github.com/Jonas-Santos-Siqueira/FAVAR)
|
|
40
|
+
|
|
41
|
+
`favar` is a Python package for estimating **Factor-Augmented Vector
|
|
42
|
+
Autoregressive** models. It is designed for empirical macroeconomic research,
|
|
43
|
+
monetary policy analysis, forecasting, and impulse-response analysis with large
|
|
44
|
+
information panels.
|
|
45
|
+
|
|
46
|
+
The package implements the two-step FAVAR procedure of Bernanke, Boivin, and
|
|
47
|
+
Eliasz (2005). It extracts latent factors from a large panel, removes the
|
|
48
|
+
contemporaneous policy component from the estimated factors, estimates an
|
|
49
|
+
augmented VAR system, and projects impulse responses back to any observable
|
|
50
|
+
series in the information panel.
|
|
51
|
+
|
|
52
|
+
## Contents
|
|
53
|
+
|
|
54
|
+
- [Installation](#installation)
|
|
55
|
+
- [Key Features](#key-features)
|
|
56
|
+
- [Quick Start](#quick-start)
|
|
57
|
+
- [Model Overview](#model-overview)
|
|
58
|
+
- [Data Requirements](#data-requirements)
|
|
59
|
+
- [Data Preparation and Transformations](#data-preparation-and-transformations)
|
|
60
|
+
- [Slow-Moving and Fast-Moving Variables](#slow-moving-and-fast-moving-variables)
|
|
61
|
+
- [Estimation Procedure](#estimation-procedure)
|
|
62
|
+
- [Forecasting](#forecasting)
|
|
63
|
+
- [Impulse Response Functions](#impulse-response-functions)
|
|
64
|
+
- [Residual Autocorrelation Diagnostics](#residual-autocorrelation-diagnostics)
|
|
65
|
+
- [Example Summary Output](#example-summary-output)
|
|
66
|
+
- [Examples and Notebook](#examples-and-notebook)
|
|
67
|
+
- [Public API](#public-api)
|
|
68
|
+
- [References](#references)
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
Install the latest release from PyPI:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install favar
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For an editable development install from a local checkout:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install -e .
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For development and tests:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install -e ".[test]"
|
|
88
|
+
pytest
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Key Features
|
|
92
|
+
|
|
93
|
+
- Two-step FAVAR estimation following Bernanke, Boivin, and Eliasz (2005).
|
|
94
|
+
- Principal-component factor extraction from large information panels.
|
|
95
|
+
- Slow-moving variable adjustment for recursive monetary policy identification.
|
|
96
|
+
- Forecasts for observed variables with confidence intervals.
|
|
97
|
+
- Orthogonalized impulse response functions for the augmented system.
|
|
98
|
+
- Panel-projected impulse responses for any selected series in $X_t$.
|
|
99
|
+
- Lag-order selection table with AIC, BIC, FPE, and HQIC.
|
|
100
|
+
- Residual autocorrelation diagnostics with $2 / \sqrt{T}$ bounds.
|
|
101
|
+
- Clean pandas-based interface.
|
|
102
|
+
|
|
103
|
+
## Quick Start
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from favar import FAVAR
|
|
107
|
+
|
|
108
|
+
model = FAVAR(
|
|
109
|
+
X=X,
|
|
110
|
+
Y=Y,
|
|
111
|
+
policy_var="policy_rate",
|
|
112
|
+
k_factors=3,
|
|
113
|
+
slow_columns=slow_columns,
|
|
114
|
+
standardize=True,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
order_selection = model.select_order(maxlags=12)
|
|
118
|
+
print(order_selection.summary())
|
|
119
|
+
|
|
120
|
+
results = model.fit(lags=4)
|
|
121
|
+
print(results.summary())
|
|
122
|
+
|
|
123
|
+
forecast = results.forecast(steps=12, confidence_level=0.95)
|
|
124
|
+
irf_y = results.impulse_response(periods=48, impulse_size=0.25)
|
|
125
|
+
irf_x = results.panel_impulse_response(
|
|
126
|
+
periods=48,
|
|
127
|
+
columns=["ip_growth", "inflation_core"],
|
|
128
|
+
impulse_size=0.25,
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Model Overview
|
|
133
|
+
|
|
134
|
+
A FAVAR combines a large information panel $X_t$ with a smaller set of observed
|
|
135
|
+
variables $Y_t$ that enter the VAR directly.
|
|
136
|
+
|
|
137
|
+
- $X_t$ is a large panel of economic indicators with dimension $T \times N$.
|
|
138
|
+
- $Y_t$ is a smaller set of observed variables with dimension $T \times M$.
|
|
139
|
+
- $F_t$ is a low-dimensional vector of latent factors extracted from $X_t$.
|
|
140
|
+
- $R_t$ is the policy instrument, supplied through `policy_var`.
|
|
141
|
+
|
|
142
|
+
The estimated system is:
|
|
143
|
+
|
|
144
|
+
$$
|
|
145
|
+
\begin{aligned}
|
|
146
|
+
Z_t &= c + A_1 Z_{t-1} + \cdots + A_p Z_{t-p} + u_t, \\
|
|
147
|
+
X_t &= d + \Lambda F_t + \Gamma Y_t + e_t,
|
|
148
|
+
\end{aligned}
|
|
149
|
+
$$
|
|
150
|
+
|
|
151
|
+
where:
|
|
152
|
+
|
|
153
|
+
$$
|
|
154
|
+
Z_t =
|
|
155
|
+
\begin{bmatrix}
|
|
156
|
+
F_t \\
|
|
157
|
+
Y_t
|
|
158
|
+
\end{bmatrix}.
|
|
159
|
+
$$
|
|
160
|
+
|
|
161
|
+
The policy variable is ordered last in $Y_t$ for recursive identification.
|
|
162
|
+
|
|
163
|
+
## Data Requirements
|
|
164
|
+
|
|
165
|
+
Prepare two pandas `DataFrame` objects:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
X # large information panel, shape T x N
|
|
169
|
+
Y # observed VAR variables, shape T x M
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Both inputs must:
|
|
173
|
+
|
|
174
|
+
- have a compatible time index;
|
|
175
|
+
- be observed at the same frequency, such as monthly or quarterly;
|
|
176
|
+
- contain only numeric columns;
|
|
177
|
+
- contain no missing values after transformations;
|
|
178
|
+
- be aligned over the same sample period;
|
|
179
|
+
- include `policy_var` as a column of `Y`.
|
|
180
|
+
|
|
181
|
+
Example layout:
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
X
|
|
185
|
+
ip_growth employment_growth inflation_core credit_spread
|
|
186
|
+
2000-01 0.31 0.12 0.22 1.21
|
|
187
|
+
2000-02 0.28 0.10 0.19 1.18
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
Y
|
|
192
|
+
output_growth inflation policy_rate
|
|
193
|
+
2000-01 0.31 0.22 5.75
|
|
194
|
+
2000-02 0.28 0.19 5.80
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Data Preparation and Transformations
|
|
198
|
+
|
|
199
|
+
The package standardizes `X` internally when `standardize=True`, but it does
|
|
200
|
+
not decide the economic transformation of each raw series. Transformations
|
|
201
|
+
should be chosen before estimation.
|
|
202
|
+
|
|
203
|
+
Common transformations:
|
|
204
|
+
|
|
205
|
+
### Log growth
|
|
206
|
+
|
|
207
|
+
For real quantities such as production, employment, credit, or monetary
|
|
208
|
+
aggregates:
|
|
209
|
+
|
|
210
|
+
$$
|
|
211
|
+
\Delta \log(x_t) = 100 \left[\log(x_t) - \log(x_{t-1})\right].
|
|
212
|
+
$$
|
|
213
|
+
|
|
214
|
+
### Inflation
|
|
215
|
+
|
|
216
|
+
For price indexes:
|
|
217
|
+
|
|
218
|
+
$$
|
|
219
|
+
\pi_t = 100 \left[\log(P_t) - \log(P_{t-1})\right].
|
|
220
|
+
$$
|
|
221
|
+
|
|
222
|
+
### Interest rates and spreads
|
|
223
|
+
|
|
224
|
+
Interest rates, spreads, and percentages are often used in levels:
|
|
225
|
+
|
|
226
|
+
$$
|
|
227
|
+
r_t = R_t.
|
|
228
|
+
$$
|
|
229
|
+
|
|
230
|
+
They can also be differenced when the empirical design calls for changes:
|
|
231
|
+
|
|
232
|
+
$$
|
|
233
|
+
\Delta r_t = r_t - r_{t-1}.
|
|
234
|
+
$$
|
|
235
|
+
|
|
236
|
+
### Practical preprocessing checklist
|
|
237
|
+
|
|
238
|
+
Before fitting the model:
|
|
239
|
+
|
|
240
|
+
- seasonally adjust series when appropriate;
|
|
241
|
+
- apply logs before differencing strictly positive level series;
|
|
242
|
+
- avoid mixing levels and growth rates without an economic reason;
|
|
243
|
+
- document outlier treatment and sample restrictions;
|
|
244
|
+
- call `dropna()` after transformations;
|
|
245
|
+
- verify that `X.index.equals(Y.index)` is `True`.
|
|
246
|
+
|
|
247
|
+
Example:
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
import numpy as np
|
|
251
|
+
import pandas as pd
|
|
252
|
+
|
|
253
|
+
raw = pd.read_csv("macro_panel.csv", parse_dates=["date"]).set_index("date")
|
|
254
|
+
|
|
255
|
+
X = pd.DataFrame(index=raw.index)
|
|
256
|
+
X["ip_growth"] = 100 * np.log(raw["industrial_production"]).diff()
|
|
257
|
+
X["employment_growth"] = 100 * np.log(raw["employment"]).diff()
|
|
258
|
+
X["inflation_core"] = 100 * np.log(raw["core_price_index"]).diff()
|
|
259
|
+
X["credit_spread"] = raw["credit_spread"]
|
|
260
|
+
|
|
261
|
+
Y = pd.DataFrame(index=raw.index)
|
|
262
|
+
Y["output_growth"] = X["ip_growth"]
|
|
263
|
+
Y["inflation"] = X["inflation_core"]
|
|
264
|
+
Y["policy_rate"] = raw["policy_rate"]
|
|
265
|
+
|
|
266
|
+
data = pd.concat([X, Y], axis=1).dropna()
|
|
267
|
+
X = data[X.columns]
|
|
268
|
+
Y = data[Y.columns]
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Slow-Moving and Fast-Moving Variables
|
|
272
|
+
|
|
273
|
+
For monetary policy applications, the information panel is divided into:
|
|
274
|
+
|
|
275
|
+
- **slow-moving variables**: variables assumed not to react contemporaneously to
|
|
276
|
+
the policy shock within the period, such as output, employment, consumption,
|
|
277
|
+
and some prices;
|
|
278
|
+
- **fast-moving variables**: variables allowed to react within the period, such
|
|
279
|
+
as interest rates, spreads, asset prices, and financial indicators.
|
|
280
|
+
|
|
281
|
+
Pass the slow-moving columns through `slow_columns`:
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
slow_columns = [
|
|
285
|
+
"ip_growth",
|
|
286
|
+
"employment_growth",
|
|
287
|
+
"inflation_core",
|
|
288
|
+
]
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
If `slow_columns=None`, all columns in `X` are treated as slow-moving. This is
|
|
292
|
+
allowed, but explicit classification is recommended for monetary policy work.
|
|
293
|
+
|
|
294
|
+
## Estimation Procedure
|
|
295
|
+
|
|
296
|
+
Let $X^s$ denote the standardized information panel:
|
|
297
|
+
|
|
298
|
+
$$
|
|
299
|
+
X^s_{tj} = \frac{X_{tj} - \bar{X}_j}{s_j}.
|
|
300
|
+
$$
|
|
301
|
+
|
|
302
|
+
The implemented two-step estimator proceeds as follows.
|
|
303
|
+
|
|
304
|
+
### 1. Principal components from the full panel
|
|
305
|
+
|
|
306
|
+
Estimate $K$ principal components from $X^s$:
|
|
307
|
+
|
|
308
|
+
$$
|
|
309
|
+
\widehat{C}_t = \widehat{C}(F_t, Y_t).
|
|
310
|
+
$$
|
|
311
|
+
|
|
312
|
+
These components estimate the common space spanned by both latent factors and
|
|
313
|
+
observed variables.
|
|
314
|
+
|
|
315
|
+
### 2. Principal components from slow-moving variables
|
|
316
|
+
|
|
317
|
+
Estimate $K$ principal components from the slow-moving subset of the panel:
|
|
318
|
+
|
|
319
|
+
$$
|
|
320
|
+
\widehat{C}^{*}_t = \widehat{C}^{*}(F_t).
|
|
321
|
+
$$
|
|
322
|
+
|
|
323
|
+
These components are used to isolate the latent factor space from the
|
|
324
|
+
contemporaneous policy instrument.
|
|
325
|
+
|
|
326
|
+
### 3. Remove the contemporaneous policy component
|
|
327
|
+
|
|
328
|
+
Regress the full-panel principal components on a constant, the policy
|
|
329
|
+
instrument, and the slow-moving principal components:
|
|
330
|
+
|
|
331
|
+
$$
|
|
332
|
+
\widehat{C}_t
|
|
333
|
+
= a + b_R R_t + B_S \widehat{C}^{*}_t + v_t.
|
|
334
|
+
$$
|
|
335
|
+
|
|
336
|
+
The cleaned factor estimate is:
|
|
337
|
+
|
|
338
|
+
$$
|
|
339
|
+
\widehat{F}_t = \widehat{C}_t - \widehat{b}_R R_t.
|
|
340
|
+
$$
|
|
341
|
+
|
|
342
|
+
### 4. Estimate the augmented VAR
|
|
343
|
+
|
|
344
|
+
Stack the cleaned factors and observed variables:
|
|
345
|
+
|
|
346
|
+
$$
|
|
347
|
+
\widehat{Z}_t =
|
|
348
|
+
\begin{bmatrix}
|
|
349
|
+
\widehat{F}_t \\
|
|
350
|
+
Y_t
|
|
351
|
+
\end{bmatrix}.
|
|
352
|
+
$$
|
|
353
|
+
|
|
354
|
+
Estimate:
|
|
355
|
+
|
|
356
|
+
$$
|
|
357
|
+
\widehat{Z}_t
|
|
358
|
+
= c + A_1 \widehat{Z}_{t-1}
|
|
359
|
+
+ \cdots
|
|
360
|
+
+ A_p \widehat{Z}_{t-p}
|
|
361
|
+
+ u_t.
|
|
362
|
+
$$
|
|
363
|
+
|
|
364
|
+
### 5. Estimate the measurement equation
|
|
365
|
+
|
|
366
|
+
Estimate the relationship between the standardized information panel and the
|
|
367
|
+
augmented state:
|
|
368
|
+
|
|
369
|
+
$$
|
|
370
|
+
X^s_t = d + \Theta \widehat{Z}_t + e_t.
|
|
371
|
+
$$
|
|
372
|
+
|
|
373
|
+
This measurement equation allows responses from the FAVAR system to be mapped
|
|
374
|
+
back to each series in $X$:
|
|
375
|
+
|
|
376
|
+
$$
|
|
377
|
+
\operatorname{IRF}_{X}(h)
|
|
378
|
+
= \operatorname{IRF}_{Z}(h)\widehat{\Theta}.
|
|
379
|
+
$$
|
|
380
|
+
|
|
381
|
+
When `scale="original"`, projected panel responses are multiplied by the
|
|
382
|
+
stored standard deviation of each original `X` column.
|
|
383
|
+
|
|
384
|
+
## Basic Usage
|
|
385
|
+
|
|
386
|
+
```python
|
|
387
|
+
from favar import FAVAR
|
|
388
|
+
|
|
389
|
+
model = FAVAR(
|
|
390
|
+
X=X,
|
|
391
|
+
Y=Y,
|
|
392
|
+
policy_var="policy_rate",
|
|
393
|
+
k_factors=3,
|
|
394
|
+
slow_columns=slow_columns,
|
|
395
|
+
standardize=True,
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
results = model.fit(lags=13)
|
|
399
|
+
print(results.summary())
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Main arguments:
|
|
403
|
+
|
|
404
|
+
- `X`: large information panel.
|
|
405
|
+
- `Y`: observed variables included directly in the FAVAR system.
|
|
406
|
+
- `policy_var`: policy instrument column in `Y`.
|
|
407
|
+
- `k_factors`: number of latent factors.
|
|
408
|
+
- `slow_columns`: slow-moving columns from `X`.
|
|
409
|
+
- `standardize`: whether to standardize `X` before factor extraction.
|
|
410
|
+
- `lags`: fixed lag order for the augmented VAR.
|
|
411
|
+
|
|
412
|
+
Lag order can also be selected by an information criterion:
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
order_selection = model.select_order(maxlags=12)
|
|
416
|
+
print(order_selection.summary())
|
|
417
|
+
|
|
418
|
+
results = model.fit(select_order="aic", maxlags=12)
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Accepted criteria are `"aic"`, `"bic"`, `"hqic"`, and `"fpe"`.
|
|
422
|
+
|
|
423
|
+
Compact order-selection example:
|
|
424
|
+
|
|
425
|
+
```text
|
|
426
|
+
FAVAR Lag Order Selection (* highlights the minimums)
|
|
427
|
+
==================================
|
|
428
|
+
AIC BIC FPE HQIC
|
|
429
|
+
----------------------------------
|
|
430
|
+
0 -1.262 -1.208 0.2832 -1.240
|
|
431
|
+
1 -3.985* -3.769* 0.01859* -3.897*
|
|
432
|
+
2 -3.979 -3.601 0.01870 -3.826
|
|
433
|
+
3 -3.927 -3.386 0.01971 -3.708
|
|
434
|
+
4 -3.881 -3.178 0.02066 -3.596
|
|
435
|
+
----------------------------------
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Forecasting
|
|
439
|
+
|
|
440
|
+
Use `forecast()` to forecast the observed variables in `Y`:
|
|
441
|
+
|
|
442
|
+
```python
|
|
443
|
+
forecast = results.forecast(steps=12, confidence_level=0.95)
|
|
444
|
+
print(forecast.head())
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
For each variable in `Y`, the output includes:
|
|
448
|
+
|
|
449
|
+
- point forecast;
|
|
450
|
+
- lower confidence bound;
|
|
451
|
+
- upper confidence bound.
|
|
452
|
+
|
|
453
|
+
Example column names:
|
|
454
|
+
|
|
455
|
+
```text
|
|
456
|
+
policy_rate policy_rate_lower policy_rate_upper
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## Impulse Response Functions
|
|
460
|
+
|
|
461
|
+
Use `impulse_response()` for responses of the augmented FAVAR system.
|
|
462
|
+
|
|
463
|
+
```python
|
|
464
|
+
irf_system = results.impulse_response(
|
|
465
|
+
periods=48,
|
|
466
|
+
shock="policy_rate",
|
|
467
|
+
impulse_size=0.25,
|
|
468
|
+
include_factors=False,
|
|
469
|
+
)
|
|
470
|
+
print(irf_system.head())
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
`impulse_size=0.25` rescales the shock so that the impact response of the
|
|
474
|
+
policy variable is `0.25`. If the policy rate is measured in percentage
|
|
475
|
+
points, this corresponds to 25 basis points.
|
|
476
|
+
|
|
477
|
+
Use `panel_impulse_response()` to project responses back to selected series in
|
|
478
|
+
the information panel:
|
|
479
|
+
|
|
480
|
+
```python
|
|
481
|
+
irf_panel = results.panel_impulse_response(
|
|
482
|
+
periods=48,
|
|
483
|
+
shock="policy_rate",
|
|
484
|
+
columns=["ip_growth", "inflation_core", "credit_spread"],
|
|
485
|
+
scale="original",
|
|
486
|
+
impulse_size=0.25,
|
|
487
|
+
)
|
|
488
|
+
print(irf_panel.head())
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Use:
|
|
492
|
+
|
|
493
|
+
- `scale="original"` for projected responses in the transformed units supplied
|
|
494
|
+
by the user;
|
|
495
|
+
- `scale="std"` for responses in standardized panel units.
|
|
496
|
+
|
|
497
|
+
## Residual Autocorrelation Diagnostics
|
|
498
|
+
|
|
499
|
+
Use `plot_acorr()` to inspect residual autocorrelations and cross-correlations
|
|
500
|
+
of the augmented FAVAR system:
|
|
501
|
+
|
|
502
|
+
```python
|
|
503
|
+
fig = results.plot_acorr(nlags=10)
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
The figure contains one panel for each pair of variables in the augmented
|
|
507
|
+
system. The dashed bands are $2 / \sqrt{T}$ bounds.
|
|
508
|
+
|
|
509
|
+
## Example Summary Output
|
|
510
|
+
|
|
511
|
+
`results.summary()` returns a text summary with overall fit statistics,
|
|
512
|
+
equation-by-equation coefficients, residual correlations, and FAVAR-specific
|
|
513
|
+
metadata.
|
|
514
|
+
|
|
515
|
+
Compact example:
|
|
516
|
+
|
|
517
|
+
```text
|
|
518
|
+
Summary of FAVAR Regression Results
|
|
519
|
+
======================================
|
|
520
|
+
Model: FAVAR
|
|
521
|
+
Estimator: Two-step PCA
|
|
522
|
+
VAR method: OLS
|
|
523
|
+
Date: Sun, 28, Jun, 2026
|
|
524
|
+
Time: 21:14:27
|
|
525
|
+
--------------------------------------------------------------------
|
|
526
|
+
No. of Equations: 3 BIC: -3.59224
|
|
527
|
+
Nobs: 178 HQIC: -3.81539
|
|
528
|
+
Log likelihood: -383.59539 FPE: 0.01892
|
|
529
|
+
AIC: -3.96762 Det(Omega_mle): 0.01685
|
|
530
|
+
--------------------------------------------------------------------
|
|
531
|
+
FAVAR Model Information
|
|
532
|
+
====================================================================
|
|
533
|
+
No. of factors: 2
|
|
534
|
+
No. of X variables: 40
|
|
535
|
+
No. of observed Y variables: 1
|
|
536
|
+
No. of slow-moving variables: 20
|
|
537
|
+
Policy variable: FFR
|
|
538
|
+
Policy position: 3
|
|
539
|
+
Lag order: 2
|
|
540
|
+
Standardized X: True
|
|
541
|
+
PC variance shares: 0.579, 0.248
|
|
542
|
+
--------------------------------------------------------------------
|
|
543
|
+
Identification: recursive policy shock with the policy variable ordered last.
|
|
544
|
+
Results for equation F1
|
|
545
|
+
============================================================================
|
|
546
|
+
coefficient std. error t-stat prob
|
|
547
|
+
----------------------------------------------------------------------------
|
|
548
|
+
const 0.024340 0.040805 0.596496 0.551
|
|
549
|
+
L1.F1 0.699803 0.078694 8.892735 0.000
|
|
550
|
+
L1.F2 0.055353 0.068085 0.813003 0.416
|
|
551
|
+
L1.FFR -0.001386 0.028840 -0.048049 0.962
|
|
552
|
+
...
|
|
553
|
+
|
|
554
|
+
Correlation matrix of residuals
|
|
555
|
+
F1 F2 FFR
|
|
556
|
+
F1 1.000000 -0.266766 -0.145655
|
|
557
|
+
F2 -0.266766 1.000000 0.674814
|
|
558
|
+
FFR -0.145655 0.674814 1.000000
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
## Examples and Notebook
|
|
562
|
+
|
|
563
|
+
Run the self-contained script:
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
python examples/synthetic_demo.py
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Open the walkthrough notebook:
|
|
570
|
+
|
|
571
|
+
```text
|
|
572
|
+
notebooks/favar_synthetic_walkthrough.ipynb
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
The notebook demonstrates:
|
|
576
|
+
|
|
577
|
+
1. package import and installation check;
|
|
578
|
+
2. synthetic macroeconomic data generation;
|
|
579
|
+
3. preprocessing and transformations;
|
|
580
|
+
4. construction of `X`, `Y`, and `slow_columns`;
|
|
581
|
+
5. FAVAR estimation;
|
|
582
|
+
6. forecasts with confidence intervals;
|
|
583
|
+
7. impulse response functions;
|
|
584
|
+
8. panel-projected impulse responses.
|
|
585
|
+
|
|
586
|
+
## Public API
|
|
587
|
+
|
|
588
|
+
```python
|
|
589
|
+
from favar import FAVAR
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Main methods:
|
|
593
|
+
|
|
594
|
+
- `FAVAR(...).fit(...)`: estimate the model.
|
|
595
|
+
- `results.summary()`: print the estimation summary.
|
|
596
|
+
- `model.select_order(maxlags=12)`: compare lag orders by information criteria.
|
|
597
|
+
- `results.forecast(steps, confidence_level=0.95)`: forecast observed
|
|
598
|
+
variables.
|
|
599
|
+
- `results.impulse_response(periods, impulse_size=None)`: compute system IRFs.
|
|
600
|
+
- `results.panel_impulse_response(periods, columns=None)`: compute IRFs
|
|
601
|
+
projected to the information panel.
|
|
602
|
+
- `results.plot_acorr(nlags=10)`: plot residual autocorrelations and
|
|
603
|
+
cross-correlations.
|
|
604
|
+
- `results.is_stable()`: check dynamic stability of the augmented VAR.
|
|
605
|
+
|
|
606
|
+
## Final Checklist Before Estimation
|
|
607
|
+
|
|
608
|
+
- `X` and `Y` have the same time index.
|
|
609
|
+
- No missing values remain after transformations.
|
|
610
|
+
- All columns in `X` and `Y` are numeric.
|
|
611
|
+
- `policy_var` is a column of `Y`.
|
|
612
|
+
- Every item in `slow_columns` is a column of `X`.
|
|
613
|
+
- `k_factors <= min(T, N)`.
|
|
614
|
+
- The lag order is feasible for the available sample size.
|
|
615
|
+
- Transformations are economically justified and documented.
|
|
616
|
+
|
|
617
|
+
## References
|
|
618
|
+
|
|
619
|
+
Bernanke, B. S., Boivin, J., & Eliasz, P. (2005). Measuring the Effects of
|
|
620
|
+
Monetary Policy: A Factor-Augmented Vector Autoregressive (FAVAR) Approach.
|
|
621
|
+
Quarterly Journal of Economics.
|
|
622
|
+
|
|
623
|
+
Lutkepohl, H. (2005). New Introduction to Multiple Time Series Analysis.
|
|
624
|
+
Springer.
|
|
625
|
+
|
|
626
|
+
Seabold, S., & Perktold, J. (2010). statsmodels: Econometric and Statistical
|
|
627
|
+
Modeling with Python. Proceedings of the 9th Python in Science Conference.
|
|
628
|
+
|
|
629
|
+
## License
|
|
630
|
+
|
|
631
|
+
MIT.
|