asycaus 1.0.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.
- asycaus-1.0.0/LICENSE +21 -0
- asycaus-1.0.0/MANIFEST.in +6 -0
- asycaus-1.0.0/PKG-INFO +305 -0
- asycaus-1.0.0/README.md +271 -0
- asycaus-1.0.0/asycaus/__init__.py +64 -0
- asycaus-1.0.0/asycaus/all_tests.py +160 -0
- asycaus-1.0.0/asycaus/dynamic.py +131 -0
- asycaus-1.0.0/asycaus/efficient.py +86 -0
- asycaus-1.0.0/asycaus/engine.py +486 -0
- asycaus-1.0.0/asycaus/fourier.py +94 -0
- asycaus-1.0.0/asycaus/plots.py +233 -0
- asycaus-1.0.0/asycaus/quantile.py +94 -0
- asycaus-1.0.0/asycaus/spectral.py +96 -0
- asycaus-1.0.0/asycaus/static.py +132 -0
- asycaus-1.0.0/asycaus/tables.py +311 -0
- asycaus-1.0.0/asycaus.egg-info/PKG-INFO +305 -0
- asycaus-1.0.0/asycaus.egg-info/SOURCES.txt +24 -0
- asycaus-1.0.0/asycaus.egg-info/dependency_links.txt +1 -0
- asycaus-1.0.0/asycaus.egg-info/requires.txt +10 -0
- asycaus-1.0.0/asycaus.egg-info/top_level.txt +1 -0
- asycaus-1.0.0/docs/SYNTAX.md +339 -0
- asycaus-1.0.0/examples/example_lutkepohl.py +55 -0
- asycaus-1.0.0/examples/example_simulation.py +59 -0
- asycaus-1.0.0/pyproject.toml +56 -0
- asycaus-1.0.0/setup.cfg +4 -0
- asycaus-1.0.0/tests/test_basic.py +81 -0
asycaus-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dr Merwan Roudane
|
|
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.
|
asycaus-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: asycaus
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Asymmetric Granger-causality suite for Python (Hatemi-J, Bahmani-Oskooee, Fang et al., Nazlioglu et al.)
|
|
5
|
+
Author-email: Dr Merwan Roudane <merwanroudane920@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/merwanroudane/asycaus
|
|
8
|
+
Project-URL: Source, https://github.com/merwanroudane/asycaus
|
|
9
|
+
Project-URL: Issues, https://github.com/merwanroudane/asycaus/issues
|
|
10
|
+
Keywords: granger causality,asymmetric causality,Hatemi-J,Toda-Yamamoto,Breitung-Candelon,spectral causality,quantile causality,Fourier causality,leverage bootstrap,time-varying causality,econometrics,time series
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=1.22
|
|
26
|
+
Requires-Dist: scipy>=1.8
|
|
27
|
+
Requires-Dist: pandas>=1.4
|
|
28
|
+
Requires-Dist: matplotlib>=3.5
|
|
29
|
+
Requires-Dist: rich>=12.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
32
|
+
Requires-Dist: black; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff; extra == "dev"
|
|
34
|
+
|
|
35
|
+
# asycaus — Asymmetric Granger-Causality Suite for Python
|
|
36
|
+
|
|
37
|
+
[](LICENSE)
|
|
38
|
+
[]()
|
|
39
|
+
[](https://github.com/merwanroudane/asycaus)
|
|
40
|
+
|
|
41
|
+
**Repository:** <https://github.com/merwanroudane/asycaus>
|
|
42
|
+
|
|
43
|
+
A complete Python implementation of asymmetric Granger-causality tests for
|
|
44
|
+
bivariate time series. The package is a faithful mirror of the companion
|
|
45
|
+
**Stata `asycaus`** library by the same author, with publication-quality
|
|
46
|
+
tables (powered by [`rich`](https://github.com/Textualize/rich)) and plots
|
|
47
|
+
(`matplotlib`).
|
|
48
|
+
|
|
49
|
+
> **Author:** Dr Merwan Roudane · <merwanroudane920@gmail.com>
|
|
50
|
+
> · [GitHub](https://github.com/merwanroudane/asycaus)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Methods implemented
|
|
55
|
+
|
|
56
|
+
| Function | Test | Reference |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `asycaus.static` | Static asymmetric causality with leverage bootstrap | Hatemi-J (2012); Hacker & Hatemi-J (2006, 2012) |
|
|
59
|
+
| `asycaus.dynamic` | Rolling / recursive time-varying asymmetric causality | Hatemi-J (2021) |
|
|
60
|
+
| `asycaus.fourier` | Fourier-augmented asymmetric Toda-Yamamoto | Nazlioglu, Gormus & Soytas (2016); Pata (2020) |
|
|
61
|
+
| `asycaus.spectral` | Frequency-domain BC test on Pos / Neg components | Bahmani-Oskooee, Chang & Ranjbar (2016); Breitung & Candelon (2006) |
|
|
62
|
+
| `asycaus.quantile` | Quantile asymmetric causality (+ optional Fourier detrending) | Fang, Wang, Shieh & Chung (2026) |
|
|
63
|
+
| `asycaus.efficient` | SUR-based joint Pos / Neg / Joint / Pos=Neg test | Hatemi-J (2024) |
|
|
64
|
+
| `asycaus.all_tests` | Full battery with unified summary table | this package |
|
|
65
|
+
| `asycaus.pos_neg_components` | Utility: build cumulative shock components | Granger & Yoon (2002) |
|
|
66
|
+
|
|
67
|
+
The default lag-selection criterion across the library is the
|
|
68
|
+
**Hatemi-J information criterion** (HJC; Hatemi-J 2003), with AIC, AICC,
|
|
69
|
+
SBC, HQC also available.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Once published to PyPI:
|
|
77
|
+
pip install asycaus
|
|
78
|
+
|
|
79
|
+
# Directly from GitHub:
|
|
80
|
+
pip install git+https://github.com/merwanroudane/asycaus.git
|
|
81
|
+
|
|
82
|
+
# Or from a local clone:
|
|
83
|
+
git clone https://github.com/merwanroudane/asycaus.git
|
|
84
|
+
pip install -e asycaus
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Dependencies** (installed automatically):
|
|
88
|
+
`numpy`, `scipy`, `pandas`, `matplotlib`, `rich`.
|
|
89
|
+
|
|
90
|
+
Python **≥ 3.9** is required.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Quick start
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import numpy as np
|
|
98
|
+
import asycaus
|
|
99
|
+
|
|
100
|
+
# An asymmetric DGP: positive shocks in x cause y, negative do not.
|
|
101
|
+
rng = np.random.default_rng(30540)
|
|
102
|
+
ex = rng.standard_normal(300)
|
|
103
|
+
ey = rng.standard_normal(300)
|
|
104
|
+
x = np.cumsum(ex)
|
|
105
|
+
y = np.zeros(300)
|
|
106
|
+
for t in range(1, 300):
|
|
107
|
+
y[t] = 0.5 * y[t - 1] + 0.7 * max(ex[t - 1], 0) + ey[t]
|
|
108
|
+
|
|
109
|
+
# --- 1. Static Hatemi-J (2012) ----------------------------------------
|
|
110
|
+
asycaus.static(y, x, shock="both", boot=300)
|
|
111
|
+
|
|
112
|
+
# --- 2. Dynamic Hatemi-J (2021) rolling window ------------------------
|
|
113
|
+
asycaus.dynamic(y, x, shock="pos", mode="rolling", boot=150)
|
|
114
|
+
|
|
115
|
+
# --- 3. Fourier (Nazlioglu et al. 2016) -------------------------------
|
|
116
|
+
asycaus.fourier(y, x, kmax=3, form="single")
|
|
117
|
+
|
|
118
|
+
# --- 4. Spectral (Bahmani-Oskooee et al. 2016) ------------------------
|
|
119
|
+
asycaus.spectral(y, x, nfreq=50)
|
|
120
|
+
|
|
121
|
+
# --- 5. Quantile (Fang et al. 2026), with Fourier detrending ----------
|
|
122
|
+
asycaus.quantile(y, x, quantiles=(0.1, 0.25, 0.5, 0.75, 0.9),
|
|
123
|
+
fourier=True, kmax=2)
|
|
124
|
+
|
|
125
|
+
# --- 6. Efficient SUR (Hatemi-J 2024) ---------------------------------
|
|
126
|
+
asycaus.efficient(y, x, max_lag=4)
|
|
127
|
+
|
|
128
|
+
# --- Everything in one call -------------------------------------------
|
|
129
|
+
asycaus.all_tests(y, x, max_lag=4, boot=300, skip_dynamic=True)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Every test prints a coloured, boxed table (via `rich`) and renders a
|
|
133
|
+
publication-quality plot (set `plot=False` to suppress; `show=False` to
|
|
134
|
+
suppress the table; both return a `Result` dataclass).
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Detailed function reference
|
|
139
|
+
|
|
140
|
+
### `asycaus.static(y, x, *, shock='both', max_lag=8, ic='hjc', intorder=1, boot=1000, seed=12345, lnform=False, show=True, plot=True)`
|
|
141
|
+
|
|
142
|
+
**Hatemi-J (2012) static asymmetric causality with leverage-adjusted bootstrap.**
|
|
143
|
+
|
|
144
|
+
- `y`, `x`: 1-D arrays of equal length (length T). H₀: *x* does **not** Granger-cause *y*.
|
|
145
|
+
- `shock`: `'pos'` | `'neg'` | `'both'`. The cumulative components to test.
|
|
146
|
+
- `max_lag`: integer, max VAR lag for the IC search.
|
|
147
|
+
- `ic`: `'aic'` | `'aicc'` | `'sbc'` | `'hqc'` | `'hjc'` (default).
|
|
148
|
+
- `intorder`: integer ≥ 0, Toda-Yamamoto augmentation lags (max integration order).
|
|
149
|
+
- `boot`: bootstrap replications.
|
|
150
|
+
- `seed`: RNG seed (`None` for non-reproducible).
|
|
151
|
+
- `lnform`: take `np.log()` of inputs before the decomposition.
|
|
152
|
+
- `show` / `plot`: print the table / render the bar plot.
|
|
153
|
+
|
|
154
|
+
Returns `StaticResult`:
|
|
155
|
+
- `.table` — `pandas.DataFrame` indexed by shock, columns `Wald`, `lag`, `dof`, `asy_p`, `cv10`, `cv5`, `cv1`, `decision_5pct`.
|
|
156
|
+
- `.depvar`, `.causvar`, `.ic`, `.boot`, `.sample_size`, `.intorder`.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### `asycaus.dynamic(y, x, *, shock='pos', mode='rolling', window=None, max_lag=4, ic='hjc', intorder=1, boot=200, seed=12345, lnform=False, show=True, plot=True, progress=True)`
|
|
161
|
+
|
|
162
|
+
**Hatemi-J (2021) time-varying asymmetric causality.**
|
|
163
|
+
|
|
164
|
+
- `mode`: `'rolling'` (fixed window, slides by 1) or `'recursive'` (anchored at observation 1, expanding).
|
|
165
|
+
- `window`: window size *S*; defaults to the Phillips-Shi-Yu (2015) lower bound
|
|
166
|
+
*S = ceil(T (0.01 + 1.8/√T))*.
|
|
167
|
+
- `progress`: print `subsample k/N` every 10 windows.
|
|
168
|
+
|
|
169
|
+
Returns `DynamicResult`:
|
|
170
|
+
- `.table` — DataFrame columns `sub_start`, `sub_end`, `lag`, `Wald`, `cv10`, `cv5`, `cv1`, `ratio_5pct`.
|
|
171
|
+
- `.mode`, `.window`, `.smin`, `.nsub`, `.shock`, `.ic`, `.boot`, `.intorder`.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### `asycaus.fourier(y, x, *, shock='both', kmax=5, form='single', max_lag=8, ic='hjc', intorder=1, lnform=False, show=True, plot=True)`
|
|
176
|
+
|
|
177
|
+
**Fourier-augmented asymmetric Toda-Yamamoto (Nazlioglu et al. 2016; Pata 2020).**
|
|
178
|
+
|
|
179
|
+
- `kmax`: maximum Fourier frequency. The function searches `k = 1..kmax` and selects the most informative *k*\*.
|
|
180
|
+
- `form`: `'single'` (sin/cos at frequency *k*) or `'cumulative'` (basis `k = 1..k_max`).
|
|
181
|
+
|
|
182
|
+
Returns `FourierResult` with `.table` indexed by shock, columns
|
|
183
|
+
`Wald`, `lag`, `k_opt`, `asy_p`, `sample`, `decision_5pct`.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### `asycaus.spectral(y, x, *, shock='both', nfreq=50, max_lag=8, ic='hjc', lnform=False, show=True, plot=True)`
|
|
188
|
+
|
|
189
|
+
**Asymmetric frequency-domain causality (Bahmani-Oskooee et al. 2016 — BC 2006 applied to Pos/Neg components).**
|
|
190
|
+
|
|
191
|
+
- `nfreq`: number of grid points in `ω ∈ (0, π]`.
|
|
192
|
+
|
|
193
|
+
Returns `SpectralResult` with:
|
|
194
|
+
- `.table` — full grid (`shock_id`, `shock`, `omega`, `Wald`, `cv10`, `cv5`, `cv1`, `lag`)
|
|
195
|
+
- `.summary` — per-shock count of rejections at 1%, 5%, 10%
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### `asycaus.quantile(y, x, *, shock='both', quantiles=(0.1,0.25,0.5,0.75,0.9), max_lag=4, ic='hjc', intorder=1, fourier=False, kmax=3, lnform=False, show=True, plot=True)`
|
|
200
|
+
|
|
201
|
+
**Quantile asymmetric causality (Fang, Wang, Shieh & Chung 2026).**
|
|
202
|
+
|
|
203
|
+
- `quantiles`: iterable of quantile probabilities in (0, 1).
|
|
204
|
+
- `fourier=True`: project out a cumulative Fourier basis (sin/cos with *k = 1..kmax*) before estimating the quantile causality.
|
|
205
|
+
|
|
206
|
+
Returns `QuantileResult` with `.table` columns
|
|
207
|
+
`shock_id`, `shock`, `tau`, `Wald`, `lag`, `asy_p`, `decision_5pct`.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
### `asycaus.efficient(y, x, *, max_lag=8, ic='hjc', intorder=1, lnform=False, show=True, plot=True)`
|
|
212
|
+
|
|
213
|
+
**Hatemi-J (2024) efficient asymmetric causality via SUR.**
|
|
214
|
+
|
|
215
|
+
Reports four hypotheses jointly:
|
|
216
|
+
|
|
217
|
+
1. No causality through **Pos** shocks
|
|
218
|
+
2. No causality through **Neg** shocks
|
|
219
|
+
3. **Joint** no causality
|
|
220
|
+
4. **Pos = Neg** causal coefficients — the formal asymmetry test
|
|
221
|
+
|
|
222
|
+
Returns `EfficientResult` with:
|
|
223
|
+
- `.table` indexed by hypothesis: `Wald`, `df`, `asy_p`, `decision_5pct`
|
|
224
|
+
- `.raw` dict with `W_pos`, `p_pos`, `W_neg`, `p_neg`, `W_joint`, `p_joint`, `W_diff`, `p_diff`, `dof`
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
### `asycaus.all_tests(y, x, *, max_lag=4, ic='hjc', intorder=1, boot=500, seed=12345, kmax=5, nfreq=50, quantiles=(0.1,0.25,0.5,0.75,0.9), window=None, lnform=False, skip_dynamic=False, skip_spectral=False, skip_quantile=False, show=True, plot=False)`
|
|
229
|
+
|
|
230
|
+
**Run the full battery and print a unified summary.**
|
|
231
|
+
|
|
232
|
+
Returns `AllResult` containing every individual result plus:
|
|
233
|
+
- `.summary` — DataFrame with rows of the form (Test, Shock, Statistic, p-value, Decision).
|
|
234
|
+
- `.plot()` — assembles a 6-panel dashboard.
|
|
235
|
+
|
|
236
|
+
`skip_dynamic`, `skip_spectral`, `skip_quantile` let you turn off the slowest tests.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### `asycaus.pos_neg_components(Y, positive=True)`
|
|
241
|
+
|
|
242
|
+
Utility: cumulative sum of positive (or negative) first differences of `Y` (T × K).
|
|
243
|
+
Returns a (T-1) × K matrix.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Output styling
|
|
248
|
+
|
|
249
|
+
Tables use `rich` for colour output if available, falling back to a clean
|
|
250
|
+
ASCII boxed format otherwise. Plots use matplotlib with a consistent
|
|
251
|
+
publication-quality theme (navy / orange / green / red).
|
|
252
|
+
|
|
253
|
+
Each `Result` dataclass exposes `.print()` and `.plot()` so you can re-render
|
|
254
|
+
without re-running the test:
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
r = asycaus.static(y, x, show=False, plot=False) # silent
|
|
258
|
+
r.print() # boxed table
|
|
259
|
+
fig = r.plot(save="static.png") # save the figure
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## References
|
|
265
|
+
|
|
266
|
+
- Bahmani-Oskooee, M., Chang, T., & Ranjbar, O. (2016). Asymmetric causality using frequency-domain and time-frequency-domain (wavelet) approaches. *Economic Modelling*, 56, 66–78.
|
|
267
|
+
- Breitung, J., & Candelon, B. (2006). Testing for short- and long-run causality: a frequency-domain approach. *Journal of Econometrics*, 132, 363–378.
|
|
268
|
+
- Enders, W., & Lee, J. (2012). The flexible Fourier form and Dickey-Fuller type unit root tests. *Economics Letters*, 117(1), 196–199.
|
|
269
|
+
- Fang, H., Wang, C.-H., Shieh, J. C. P., & Chung, C.-P. (2026). The asymmetric Granger causality between banking-sector and stock-market development and economic growth in quantiles considering Fourier. *Applied Economics*, 58(20), 3822–3838.
|
|
270
|
+
- Granger, C. W. J., & Yoon, G. (2002). Hidden cointegration. *UCSD Discussion Paper* 2002-02.
|
|
271
|
+
- Hacker, R. S., & Hatemi-J, A. (2006). Tests for causality between integrated variables using asymptotic and bootstrap distributions: theory and application. *Applied Economics*, 38(13), 1489–1500.
|
|
272
|
+
- Hacker, R. S., & Hatemi-J, A. (2012). A bootstrap test for causality with endogenous lag length choice: theory and application in finance. *Journal of Economic Studies*, 39(2), 144–160.
|
|
273
|
+
- Hatemi-J, A. (2003). A new method to choose optimal lag order in stable and unstable VAR models. *Applied Economics Letters*, 10(3), 135–137.
|
|
274
|
+
- Hatemi-J, A. (2012). Asymmetric causality tests with an application. *Empirical Economics*, 43, 447–456.
|
|
275
|
+
- Hatemi-J, A. (2021). Dynamic Asymmetric Causality Tests with an Application. *arXiv* 2106.07612.
|
|
276
|
+
- Hatemi-J, A. (2024). Efficient Asymmetric Causality Tests. *arXiv* 2408.03137.
|
|
277
|
+
- Koenker, R. (2005). *Quantile Regression*. Cambridge University Press.
|
|
278
|
+
- Nazlioglu, S., Gormus, N. A., & Soytas, U. (2016). Oil prices and real estate investment trusts (REITs): gradual-shift causality and volatility transmission analysis. *Energy Economics*, 60, 168–175.
|
|
279
|
+
- Pata, U. K. (2020). How is COVID-19 affecting environmental pollution in US cities? Evidence from asymmetric Fourier causality test. *Air Quality, Atmosphere & Health*, 13, 1149–1155.
|
|
280
|
+
- Phillips, P. C. B., Shi, S., & Yu, J. (2015). Testing for multiple bubbles: limit theory of real-time detectors. *International Economic Review*, 56(4), 1043–1078.
|
|
281
|
+
- Toda, H. Y., & Yamamoto, T. (1995). Statistical inference in vector autoregressions with possibly integrated processes. *Journal of Econometrics*, 66, 225–250.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Citation
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Roudane, M. (2026). asycaus: Asymmetric Granger-causality suite for Python.
|
|
289
|
+
Version 1.0.0. https://github.com/merwanroudane/asycaus
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT — see [LICENSE](LICENSE).
|
|
297
|
+
|
|
298
|
+
## Companion package (Stata)
|
|
299
|
+
|
|
300
|
+
The Stata twin of this library, also by the same author, is available on SSC:
|
|
301
|
+
|
|
302
|
+
```stata
|
|
303
|
+
ssc install asycaus
|
|
304
|
+
help asycaus
|
|
305
|
+
```
|
asycaus-1.0.0/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# asycaus — Asymmetric Granger-Causality Suite for Python
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[]()
|
|
5
|
+
[](https://github.com/merwanroudane/asycaus)
|
|
6
|
+
|
|
7
|
+
**Repository:** <https://github.com/merwanroudane/asycaus>
|
|
8
|
+
|
|
9
|
+
A complete Python implementation of asymmetric Granger-causality tests for
|
|
10
|
+
bivariate time series. The package is a faithful mirror of the companion
|
|
11
|
+
**Stata `asycaus`** library by the same author, with publication-quality
|
|
12
|
+
tables (powered by [`rich`](https://github.com/Textualize/rich)) and plots
|
|
13
|
+
(`matplotlib`).
|
|
14
|
+
|
|
15
|
+
> **Author:** Dr Merwan Roudane · <merwanroudane920@gmail.com>
|
|
16
|
+
> · [GitHub](https://github.com/merwanroudane/asycaus)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Methods implemented
|
|
21
|
+
|
|
22
|
+
| Function | Test | Reference |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `asycaus.static` | Static asymmetric causality with leverage bootstrap | Hatemi-J (2012); Hacker & Hatemi-J (2006, 2012) |
|
|
25
|
+
| `asycaus.dynamic` | Rolling / recursive time-varying asymmetric causality | Hatemi-J (2021) |
|
|
26
|
+
| `asycaus.fourier` | Fourier-augmented asymmetric Toda-Yamamoto | Nazlioglu, Gormus & Soytas (2016); Pata (2020) |
|
|
27
|
+
| `asycaus.spectral` | Frequency-domain BC test on Pos / Neg components | Bahmani-Oskooee, Chang & Ranjbar (2016); Breitung & Candelon (2006) |
|
|
28
|
+
| `asycaus.quantile` | Quantile asymmetric causality (+ optional Fourier detrending) | Fang, Wang, Shieh & Chung (2026) |
|
|
29
|
+
| `asycaus.efficient` | SUR-based joint Pos / Neg / Joint / Pos=Neg test | Hatemi-J (2024) |
|
|
30
|
+
| `asycaus.all_tests` | Full battery with unified summary table | this package |
|
|
31
|
+
| `asycaus.pos_neg_components` | Utility: build cumulative shock components | Granger & Yoon (2002) |
|
|
32
|
+
|
|
33
|
+
The default lag-selection criterion across the library is the
|
|
34
|
+
**Hatemi-J information criterion** (HJC; Hatemi-J 2003), with AIC, AICC,
|
|
35
|
+
SBC, HQC also available.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Once published to PyPI:
|
|
43
|
+
pip install asycaus
|
|
44
|
+
|
|
45
|
+
# Directly from GitHub:
|
|
46
|
+
pip install git+https://github.com/merwanroudane/asycaus.git
|
|
47
|
+
|
|
48
|
+
# Or from a local clone:
|
|
49
|
+
git clone https://github.com/merwanroudane/asycaus.git
|
|
50
|
+
pip install -e asycaus
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Dependencies** (installed automatically):
|
|
54
|
+
`numpy`, `scipy`, `pandas`, `matplotlib`, `rich`.
|
|
55
|
+
|
|
56
|
+
Python **≥ 3.9** is required.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
import numpy as np
|
|
64
|
+
import asycaus
|
|
65
|
+
|
|
66
|
+
# An asymmetric DGP: positive shocks in x cause y, negative do not.
|
|
67
|
+
rng = np.random.default_rng(30540)
|
|
68
|
+
ex = rng.standard_normal(300)
|
|
69
|
+
ey = rng.standard_normal(300)
|
|
70
|
+
x = np.cumsum(ex)
|
|
71
|
+
y = np.zeros(300)
|
|
72
|
+
for t in range(1, 300):
|
|
73
|
+
y[t] = 0.5 * y[t - 1] + 0.7 * max(ex[t - 1], 0) + ey[t]
|
|
74
|
+
|
|
75
|
+
# --- 1. Static Hatemi-J (2012) ----------------------------------------
|
|
76
|
+
asycaus.static(y, x, shock="both", boot=300)
|
|
77
|
+
|
|
78
|
+
# --- 2. Dynamic Hatemi-J (2021) rolling window ------------------------
|
|
79
|
+
asycaus.dynamic(y, x, shock="pos", mode="rolling", boot=150)
|
|
80
|
+
|
|
81
|
+
# --- 3. Fourier (Nazlioglu et al. 2016) -------------------------------
|
|
82
|
+
asycaus.fourier(y, x, kmax=3, form="single")
|
|
83
|
+
|
|
84
|
+
# --- 4. Spectral (Bahmani-Oskooee et al. 2016) ------------------------
|
|
85
|
+
asycaus.spectral(y, x, nfreq=50)
|
|
86
|
+
|
|
87
|
+
# --- 5. Quantile (Fang et al. 2026), with Fourier detrending ----------
|
|
88
|
+
asycaus.quantile(y, x, quantiles=(0.1, 0.25, 0.5, 0.75, 0.9),
|
|
89
|
+
fourier=True, kmax=2)
|
|
90
|
+
|
|
91
|
+
# --- 6. Efficient SUR (Hatemi-J 2024) ---------------------------------
|
|
92
|
+
asycaus.efficient(y, x, max_lag=4)
|
|
93
|
+
|
|
94
|
+
# --- Everything in one call -------------------------------------------
|
|
95
|
+
asycaus.all_tests(y, x, max_lag=4, boot=300, skip_dynamic=True)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Every test prints a coloured, boxed table (via `rich`) and renders a
|
|
99
|
+
publication-quality plot (set `plot=False` to suppress; `show=False` to
|
|
100
|
+
suppress the table; both return a `Result` dataclass).
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Detailed function reference
|
|
105
|
+
|
|
106
|
+
### `asycaus.static(y, x, *, shock='both', max_lag=8, ic='hjc', intorder=1, boot=1000, seed=12345, lnform=False, show=True, plot=True)`
|
|
107
|
+
|
|
108
|
+
**Hatemi-J (2012) static asymmetric causality with leverage-adjusted bootstrap.**
|
|
109
|
+
|
|
110
|
+
- `y`, `x`: 1-D arrays of equal length (length T). H₀: *x* does **not** Granger-cause *y*.
|
|
111
|
+
- `shock`: `'pos'` | `'neg'` | `'both'`. The cumulative components to test.
|
|
112
|
+
- `max_lag`: integer, max VAR lag for the IC search.
|
|
113
|
+
- `ic`: `'aic'` | `'aicc'` | `'sbc'` | `'hqc'` | `'hjc'` (default).
|
|
114
|
+
- `intorder`: integer ≥ 0, Toda-Yamamoto augmentation lags (max integration order).
|
|
115
|
+
- `boot`: bootstrap replications.
|
|
116
|
+
- `seed`: RNG seed (`None` for non-reproducible).
|
|
117
|
+
- `lnform`: take `np.log()` of inputs before the decomposition.
|
|
118
|
+
- `show` / `plot`: print the table / render the bar plot.
|
|
119
|
+
|
|
120
|
+
Returns `StaticResult`:
|
|
121
|
+
- `.table` — `pandas.DataFrame` indexed by shock, columns `Wald`, `lag`, `dof`, `asy_p`, `cv10`, `cv5`, `cv1`, `decision_5pct`.
|
|
122
|
+
- `.depvar`, `.causvar`, `.ic`, `.boot`, `.sample_size`, `.intorder`.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### `asycaus.dynamic(y, x, *, shock='pos', mode='rolling', window=None, max_lag=4, ic='hjc', intorder=1, boot=200, seed=12345, lnform=False, show=True, plot=True, progress=True)`
|
|
127
|
+
|
|
128
|
+
**Hatemi-J (2021) time-varying asymmetric causality.**
|
|
129
|
+
|
|
130
|
+
- `mode`: `'rolling'` (fixed window, slides by 1) or `'recursive'` (anchored at observation 1, expanding).
|
|
131
|
+
- `window`: window size *S*; defaults to the Phillips-Shi-Yu (2015) lower bound
|
|
132
|
+
*S = ceil(T (0.01 + 1.8/√T))*.
|
|
133
|
+
- `progress`: print `subsample k/N` every 10 windows.
|
|
134
|
+
|
|
135
|
+
Returns `DynamicResult`:
|
|
136
|
+
- `.table` — DataFrame columns `sub_start`, `sub_end`, `lag`, `Wald`, `cv10`, `cv5`, `cv1`, `ratio_5pct`.
|
|
137
|
+
- `.mode`, `.window`, `.smin`, `.nsub`, `.shock`, `.ic`, `.boot`, `.intorder`.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### `asycaus.fourier(y, x, *, shock='both', kmax=5, form='single', max_lag=8, ic='hjc', intorder=1, lnform=False, show=True, plot=True)`
|
|
142
|
+
|
|
143
|
+
**Fourier-augmented asymmetric Toda-Yamamoto (Nazlioglu et al. 2016; Pata 2020).**
|
|
144
|
+
|
|
145
|
+
- `kmax`: maximum Fourier frequency. The function searches `k = 1..kmax` and selects the most informative *k*\*.
|
|
146
|
+
- `form`: `'single'` (sin/cos at frequency *k*) or `'cumulative'` (basis `k = 1..k_max`).
|
|
147
|
+
|
|
148
|
+
Returns `FourierResult` with `.table` indexed by shock, columns
|
|
149
|
+
`Wald`, `lag`, `k_opt`, `asy_p`, `sample`, `decision_5pct`.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### `asycaus.spectral(y, x, *, shock='both', nfreq=50, max_lag=8, ic='hjc', lnform=False, show=True, plot=True)`
|
|
154
|
+
|
|
155
|
+
**Asymmetric frequency-domain causality (Bahmani-Oskooee et al. 2016 — BC 2006 applied to Pos/Neg components).**
|
|
156
|
+
|
|
157
|
+
- `nfreq`: number of grid points in `ω ∈ (0, π]`.
|
|
158
|
+
|
|
159
|
+
Returns `SpectralResult` with:
|
|
160
|
+
- `.table` — full grid (`shock_id`, `shock`, `omega`, `Wald`, `cv10`, `cv5`, `cv1`, `lag`)
|
|
161
|
+
- `.summary` — per-shock count of rejections at 1%, 5%, 10%
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### `asycaus.quantile(y, x, *, shock='both', quantiles=(0.1,0.25,0.5,0.75,0.9), max_lag=4, ic='hjc', intorder=1, fourier=False, kmax=3, lnform=False, show=True, plot=True)`
|
|
166
|
+
|
|
167
|
+
**Quantile asymmetric causality (Fang, Wang, Shieh & Chung 2026).**
|
|
168
|
+
|
|
169
|
+
- `quantiles`: iterable of quantile probabilities in (0, 1).
|
|
170
|
+
- `fourier=True`: project out a cumulative Fourier basis (sin/cos with *k = 1..kmax*) before estimating the quantile causality.
|
|
171
|
+
|
|
172
|
+
Returns `QuantileResult` with `.table` columns
|
|
173
|
+
`shock_id`, `shock`, `tau`, `Wald`, `lag`, `asy_p`, `decision_5pct`.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### `asycaus.efficient(y, x, *, max_lag=8, ic='hjc', intorder=1, lnform=False, show=True, plot=True)`
|
|
178
|
+
|
|
179
|
+
**Hatemi-J (2024) efficient asymmetric causality via SUR.**
|
|
180
|
+
|
|
181
|
+
Reports four hypotheses jointly:
|
|
182
|
+
|
|
183
|
+
1. No causality through **Pos** shocks
|
|
184
|
+
2. No causality through **Neg** shocks
|
|
185
|
+
3. **Joint** no causality
|
|
186
|
+
4. **Pos = Neg** causal coefficients — the formal asymmetry test
|
|
187
|
+
|
|
188
|
+
Returns `EfficientResult` with:
|
|
189
|
+
- `.table` indexed by hypothesis: `Wald`, `df`, `asy_p`, `decision_5pct`
|
|
190
|
+
- `.raw` dict with `W_pos`, `p_pos`, `W_neg`, `p_neg`, `W_joint`, `p_joint`, `W_diff`, `p_diff`, `dof`
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### `asycaus.all_tests(y, x, *, max_lag=4, ic='hjc', intorder=1, boot=500, seed=12345, kmax=5, nfreq=50, quantiles=(0.1,0.25,0.5,0.75,0.9), window=None, lnform=False, skip_dynamic=False, skip_spectral=False, skip_quantile=False, show=True, plot=False)`
|
|
195
|
+
|
|
196
|
+
**Run the full battery and print a unified summary.**
|
|
197
|
+
|
|
198
|
+
Returns `AllResult` containing every individual result plus:
|
|
199
|
+
- `.summary` — DataFrame with rows of the form (Test, Shock, Statistic, p-value, Decision).
|
|
200
|
+
- `.plot()` — assembles a 6-panel dashboard.
|
|
201
|
+
|
|
202
|
+
`skip_dynamic`, `skip_spectral`, `skip_quantile` let you turn off the slowest tests.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### `asycaus.pos_neg_components(Y, positive=True)`
|
|
207
|
+
|
|
208
|
+
Utility: cumulative sum of positive (or negative) first differences of `Y` (T × K).
|
|
209
|
+
Returns a (T-1) × K matrix.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Output styling
|
|
214
|
+
|
|
215
|
+
Tables use `rich` for colour output if available, falling back to a clean
|
|
216
|
+
ASCII boxed format otherwise. Plots use matplotlib with a consistent
|
|
217
|
+
publication-quality theme (navy / orange / green / red).
|
|
218
|
+
|
|
219
|
+
Each `Result` dataclass exposes `.print()` and `.plot()` so you can re-render
|
|
220
|
+
without re-running the test:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
r = asycaus.static(y, x, show=False, plot=False) # silent
|
|
224
|
+
r.print() # boxed table
|
|
225
|
+
fig = r.plot(save="static.png") # save the figure
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## References
|
|
231
|
+
|
|
232
|
+
- Bahmani-Oskooee, M., Chang, T., & Ranjbar, O. (2016). Asymmetric causality using frequency-domain and time-frequency-domain (wavelet) approaches. *Economic Modelling*, 56, 66–78.
|
|
233
|
+
- Breitung, J., & Candelon, B. (2006). Testing for short- and long-run causality: a frequency-domain approach. *Journal of Econometrics*, 132, 363–378.
|
|
234
|
+
- Enders, W., & Lee, J. (2012). The flexible Fourier form and Dickey-Fuller type unit root tests. *Economics Letters*, 117(1), 196–199.
|
|
235
|
+
- Fang, H., Wang, C.-H., Shieh, J. C. P., & Chung, C.-P. (2026). The asymmetric Granger causality between banking-sector and stock-market development and economic growth in quantiles considering Fourier. *Applied Economics*, 58(20), 3822–3838.
|
|
236
|
+
- Granger, C. W. J., & Yoon, G. (2002). Hidden cointegration. *UCSD Discussion Paper* 2002-02.
|
|
237
|
+
- Hacker, R. S., & Hatemi-J, A. (2006). Tests for causality between integrated variables using asymptotic and bootstrap distributions: theory and application. *Applied Economics*, 38(13), 1489–1500.
|
|
238
|
+
- Hacker, R. S., & Hatemi-J, A. (2012). A bootstrap test for causality with endogenous lag length choice: theory and application in finance. *Journal of Economic Studies*, 39(2), 144–160.
|
|
239
|
+
- Hatemi-J, A. (2003). A new method to choose optimal lag order in stable and unstable VAR models. *Applied Economics Letters*, 10(3), 135–137.
|
|
240
|
+
- Hatemi-J, A. (2012). Asymmetric causality tests with an application. *Empirical Economics*, 43, 447–456.
|
|
241
|
+
- Hatemi-J, A. (2021). Dynamic Asymmetric Causality Tests with an Application. *arXiv* 2106.07612.
|
|
242
|
+
- Hatemi-J, A. (2024). Efficient Asymmetric Causality Tests. *arXiv* 2408.03137.
|
|
243
|
+
- Koenker, R. (2005). *Quantile Regression*. Cambridge University Press.
|
|
244
|
+
- Nazlioglu, S., Gormus, N. A., & Soytas, U. (2016). Oil prices and real estate investment trusts (REITs): gradual-shift causality and volatility transmission analysis. *Energy Economics*, 60, 168–175.
|
|
245
|
+
- Pata, U. K. (2020). How is COVID-19 affecting environmental pollution in US cities? Evidence from asymmetric Fourier causality test. *Air Quality, Atmosphere & Health*, 13, 1149–1155.
|
|
246
|
+
- Phillips, P. C. B., Shi, S., & Yu, J. (2015). Testing for multiple bubbles: limit theory of real-time detectors. *International Economic Review*, 56(4), 1043–1078.
|
|
247
|
+
- Toda, H. Y., & Yamamoto, T. (1995). Statistical inference in vector autoregressions with possibly integrated processes. *Journal of Econometrics*, 66, 225–250.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Citation
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
Roudane, M. (2026). asycaus: Asymmetric Granger-causality suite for Python.
|
|
255
|
+
Version 1.0.0. https://github.com/merwanroudane/asycaus
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
MIT — see [LICENSE](LICENSE).
|
|
263
|
+
|
|
264
|
+
## Companion package (Stata)
|
|
265
|
+
|
|
266
|
+
The Stata twin of this library, also by the same author, is available on SSC:
|
|
267
|
+
|
|
268
|
+
```stata
|
|
269
|
+
ssc install asycaus
|
|
270
|
+
help asycaus
|
|
271
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
asycaus
|
|
3
|
+
=======
|
|
4
|
+
|
|
5
|
+
Asymmetric Granger-causality suite for Python. Python mirror of the Stata
|
|
6
|
+
package `asycaus` by the same author.
|
|
7
|
+
|
|
8
|
+
Quick start
|
|
9
|
+
-----------
|
|
10
|
+
|
|
11
|
+
>>> import numpy as np, asycaus
|
|
12
|
+
>>> rng = np.random.default_rng(0)
|
|
13
|
+
>>> x = np.cumsum(rng.standard_normal(300))
|
|
14
|
+
>>> y = np.r_[0, 0.5*x[:-1] + rng.standard_normal(299)]
|
|
15
|
+
>>> r = asycaus.static(y, x, shock="both", boot=200, plot=False)
|
|
16
|
+
|
|
17
|
+
Available tests
|
|
18
|
+
---------------
|
|
19
|
+
|
|
20
|
+
asycaus.static Hatemi-J (2012) static asymmetric (leverage bootstrap)
|
|
21
|
+
asycaus.dynamic Hatemi-J (2021) rolling / recursive
|
|
22
|
+
asycaus.fourier Nazlioglu et al. (2016) Fourier-augmented TY
|
|
23
|
+
asycaus.spectral Bahmani-Oskooee et al. (2016) BC frequency-domain
|
|
24
|
+
asycaus.quantile Fang et al. (2026) quantile asymmetric
|
|
25
|
+
asycaus.efficient Hatemi-J (2024) SUR (Pos / Neg / Joint / Pos=Neg)
|
|
26
|
+
asycaus.all_tests Run every test, return unified summary
|
|
27
|
+
|
|
28
|
+
Author : Dr Merwan Roudane <merwanroudane920@gmail.com>
|
|
29
|
+
GitHub : https://github.com/merwanroudane/asycaus
|
|
30
|
+
License: MIT
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
__version__ = version("asycaus")
|
|
37
|
+
except PackageNotFoundError:
|
|
38
|
+
__version__ = "1.0.0"
|
|
39
|
+
|
|
40
|
+
__author__ = "Dr Merwan Roudane"
|
|
41
|
+
__email__ = "merwanroudane920@gmail.com"
|
|
42
|
+
__license__ = "MIT"
|
|
43
|
+
__url__ = "https://github.com/merwanroudane/asycaus"
|
|
44
|
+
|
|
45
|
+
from . import engine
|
|
46
|
+
from . import tables
|
|
47
|
+
from . import plots
|
|
48
|
+
from .static import static, StaticResult
|
|
49
|
+
from .dynamic import dynamic, DynamicResult
|
|
50
|
+
from .fourier import fourier, FourierResult
|
|
51
|
+
from .spectral import spectral, SpectralResult
|
|
52
|
+
from .quantile import quantile, QuantileResult
|
|
53
|
+
from .efficient import efficient, EfficientResult
|
|
54
|
+
from .all_tests import all_tests, AllResult
|
|
55
|
+
from .engine import pos_neg_components
|
|
56
|
+
|
|
57
|
+
__all__ = [
|
|
58
|
+
"static", "dynamic", "fourier", "spectral", "quantile",
|
|
59
|
+
"efficient", "all_tests", "pos_neg_components",
|
|
60
|
+
"StaticResult", "DynamicResult", "FourierResult", "SpectralResult",
|
|
61
|
+
"QuantileResult", "EfficientResult", "AllResult",
|
|
62
|
+
"engine", "tables", "plots",
|
|
63
|
+
"__version__", "__author__", "__email__", "__license__", "__url__",
|
|
64
|
+
]
|