{"record":{"id":"99d1d1ed48b4c076","repo":"HKUDS/Vibe-Trading","slug":"granger-test-column-s-not-in-data-missing","errorCode":null,"errorMessage":"granger_test: column(s) not in data: {missing}","messagePattern":"granger_test: column\\(s\\) not in data: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/timeseries.py","lineNumber":414,"sourceCode":"    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:\n        returns: Daily return series as *fractions* (0.01 = 1%). Scaled to\n            percent internally, which is what ``arch`` optimises well on.\n        horizon: Number of days ahead to forecast.","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/timeseries.py#L396-L432","documentation":"granger_test raises KeyError listing the requested columns missing from the input DataFrame, because statsmodels would fail cryptically when selecting data[[y_col, x_col]] with unknown names.","triggerScenarios":"Calling granger_test with a column name not in data.columns — typos, differing naming conventions ('Close' vs 'close'), or DataFrame built without the expected columns.","commonSituations":"Case-mismatched column names, DataFrames from CSVs with renamed headers, or pipelines where the feature-engineering step that creates the column (e.g. returns) never ran.","solutions":["Print/inspect data.columns and fix the name","Normalize column names to lowercase/snake_case before calling","Ensure upstream steps that create derived columns (returns, spreads) executed"],"exampleFix":"# before\nres = granger_test(df, x_col='Close', y_col='Volume')  # actual: 'close','volume'\n# after\nres = granger_test(df.rename(columns=str.lower), x_col='close', y_col='volume')","handlingStrategy":"validation","validationCode":"missing = [c for c in (y_col, x_col) if c not in data.columns]\nif missing:\n    raise KeyError(f'missing columns: {missing}')","typeGuard":"def columns_present(data: pd.DataFrame, *cols: str) -> bool:\n    return all(c in data.columns for c in cols)","tryCatchPattern":"try:\n    granger_test(data, y_col, x_col)\nexcept KeyError as e:\n    # re-raise with available columns for debugging\n    raise KeyError(f'{e}; available: {list(data.columns)}') from e","preventionTips":["Normalize column names (str.lower/strip) at load time","Assert required columns exist after feature engineering","Log data.columns when debugging pipeline failures"],"tags":["python","pandas","missing-column","keyerror"],"backgroundTag":"missing-column-name","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}