{"record":{"id":"79f5ec433ac0957b","repo":"HKUDS/Vibe-Trading","slug":"ts-mean-window-must-be-1-got-n","errorCode":null,"errorMessage":"ts_mean window must be >= 1, got {n}","messagePattern":"ts_mean window must be >= 1, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/base.py","lineNumber":182,"sourceCode":"\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.\"\"\"\n    if n < 2:\n        raise ValueError(f\"ts_std window must be >= 2, got {n}\")\n    return df.rolling(window=n, min_periods=n).std(ddof=1)\n\n\ndef ts_max(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling max per column, warmup → NaN.\"\"\"\n    if n < 1:\n        raise ValueError(f\"ts_max window must be >= 1, got {n}\")\n    return df.rolling(window=n, min_periods=n).max()\n\n\ndef ts_min(df: pd.DataFrame, n: int) -> pd.DataFrame:","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/base.py#L164-L200","documentation":"ts_mean requires n >= 1; a rolling mean over zero or negative observations is undefined, so the guard raises immediately. Warmup rows (first n-1) are NaN because min_periods=n.","triggerScenarios":"ts_mean(df, 0), ts_mean(df, -3), or a window computed as len(df) - offset that hits 0. Called from compute() in the factor pipeline.","commonSituations":"Missing config values defaulting to 0; percentage windows (0.5) instead of counts; dynamic windows on very short dataframes.","solutions":["Pass a positive integer window","Validate window parameters at config load time","When deriving windows from data length, assert n >= 1 before calling"],"exampleFix":"# before\nm = ts_mean(df, n=0)\n\n# after\nm = ts_mean(df, n=20)","handlingStrategy":"validation","validationCode":"if not isinstance(n, int) or n < 1:\n    raise ValueError(f'invalid ts_mean window: {n!r}')\nm = ts_mean(df, n)","typeGuard":"def is_valid_ts_mean_window(n) -> bool:\n    return isinstance(n, int) and n >= 1","tryCatchPattern":null,"preventionTips":["Validate window params at config load, not per call","Reject fractional/percentage windows early","Assert n <= len(df) when windows are derived from data length"],"tags":["python","factors","rolling-window","parameter-validation"],"backgroundTag":"rolling-window-invalid","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}