HKUDS/Vibe-Trading · error · ValueError
granger_test needs max_lag >= 1, got {max_lag}
Error message
granger_test needs max_lag >= 1, got {max_lag} What it means
granger_test requires max_lag >= 1; a max_lag of 0 or negative means no lags to test, which statsmodels' grangercausalitytests cannot handle meaningfully.
Source
Thrown at agent/src/quantlib/timeseries.py:411
Dict mapping lag (int, 1..``max_lag``) to the SSR F-test p-value (float).
A small p-value rejects "x does not Granger-cause y".
Raises:
ImportError: If ``statsmodels`` is not installed.
KeyError: If either column is missing from ``data``.
ValueError: If ``max_lag`` is below 1, or if ``x_col`` and ``y_col`` are
the same column. Testing a series against itself hands statsmodels a
duplicated column, where the F-test trivially fails to reject and
every p-value comes back 1.0 -- an answer that looks like a finding.
"""
if x_col == y_col:
raise ValueError(
f"x_col and y_col must differ; both are {x_col!r}. A series cannot "
"Granger-cause itself and the test returns p=1.0 regardless."
)
stattools = _require("statsmodels.tsa.stattools", "statsmodels", "granger_test")
if max_lag < 1:
raise ValueError(f"granger_test needs max_lag >= 1, got {max_lag}")
missing = [c for c in (y_col, x_col) if c not in data.columns]
if missing:
raise KeyError(f"granger_test: column(s) not in data: {missing}")
# statsmodels >= 0.14 dropped the `verbose` kwarg and prints the full test
# table to stdout unconditionally; swallow it so a library call stays quiet.
with contextlib.redirect_stdout(io.StringIO()):
results = stattools.grangercausalitytests(data[[y_col, x_col]].dropna(), maxlag=max_lag)
return {lag: float(results[lag][0]["ssr_ftest"][1]) for lag in range(1, max_lag + 1)}
def fit_garch(returns: pd.Series, horizon: int = 5) -> dict:
"""Fit a GARCH(1,1) model and forecast forward volatility.
Model: ``r_t = μ + ε_t`` with ``σ²_t = ω + α·ε²_{t-1} + β·σ²_{t-1}``.
``α + β`` is volatility persistence (typically 0.95-0.99 in equities).
Args:View on GitHub (pinned to 80ffdda44c)
Solutions
- Clamp the computed lag: max_lag = max(1, computed_lag)
- Validate config values before the call
- Choose a conventional lag such as 4 (quarterly) or 12 for daily data
Example fix
# before res = granger_test(df, 'y', 'x', max_lag=computed_lag) # after res = granger_test(df, 'y', 'x', max_lag=max(1, computed_lag))
Defensive patterns
Strategy: validation
Validate before calling
max_lag = max(1, int(max_lag)) assert max_lag >= 1
Type guard
def valid_lag(max_lag: int) -> bool:
return isinstance(max_lag, int) and max_lag >= 1 Try / catch
try:
granger_test(data, y_col, x_col, max_lag=max_lag)
except ValueError as e:
if 'max_lag >= 1' in str(e):
return granger_test(data, y_col, x_col, max_lag=1)
raise Prevention
- Clamp computed lag orders with max(1, value)
- Validate config parameters at load time
- Prefer standard lag choices (4, 12) over auto-computed ones on short data
When it happens
Trigger: Calling granger_test(..., max_lag=0) or a negative value, often from a computed lag order (e.g. int(len(data) ** 0.3) on a tiny frame) or a config default of 0.
Common situations: Auto-tuning lag order that underflows to 0 on short series, config files with lag: 0, or arithmetic on user-supplied parameters.
Related errors
- ts_rank window must be >= 1, got {n}
- ts_corr window must be >= 2, got {n}
- ts_cov window must be >= 2, got {n}
- ts_mean window must be >= 1, got {n}
- ts_std window must be >= 2, got {n}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/036b6a1a51b5c7ab.
Report an issue: GitHub.