{"record":{"id":"e0d7b225730f7fc3","repo":"HKUDS/Vibe-Trading","slug":"ts-max-window-must-be-1-got-n","errorCode":null,"errorMessage":"ts_max window must be >= 1, got {n}","messagePattern":"ts_max window must be >= 1, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/base.py","lineNumber":196,"sourceCode":"\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:\n    \"\"\"Rolling min per column, warmup → NaN.\"\"\"\n    if n < 1:\n        raise ValueError(f\"ts_min window must be >= 1, got {n}\")\n    return df.rolling(window=n, min_periods=n).min()\n\n\ndef _argmax_last(arr: np.ndarray) -> float:\n    if np.isnan(arr).all():\n        return np.nan\n    arr_filled = np.where(np.isnan(arr), -np.inf, arr)\n    return float(np.argmax(arr_filled))\n\n\ndef _argmin_last(arr: np.ndarray) -> float:","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/base.py#L178-L214","documentation":"ts_max computes a rolling maximum per column with a warmup of NaN. The window parameter n must be a positive integer because pandas rolling requires window >= 1; n < 1 (zero or negative) is rejected before calling pandas to fail fast with a clear message.","triggerScenarios":"Calling ts_max(df, 0), ts_max(df, -3), or passing a window derived from config/user input that evaluates to a non-positive integer.","commonSituations":"Config typos (window: 0), computing windows from expressions like len(df) - horizon that hit 0 on short data, or looping over a list of windows that accidentally includes 0.","solutions":["Pass a window >= 1, e.g. ts_max(df, 5)","Validate windows in config/loading before calling compute()","If windows come from arithmetic, clamp: max(1, n)"],"exampleFix":"// before\nts_max(df, 0)\n// after\nts_max(df, max(1, window))","handlingStrategy":"validation","validationCode":"if not isinstance(n, int) or n < 1: raise ValueError(f'window must be int >= 1, got {n!r}')","typeGuard":"def is_valid_window(n: object) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n >= 1","tryCatchPattern":null,"preventionTips":["Validate all window params at config load time","Never compute windows without clamping to >= 1"],"tags":["rolling-window","validation","pandas"],"backgroundTag":"invalid-window-size","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}