Skip to content

Commit d7286a4

Browse files
authored
Merge pull request #514 from bashtage/ar0-forecast
BUG: Ensure AR0 can be used in simulation forecasting
2 parents c3ec457 + cb49c39 commit d7286a4

File tree

3 files changed

+1058
-1010
lines changed

3 files changed

+1058
-1010
lines changed

arch/tests/univariate/test_forecast.py

+48
Original file line numberDiff line numberDiff line change
@@ -864,3 +864,51 @@ def test_model_forecast_recursive():
864864
end = SP500.shape[0] - 10 + i
865865
mod = ConstantMean(SP500.iloc[:end], volatility=vol)
866866
fcasts[i] = mod.forecast(params, reindex=True)
867+
868+
869+
@pytest.mark.parametrize("lags", [0, 1, 2, [2]])
870+
@pytest.mark.parametrize("constant", [True, False])
871+
def test_forecast_ar0(constant, lags):
872+
burn = 250
873+
874+
x_mod = ARX(None, lags=1)
875+
x0 = x_mod.simulate([1, 0.8, 1], nobs=1000 + burn).data
876+
x1 = x_mod.simulate([2.5, 0.5, 1], nobs=1000 + burn).data
877+
878+
resid_mod = ZeroMean(volatility=GARCH())
879+
resids = resid_mod.simulate([0.1, 0.1, 0.8], nobs=1000 + burn).data
880+
881+
phi1 = 0.7
882+
phi0 = 3
883+
y = 10 + resids.copy()
884+
for i in range(1, y.shape[0]):
885+
y[i] = phi0 + phi1 * y[i - 1] + 2 * x0[i] - 2 * x1[i] + resids[i]
886+
887+
x0 = x0.iloc[-1000:]
888+
x1 = x1.iloc[-1000:]
889+
y = y.iloc[-1000:]
890+
y.index = x0.index = x1.index = np.arange(1000)
891+
892+
x0_oos = np.empty((1000, 10))
893+
x1_oos = np.empty((1000, 10))
894+
for i in range(10):
895+
if i == 0:
896+
last = x0
897+
else:
898+
last = x0_oos[:, i - 1]
899+
x0_oos[:, i] = 1 + 0.8 * last
900+
if i == 0:
901+
last = x1
902+
else:
903+
last = x1_oos[:, i - 1]
904+
x1_oos[:, i] = 2.5 + 0.5 * last
905+
906+
exog = pd.DataFrame({"x0": x0, "x1": x1})
907+
mod = ARX(y, x=exog, lags=lags, constant=constant, volatility=GARCH())
908+
res = mod.fit(disp="off")
909+
exog_fcast = {"x0": x0_oos[-1:], "x1": x1_oos[-1:]}
910+
forecasts = res.forecast(
911+
horizon=10, x=exog_fcast, method="simulation", simulations=100, reindex=False
912+
)
913+
assert forecasts.mean.shape == (1, 10)
914+
assert forecasts.simulations.values.shape == (1, 100, 10)

arch/univariate/mean.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ def _reformat_lags(self) -> None:
611611

612612
def _har_to_ar(self, params: Float64Array) -> Float64Array:
613613
if self._max_lags == 0:
614-
return params
614+
return params[: int(self.constant)]
615615
har = params[int(self.constant) :]
616616
ar = np.zeros(self._max_lags)
617617
for value, lag in zip(har, self._lags.T):

examples/univariate_forecasting_with_exogenous_variables.ipynb

+1,009-1,009
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)