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 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
+ [![PyPI version](https://img.shields.io/pypi/v/favar.svg)](https://pypi.org/project/favar/)
37
+ [![Python versions](https://img.shields.io/pypi/pyversions/favar.svg)](https://pypi.org/project/favar/)
38
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
39
+ [![Status](https://img.shields.io/badge/status-alpha-orange.svg)](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.