{"record":{"id":"e2f943f80629a74c","repo":"HKUDS/Vibe-Trading","slug":"ts-cov-window-must-be-2-got-n","errorCode":null,"errorMessage":"ts_cov window must be >= 2, got {n}","messagePattern":"ts_cov window must be >= 2, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/base.py","lineNumber":169,"sourceCode":"    on columns; columns missing from either side become NaN.\n    \"\"\"\n    if n < 2:\n        raise ValueError(f\"ts_corr window must be >= 2, got {n}\")\n    x = _as_float(x)\n    y = _as_float(y)\n    cols = x.columns.union(y.columns)\n    xa = x.reindex(columns=cols)\n    ya = y.reindex(columns=cols)\n    corr = xa.rolling(window=n, min_periods=n).corr(ya)\n    # corr above can produce +/- inf when one series is constant in some\n    # pandas versions; force to NaN.\n    return corr.replace([np.inf, -np.inf], np.nan)\n\n\ndef ts_cov(x: pd.DataFrame, y: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling sample covariance per column, min_periods=n.\"\"\"\n    if n < 2:\n        raise ValueError(f\"ts_cov window must be >= 2, got {n}\")\n    x = _as_float(x)\n    y = _as_float(y)\n    cols = x.columns.union(y.columns)\n    xa = x.reindex(columns=cols)\n    ya = y.reindex(columns=cols)\n    cov = xa.rolling(window=n, min_periods=n).cov(ya)\n    return cov.replace([np.inf, -np.inf], np.nan)\n\n\ndef ts_mean(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling mean per column, warmup → NaN.\"\"\"\n    if n < 1:\n        raise ValueError(f\"ts_mean window must be >= 1, got {n}\")\n    return df.rolling(window=n, min_periods=n).mean()\n\n\ndef ts_std(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling sample std (ddof=1) per column, warmup → NaN.\"\"\"","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/base.py#L151-L187","documentation":"ts_cov requires a window of at least 2 because sample covariance needs at least two observations; n < 2 raises. Like ts_corr it inner-joins columns and uses min_periods=n, so warmup rows are NaN.","triggerScenarios":"ts_cov(x, y, 1), ts_cov(x, y, 0), or negative n; also a dynamically computed window collapsing to 1 on short panels. Called from compute() and tests.","commonSituations":"Same as ts_corr: auto-scaled windows on short series, config errors, and copy-pasted window values from min-1 operators.","solutions":["Pass n >= 2","Enforce a minimum window of 2 in any auto-scaling logic and handle too-short inputs explicitly","Unit-test factor configs against boundary windows (1, 2, len(df))"],"exampleFix":"# before\ncov = ts_cov(x, y, n=1)\n\n# after\ncov = ts_cov(x, y, n=20)","handlingStrategy":"validation","validationCode":"if not isinstance(n, int) or n < 2:\n    raise ValueError(f'invalid ts_cov window: {n!r}')\ncov = ts_cov(x, y, n)","typeGuard":"def is_valid_ts_cov_window(n) -> bool:\n    return isinstance(n, int) and n >= 2","tryCatchPattern":null,"preventionTips":["Sample covariance needs at least 2 points; enforce the floor in auto-scaling","Share a validated window-config object across corr/cov operators"],"tags":["python","factors","rolling-window","covariance","parameter-validation"],"backgroundTag":"rolling-window-invalid","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}