Skip to content

Commit 47b7fe3

Browse files
committed
More work and tests
1 parent cc62df7 commit 47b7fe3

File tree

11 files changed

+214
-67
lines changed

11 files changed

+214
-67
lines changed

arch/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
pytest_plugins = [
44
"arch.tests.unitroot.cointegration_data",
5+
"arch.tests.covariance.covariance_data",
56
]
67

78

arch/covariance/kernel.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ class CovarianceEstimator(ABC):
189189
def __init__(
190190
self,
191191
x: ArrayLike,
192+
*,
192193
bandwidth: Optional[float] = None,
193194
df_adjust: int = 0,
194195
center: bool = True,

arch/covariance/var.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class PreWhitenRecoloredCovariance(CovarianceEstimator):
3838
df_adjust : int, default 0
3939
center : bool, default True
4040
weights : array_like, default None
41+
force_int: bool, default False
4142
4243
See Also
4344
--------
@@ -52,6 +53,7 @@ class PreWhitenRecoloredCovariance(CovarianceEstimator):
5253
def __init__(
5354
self,
5455
x: ArrayLike,
56+
*,
5557
lags: Optional[int] = None,
5658
method: str = "aic",
5759
diagonal: bool = True,
@@ -62,9 +64,15 @@ def __init__(
6264
df_adjust: int = 0,
6365
center: bool = True,
6466
weights: Optional[ArrayLike] = None,
67+
force_int: bool = False,
6568
) -> None:
6669
super().__init__(
67-
x, bandwidth=bandwidth, df_adjust=df_adjust, center=center, weights=weights
70+
x,
71+
bandwidth=bandwidth,
72+
df_adjust=df_adjust,
73+
center=center,
74+
weights=weights,
75+
force_int=force_int,
6876
)
6977
self._kernel_name = kernel
7078
self._lags = 0
@@ -294,7 +302,12 @@ def cov(self) -> CovarianceEstimate:
294302
resids = var_mod.resids
295303
nobs, nvar = resids.shape
296304
self._kernel_instance = self._kernel(
297-
resids, self._bandwidth, 0, False, self._x_weights, self._force_int
305+
resids,
306+
bandwidth=self._bandwidth,
307+
df_adjust=0,
308+
center=False,
309+
weights=self._x_weights,
310+
force_int=self._force_int,
298311
)
299312
kern_cov = self._kernel_instance.cov
300313
short_run = kern_cov.short_run
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from itertools import product
2+
3+
import numpy as np
4+
import pandas as pd
5+
import pytest
6+
7+
DATA_PARAMS = list(product([1, 3], [True, False], [0])) # , 1, 3]))
8+
DATA_IDS = [f"dim: {d}, pandas: {p}, order: {o}" for d, p, o in DATA_PARAMS]
9+
10+
11+
@pytest.fixture(scope="module", params=DATA_PARAMS, ids=DATA_IDS)
12+
def covariance_data(request):
13+
dim, pandas, order = request.param
14+
rs = np.random.RandomState([839084, 3823810, 982103, 829108])
15+
burn = 100
16+
shape = (burn + 500,)
17+
if dim > 1:
18+
shape += (3,)
19+
rvs = rs.standard_normal(shape)
20+
phi = np.zeros((order, dim, dim))
21+
if order > 0:
22+
phi[0] = np.eye(dim) * 0.4 + 0.1
23+
for i in range(1, order):
24+
phi[i] = 0.3 / (i + 1) * np.eye(dim)
25+
for i in range(order, burn + 500):
26+
for j in range(order):
27+
if dim == 1:
28+
rvs[i] += np.squeeze(phi[j] * rvs[i - j - 1])
29+
else:
30+
rvs[i] += phi[j] @ rvs[i - j - 1]
31+
if order > 1:
32+
p = np.eye(dim * order, dim * order, -dim)
33+
for j in range(order):
34+
p[:dim, j * dim : (j + 1) * dim] = phi[j]
35+
v, _ = np.linalg.eig(p)
36+
assert np.max(np.abs(v)) < 1
37+
rvs = rvs[burn:]
38+
if pandas and dim == 1:
39+
return pd.Series(rvs, name="x")
40+
elif pandas:
41+
df = pd.DataFrame(rvs, columns=[f"x{i}" for i in range(dim)])
42+
df.to_csv("cov-data.csv")
43+
return df
44+
45+
return rvs

arch/tests/covariance/test_var.py

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from itertools import product
21
from typing import Optional, Tuple
32

43
import numpy as np
@@ -9,8 +8,6 @@
98
from arch.covariance.var import PreWhitenRecoloredCovariance
109
from arch.typing import NDArray
1110

12-
DATA_PARAMS = list(product([1, 3], [True, False], [0])) # , 1, 3]))
13-
DATA_IDS = [f"dim: {d}, pandas: {p}, order: {o}" for d, p, o in DATA_PARAMS]
1411
KERNELS = [
1512
"Bartlett",
1613
"Parzen",
@@ -32,40 +29,6 @@ def kernel(request):
3229
return request.param
3330

3431

35-
@pytest.fixture(scope="module", params=DATA_PARAMS, ids=DATA_IDS)
36-
def data(request):
37-
dim, pandas, order = request.param
38-
rs = np.random.RandomState([839084, 3823810, 982103, 829108])
39-
burn = 100
40-
shape = (burn + 500,)
41-
if dim > 1:
42-
shape += (3,)
43-
rvs = rs.standard_normal(shape)
44-
phi = np.zeros((order, dim, dim))
45-
if order > 0:
46-
phi[0] = np.eye(dim) * 0.4 + 0.1
47-
for i in range(1, order):
48-
phi[i] = 0.3 / (i + 1) * np.eye(dim)
49-
for i in range(order, burn + 500):
50-
for j in range(order):
51-
if dim == 1:
52-
rvs[i] += np.squeeze(phi[j] * rvs[i - j - 1])
53-
else:
54-
rvs[i] += phi[j] @ rvs[i - j - 1]
55-
if order > 1:
56-
p = np.eye(dim * order, dim * order, -dim)
57-
for j in range(order):
58-
p[:dim, j * dim : (j + 1) * dim] = phi[j]
59-
v, _ = np.linalg.eig(p)
60-
assert np.max(np.abs(v)) < 1
61-
rvs = rvs[burn:]
62-
if pandas and dim == 1:
63-
return pd.Series(rvs, name="x")
64-
elif pandas:
65-
return pd.DataFrame(rvs, columns=[f"x{i}" for i in range(dim)])
66-
return rvs
67-
68-
6932
def direct_var(
7033
x, const: bool, full_order: int, diag_order: int, max_order: Optional[int] = None
7134
) -> Tuple[NDArray, NDArray]:
@@ -140,29 +103,36 @@ def direct_ic(
140103
@pytest.mark.parametrize("diag_order", [3, 5])
141104
@pytest.mark.parametrize("max_order", [None, 10])
142105
@pytest.mark.parametrize("ic", ["aic", "bic", "hqc"])
143-
def test_direct_var(data, const, full_order, diag_order, max_order, ic):
144-
direct_ic(data, ic, const, full_order, diag_order, max_order)
106+
def test_direct_var(covariance_data, const, full_order, diag_order, max_order, ic):
107+
direct_ic(covariance_data, ic, const, full_order, diag_order, max_order)
145108

146109

147110
@pytest.mark.parametrize("center", [True, False])
148111
@pytest.mark.parametrize("diagonal", [True, False])
149112
@pytest.mark.parametrize("method", ["aic", "bic", "hqc"])
150-
def test_ic(data, center, diagonal, method):
113+
def test_ic(covariance_data, center, diagonal, method):
151114
pwrc = PreWhitenRecoloredCovariance(
152-
data, center=center, diagonal=diagonal, method=method, bandwidth=0.0,
115+
covariance_data, center=center, diagonal=diagonal, method=method, bandwidth=0.0,
153116
)
154117
cov = pwrc.cov
155-
expected_type = np.ndarray if isinstance(data, np.ndarray) else pd.DataFrame
118+
expected_type = (
119+
np.ndarray if isinstance(covariance_data, np.ndarray) else pd.DataFrame
120+
)
156121
assert isinstance(cov.short_run, expected_type)
157-
expected_max_lag = int(data.shape[0] ** (1 / 3))
122+
expected_max_lag = int(covariance_data.shape[0] ** (1 / 3))
158123
assert pwrc._max_lag == expected_max_lag
159124
expected_ics = {}
160125
for full_order in range(expected_max_lag + 1):
161126
diag_limit = expected_max_lag + 1 if diagonal else full_order + 1
162127
for diag_order in range(full_order, diag_limit):
163128
key = (full_order, diag_order)
164129
expected_ics[key] = direct_ic(
165-
data, method, center, full_order, diag_order, max_order=expected_max_lag
130+
covariance_data,
131+
method,
132+
center,
133+
full_order,
134+
diag_order,
135+
max_order=expected_max_lag,
166136
)
167137
assert tuple(sorted(pwrc._ics.keys())) == tuple(sorted(expected_ics.keys()))
168138
for key in expected_ics:
@@ -175,13 +145,18 @@ def test_ic(data, center, diagonal, method):
175145
@pytest.mark.parametrize("diagonal", [True, False])
176146
@pytest.mark.parametrize("method", ["aic", "bic", "hqc"])
177147
@pytest.mark.parametrize("lags", [0, 1, 3])
178-
def test_short_long_run(data, center, diagonal, method, lags):
148+
def test_short_long_run(covariance_data, center, diagonal, method, lags):
179149
pwrc = PreWhitenRecoloredCovariance(
180-
data, center=center, diagonal=diagonal, method=method, lags=lags, bandwidth=0.0,
150+
covariance_data,
151+
center=center,
152+
diagonal=diagonal,
153+
method=method,
154+
lags=lags,
155+
bandwidth=0.0,
181156
)
182157
cov = pwrc.cov
183158
full_order, diag_order = pwrc._order
184-
params, resids = direct_var(data, center, full_order, diag_order)
159+
params, resids = direct_var(covariance_data, center, full_order, diag_order)
185160
nobs, nvar = resids.shape
186161
expected_short_run = resids.T @ resids / nobs
187162
assert_allclose(cov.short_run, expected_short_run)
@@ -195,10 +170,27 @@ def test_short_long_run(data, center, diagonal, method, lags):
195170
assert_allclose(cov.long_run, expected_long_run)
196171

197172

173+
@pytest.mark.parametrize("force_int", [True, False])
174+
def test_pwrc_attributes(covariance_data, force_int):
175+
pwrc = PreWhitenRecoloredCovariance(covariance_data, force_int=force_int)
176+
assert isinstance(pwrc.bandwidth_scale, float)
177+
assert isinstance(pwrc.kernel_const, float)
178+
assert isinstance(pwrc.rate, float)
179+
assert isinstance(pwrc._weights(), np.ndarray)
180+
assert pwrc.force_int == force_int
181+
expected_type = (
182+
np.ndarray if isinstance(covariance_data, np.ndarray) else pd.DataFrame
183+
)
184+
assert isinstance(pwrc.cov.short_run, expected_type)
185+
assert isinstance(pwrc.cov.long_run, expected_type)
186+
assert isinstance(pwrc.cov.one_sided, expected_type)
187+
assert isinstance(pwrc.cov.one_sided_strict, expected_type)
188+
189+
198190
@pytest.mark.parametrize("sample_autocov", [True, False])
199-
def test_data(data, sample_autocov):
191+
def test_data(covariance_data, sample_autocov):
200192
pwrc = PreWhitenRecoloredCovariance(
201-
data, sample_autocov=sample_autocov, bandwidth=0.0
193+
covariance_data, sample_autocov=sample_autocov, bandwidth=0.0
202194
)
203195
pwrc.cov
204196

@@ -217,3 +209,8 @@ def test_pwrc_warnings():
217209
x = np.random.standard_normal((9, 5))
218210
with pytest.warns(RuntimeWarning, match="The maximum number of lags is 0"):
219211
PreWhitenRecoloredCovariance(x).cov
212+
213+
214+
def test_unknown_kernel(covariance_data):
215+
with pytest.raises(ValueError, match=""):
216+
PreWhitenRecoloredCovariance(covariance_data, kernel="unknown")

arch/tests/unitroot/test_dynamic_ols.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@ def test_smoke(data, trend, lags, leads, common, max_lag, method):
1616
y, x = data
1717
if common:
1818
leads = lags
19-
mod = DynamicOLS(y, x, trend, lags, leads, common, max_lag, max_lag, method)
19+
mod = DynamicOLS(
20+
y,
21+
x,
22+
trend,
23+
lags=lags,
24+
leads=leads,
25+
common=common,
26+
max_lag=max_lag,
27+
max_lead=max_lag,
28+
method=method,
29+
)
2030
mod.fit()
2131

2232

@@ -27,8 +37,14 @@ def test_smoke(data, trend, lags, leads, common, max_lag, method):
2737
@pytest.mark.parametrize("df_adjust", [True, False])
2838
def test_smoke_fit(data, cov_type, kernel, bandwidth, force_int, df_adjust):
2939
y, x = data
30-
mod = DynamicOLS(y, x, "ct", 3, 5, False)
31-
res = mod.fit(cov_type, kernel, bandwidth, force_int, df_adjust)
40+
mod = DynamicOLS(y, x, "ct", lags=3, leads=5, common=False)
41+
res = mod.fit(
42+
cov_type,
43+
kernel=kernel,
44+
bandwidth=bandwidth,
45+
force_int=force_int,
46+
df_adjust=df_adjust,
47+
)
3248
assert isinstance(res.leads, int)
3349
assert isinstance(res.lags, int)
3450
assert isinstance(res.bandwidth, (int, float))
@@ -44,7 +60,7 @@ def test_smoke_fit(data, cov_type, kernel, bandwidth, force_int, df_adjust):
4460
def test_mismatch_lead_lag(data):
4561
y, x = data
4662
with pytest.raises(ValueError, match="common is specified but leads"):
47-
DynamicOLS(y, x, "c", 4, 5, True)
63+
DynamicOLS(y, x, "c", lags=4, leads=5, common=True)
4864
with pytest.raises(ValueError, match="common is specified but max_lead"):
4965
DynamicOLS(y, x, max_lag=6, max_lead=7, common=True)
5066

arch/tests/unitroot/test_fmols_ccr.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ def test_fmols_smoke(
2020
y, x = trivariate_data
2121
if x_trend is not None and len(x_trend) < len(trend):
2222
x_trend = trend
23-
mod = FullyModifiedOLS(y, x, trend, x_trend)
24-
res = mod.fit(kernel, bandwidth, force_int, diff)
23+
mod = FullyModifiedOLS(y, x, trend, x_trend=x_trend)
24+
res = mod.fit(kernel=kernel, bandwidth=bandwidth, force_int=force_int, diff=diff)
2525
assert isinstance(res.summary(), Summary)
2626

2727

@@ -35,8 +35,8 @@ def test_ccr_smoke(trivariate_data, trend, x_trend, diff, kernel, bandwidth, for
3535
y, x = trivariate_data
3636
if x_trend is not None and len(x_trend) < len(trend):
3737
x_trend = trend
38-
mod = CanonicalCointegratingReg(y, x, trend, x_trend)
39-
res = mod.fit(kernel, bandwidth, force_int, diff)
38+
mod = CanonicalCointegratingReg(y, x, trend, x_trend=x_trend)
39+
res = mod.fit(kernel=kernel, bandwidth=bandwidth, force_int=force_int, diff=diff)
4040
assert isinstance(res.summary(), Summary)
4141

4242

@@ -189,7 +189,7 @@ def test_fmols_eviews(trivariate_data, test_key):
189189
trend, x_trend, diff = test_key
190190
key = (trend, x_trend, diff)
191191
test_res = setup_test_values(FMOLS_RES[key])
192-
mod = FullyModifiedOLS(y, x, trend, x_trend)
192+
mod = FullyModifiedOLS(y, x, trend, x_trend=x_trend)
193193
# BW is one less than what Eviews reports
194194
res = mod.fit(bandwidth=6, force_int=True, diff=diff, df_adjust=True)
195195
if trend != "ctt":
@@ -322,7 +322,7 @@ def test_ccr_eviews(trivariate_data, test_key):
322322
trend, x_trend, diff = test_key
323323
key = (trend, x_trend, diff)
324324
test_res = setup_test_values(CCR_RES[key])
325-
mod = CanonicalCointegratingReg(y, x, trend, x_trend)
325+
mod = CanonicalCointegratingReg(y, x, trend, x_trend=x_trend)
326326
# BW is one less than what Eviews reports
327327
res = mod.fit(bandwidth=6, force_int=True, diff=diff, df_adjust=True)
328328
if trend == "n":

0 commit comments

Comments
 (0)