{"record":{"id":"036b6a1a51b5c7ab","repo":"HKUDS/Vibe-Trading","slug":"granger-test-needs-max-lag-1-got-max-lag","errorCode":null,"errorMessage":"granger_test needs max_lag >= 1, got {max_lag}","messagePattern":"granger_test needs max_lag >= 1, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/timeseries.py","lineNumber":411,"sourceCode":"        Dict mapping lag (int, 1..``max_lag``) to the SSR F-test p-value (float).\n        A small p-value rejects \"x does not Granger-cause y\".\n\n    Raises:\n        ImportError: If ``statsmodels`` is not installed.\n        KeyError: If either column is missing from ``data``.\n        ValueError: If ``max_lag`` is below 1, or if ``x_col`` and ``y_col`` are\n            the same column. Testing a series against itself hands statsmodels a\n            duplicated column, where the F-test trivially fails to reject and\n            every p-value comes back 1.0 -- an answer that looks like a finding.\n    \"\"\"\n    if x_col == y_col:\n        raise ValueError(\n            f\"x_col and y_col must differ; both are {x_col!r}. A series cannot \"\n            \"Granger-cause itself and the test returns p=1.0 regardless.\"\n        )\n    stattools = _require(\"statsmodels.tsa.stattools\", \"statsmodels\", \"granger_test\")\n    if max_lag < 1:\n        raise ValueError(f\"granger_test needs max_lag >= 1, got {max_lag}\")\n    missing = [c for c in (y_col, x_col) if c not in data.columns]\n    if missing:\n        raise KeyError(f\"granger_test: column(s) not in data: {missing}\")\n\n    # statsmodels >= 0.14 dropped the `verbose` kwarg and prints the full test\n    # table to stdout unconditionally; swallow it so a library call stays quiet.\n    with contextlib.redirect_stdout(io.StringIO()):\n        results = stattools.grangercausalitytests(data[[y_col, x_col]].dropna(), maxlag=max_lag)\n    return {lag: float(results[lag][0][\"ssr_ftest\"][1]) for lag in range(1, max_lag + 1)}\n\n\ndef fit_garch(returns: pd.Series, horizon: int = 5) -> dict:\n    \"\"\"Fit a GARCH(1,1) model and forecast forward volatility.\n\n    Model: ``r_t = μ + ε_t`` with ``σ²_t = ω + α·ε²_{t-1} + β·σ²_{t-1}``.\n    ``α + β`` is volatility persistence (typically 0.95-0.99 in equities).\n\n    Args:","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/timeseries.py#L393-L429","documentation":"granger_test requires max_lag >= 1; a max_lag of 0 or negative means no lags to test, which statsmodels' grangercausalitytests cannot handle meaningfully.","triggerScenarios":"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.","commonSituations":"Auto-tuning lag order that underflows to 0 on short series, config files with lag: 0, or arithmetic on user-supplied parameters.","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"],"exampleFix":"# before\nres = granger_test(df, 'y', 'x', max_lag=computed_lag)\n# after\nres = granger_test(df, 'y', 'x', max_lag=max(1, computed_lag))","handlingStrategy":"validation","validationCode":"max_lag = max(1, int(max_lag))\nassert max_lag >= 1","typeGuard":"def valid_lag(max_lag: int) -> bool:\n    return isinstance(max_lag, int) and max_lag >= 1","tryCatchPattern":"try:\n    granger_test(data, y_col, x_col, max_lag=max_lag)\nexcept ValueError as e:\n    if 'max_lag >= 1' in str(e):\n        return granger_test(data, y_col, x_col, max_lag=1)\n    raise","preventionTips":["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"],"tags":["python","granger-causality","parameter-validation"],"backgroundTag":"invalid-argument-range","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}