HKUDS/Vibe-Trading · error · ValueError
lags must be < the number of observations; got lags={lags} f
Error message
lags must be < the number of observations; got lags={lags} for {clean.size} observations What it means
After dropping NaNs, autocorrelation_test requires lags to be strictly less than the number of remaining observations. statsmodels' acorr_ljungbox silently caps lags and then dies on a numpy shape mismatch that names neither argument, so this guard gives an actionable message up front.
Source
Thrown at agent/src/quantlib/timeseries.py:699
Dict with keys ``durbin_watson`` (float), ``dw_interpretation`` (str,
one of ``'positive autocorrelation'`` / ``'no autocorrelation'`` /
``'negative autocorrelation'``), ``ljung_box_p`` (numpy array of
p-values, one per lag), ``has_autocorrelation`` (bool) and ``fix`` (str).
Raises:
ImportError: If ``statsmodels`` is not installed.
ValueError: If ``lags`` is below 1.
"""
diagnostic = _require("statsmodels.stats.diagnostic", "statsmodels", "autocorrelation_test")
stattools = _require("statsmodels.stats.stattools", "statsmodels", "autocorrelation_test")
if lags < 1:
raise ValueError(f"autocorrelation_test needs lags >= 1, got {lags}")
clean = pd.Series(residuals, dtype=float).dropna()
if lags >= clean.size:
# acorr_ljungbox silently caps lags and then dies on a shape mismatch
# with a numpy message that names neither argument.
raise ValueError(
f"lags must be < the number of observations; got lags={lags} "
f"for {clean.size} observations"
)
dw = float(stattools.durbin_watson(clean))
lb_p = np.asarray(diagnostic.acorr_ljungbox(clean, lags=lags)["lb_pvalue"].values, dtype=float)
if dw < _DW_POSITIVE_BELOW:
interpretation = "positive autocorrelation"
elif dw < _DW_NEGATIVE_ABOVE:
interpretation = "no autocorrelation"
else:
interpretation = "negative autocorrelation"
return {
"durbin_watson": dw,
"dw_interpretation": interpretation,
"ljung_box_p": lb_p,
"has_autocorrelation": bool(np.any(lb_p < significance)),View on GitHub (pinned to 80ffdda44c)
Solutions
- Reduce lags below the number of non-NaN observations, e.g. lags < clean.size.
- Derive lags from the actual cleaned length: lags = min(desired_lags, clean_size - 1).
- Check residuals length and NaN count before calling.
Example fix
// before autocorrelation_test(residuals, lags=40) # residuals has 40 obs -> error // after clean_n = pd.Series(residuals).dropna().size autocorrelation_test(residuals, lags=min(40, clean_n - 1))
Defensive patterns
Strategy: validation
Validate before calling
clean_n = pd.Series(residuals).dropna().size lags = max(1, min(desired_lags, clean_n - 1)) autocorrelation_test(residuals, lags=lags)
Try / catch
try:
result = autocorrelation_test(residuals, lags=lags)
except ValueError as e:
if "observations" in str(e):
lags = max(1, clean_n - 1)
result = autocorrelation_test(residuals, lags=lags)
else:
raise Prevention
- Always size lags relative to the non-NaN length of the series.
- Log clean.size alongside lags when running diagnostics over many windows.
When it happens
Trigger: autocorrelation_test(residuals, lags=50) on a 40-row series, or a series whose NaN-dropped size (clean.size) falls to <= lags; passing lags == n is also rejected.
Common situations: Running diagnostics on short backtest windows, small samples after dropna, or reusing a lag count tuned on a longer dataset.
Related errors
- autocorrelation_test needs lags >= 1, got {lags}
- bootstrap_statistic needs n_bootstrap >= 1, got {n_bootstrap
- vif_test needs at least one column
- bootstrap_statistic needs a non-empty sample
- bootstrap_statistic needs confidence in (0, 1), got {confide
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/570b97f9a60e0447.
Report an issue: GitHub.