Skip to content

Commit

Permalink
ENH: Add explicit error for bad horizon
Browse files Browse the repository at this point in the history
Check that horizon is an int >= 1
  • Loading branch information
bashtage committed Jun 24, 2020
1 parent 217eb05 commit c6de761
Show file tree
Hide file tree
Showing 12 changed files with 31 additions and 10 deletions.
2 changes: 2 additions & 0 deletions arch/tests/unitroot/test_engle_granger.py
Expand Up @@ -171,6 +171,8 @@ def test_trivariate(data, trend, method, lhs):

fig = test.plot()
assert isinstance(fig, plt.Figure)

plt.close("all")
assert isinstance(test.resid, pd.Series)
assert test.resid.shape[0] == dep.shape[0]

Expand Down
2 changes: 2 additions & 0 deletions arch/tests/univariate/test_forecast.py
Expand Up @@ -123,6 +123,8 @@ def test_zero_mean_forecast(self):
assert_allclose(
fcast.residual_variance.iloc[499:], np.ones((501, 3)) * params[0]
)
with pytest.raises(ValueError, match="horizon must be an integer >= 1"):
res.forecast(horizon=0)

def test_frame_labels(self):
am = arch_model(self.zero_mean, mean="Zero", vol="Constant")
Expand Down
8 changes: 8 additions & 0 deletions arch/tests/univariate/test_mean.py
Expand Up @@ -132,6 +132,8 @@ def test_constant_mean(self):
assert isinstance(cm.__repr__(), str)
assert isinstance(cm.__str__(), str)
assert "<strong>" in cm._repr_html_()
with pytest.raises(ValueError, match="horizon must be an integer >= 1"):
res.forecast(horizon=0, start=20)

def test_zero_mean(self):
zm = ZeroMean(self.y)
Expand Down Expand Up @@ -456,13 +458,19 @@ def test_ar_plot(self):
with pytest.raises(ValueError):
res.plot(annualize="unknown")

import matplotlib.pyplot as plt

plt.close("all")

res.plot(scale=360)
res.hedgehog_plot(start=500)
res.hedgehog_plot(start=500, plot_type="mean")
res.hedgehog_plot(plot_type="volatility")
res.hedgehog_plot(start=500, method="simulation", simulations=100)
res.hedgehog_plot(plot_type="volatility", method="bootstrap")

plt.close("all")

def test_arch_arx(self):
self.rng.seed(12345)
x = self.rng.randn(500, 3)
Expand Down
2 changes: 2 additions & 0 deletions arch/tests/univariate/test_variance_forecasting.py
Expand Up @@ -235,6 +235,8 @@ def test_arch_1_forecast(self):
)
expected[:100] = np.nan
assert_allclose(forecast.forecasts, expected)
with pytest.raises(ValueError, match="horizon must be an integer >= 1"):
vol.forecast(params, self.resid, backcast, var_bounds, start=0, horizon=0)

def test_arch_1_forecast_simulation(self):
dist = Normal(self.rng)
Expand Down
Expand Up @@ -6,10 +6,8 @@
import random

import colorama
from joblib import Parallel, delayed
import numpy as np
from numpy.random import PCG64, Generator, SeedSequence
import psutil

from adf_simulation import (
OUTPUT_PATH,
Expand All @@ -18,6 +16,8 @@
TRENDS,
adf_simulation,
)
from joblib import Parallel, delayed
import psutil

GREEN = colorama.Fore.GREEN
BLUE = colorama.Fore.BLUE
Expand Down
Expand Up @@ -11,10 +11,11 @@
from typing import List

import colorama
from joblib import Parallel, cpu_count, delayed
import numpy as np
from numpy.random import PCG64, Generator, SeedSequence

from joblib import Parallel, cpu_count, delayed

ROOT = os.path.join(os.path.split(os.path.abspath(__file__))[0], "engle-granger")
if not os.path.exists(ROOT):
os.mkdir(ROOT)
Expand Down
Expand Up @@ -8,15 +8,15 @@
from typing import Optional, Tuple

import colorama
from joblib import Parallel, delayed
import numpy as np
from numpy.linalg import inv, lstsq, solve
import pandas as pd
import psutil

from arch.typing import NDArray
from arch.utility.timeseries import add_trend
from joblib import Parallel, delayed
from phillips_ouliaris import QUANTILES, ROOT, SAMPLE_SIZES, TRENDS
import psutil

GREEN = colorama.Fore.GREEN
BLUE = colorama.Fore.BLUE
Expand Down
6 changes: 3 additions & 3 deletions arch/unitroot/unitroot.py
Expand Up @@ -1341,9 +1341,9 @@ def _autolag(self) -> None:
s1 += i * resids_prod
if s0 <= 0:
raise InfeasibleTestException(
f"Residuals are all zero and so automatic bandwidth selection cannot "
f"be used. This is usually an indication that the series being testes "
f"is too small or have constant values."
"Residuals are all zero and so automatic bandwidth selection cannot "
"be used. This is usually an indication that the series being testes "
"is too small or have constant values."
)
s_hat = s1 / s0
pwr = 1.0 / 3.0
Expand Down
2 changes: 2 additions & 0 deletions arch/univariate/base.py
Expand Up @@ -1388,6 +1388,8 @@ def forecast(
or params.ndim != self._params.ndim
):
raise ValueError("params have incorrect dimensions")
if not isinstance(horizon, (int, np.integer)) or horizon < 1:
raise ValueError("horizon must be an integer >= 1.")
return self.model.forecast(
params, horizon, start, align, method, simulations, rng, random_state
)
Expand Down
2 changes: 2 additions & 0 deletions arch/univariate/mean.py
Expand Up @@ -692,6 +692,8 @@ def forecast(
rng: Optional[Callable[[Union[int, Tuple[int, ...]]], NDArray]] = None,
random_state: Optional[np.random.RandomState] = None,
) -> ARCHModelForecast:
if not isinstance(horizon, (int, np.integer)) or horizon < 1:
raise ValueError("horizon must be an integer >= 1.")
# Check start
earliest, default_start = self._fit_indices
default_start = max(0, default_start - 1)
Expand Down
5 changes: 3 additions & 2 deletions arch/univariate/volatility.py
Expand Up @@ -643,7 +643,8 @@ def forecast(
method = method.lower()
if method not in ("analytic", "simulation", "bootstrap"):
raise ValueError("{0} is not a known forecasting method".format(method))

if not isinstance(horizon, (int, np.integer)) or horizon < 1:
raise ValueError("horizon must be an integer >= 1.")
self._check_forecasting_method(method, horizon)
start = len(resids) - 1 if start is None else start
if method == "analytic":
Expand Down Expand Up @@ -2743,7 +2744,7 @@ def backcast(self, resids: NDArray) -> float:

def bounds(self, resids: NDArray) -> List[Tuple[float, float]]:
if not self._unit_scale:
v = self.starting_values(resids)
v = float(np.squeeze(self.starting_values(resids)))
_resids = resids / np.sqrt(self._variance[self._start : self._stop])
mu = _resids.mean()
return [(v / 100000.0, 10.0 * (v + mu ** 2.0))]
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Expand Up @@ -29,6 +29,7 @@ filterwarnings =
error:invalid value encountered in log:RuntimeWarning
error:divide by zero encountered in double_scalars:RuntimeWarning
error:Lag selection has changed:DeprecationWarning
error:More than 20 figures have been opened:RuntimeWarning:
markers =
slow: mark a test as slow

Expand Down

0 comments on commit c6de761

Please sign in to comment.