{"record":{"id":"79bbe3012b239e09","repo":"HKUDS/Vibe-Trading","slug":"ts-argmin-window-must-be-1-got-n","errorCode":null,"errorMessage":"ts_argmin window must be >= 1, got {n}","messagePattern":"ts_argmin window must be >= 1, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/base.py","lineNumber":246,"sourceCode":"    if n < 1:\n        raise ValueError(f\"ts_argmax window must be >= 1, got {n}\")\n    if HAS_BOTTLENECK:\n        arr = df.to_numpy(dtype=np.float64)\n        raw = bn.move_argmax(arr, window=n, min_count=n, axis=0)\n        corrected = (n - 1) - raw\n        return pd.DataFrame(corrected, index=df.index, columns=df.columns)\n    return df.rolling(window=n, min_periods=n).apply(_argmax_last, raw=True)\n\n\ndef ts_argmin(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling argmin (0-based index into the window), warmup → NaN.\n\n    Uses ``bottleneck.move_argmin`` when available (~350x faster).\n    Correction: ``bn.move_argmin`` returns distance from window end,\n    so we convert via ``(n - 1) - bn_result`` to get 0-based index from start.\n    \"\"\"\n    if n < 1:\n        raise ValueError(f\"ts_argmin window must be >= 1, got {n}\")\n    if HAS_BOTTLENECK:\n        arr = df.to_numpy(dtype=np.float64)\n        raw = bn.move_argmin(arr, window=n, min_count=n, axis=0)\n        corrected = (n - 1) - raw\n        return pd.DataFrame(corrected, index=df.index, columns=df.columns)\n    return df.rolling(window=n, min_periods=n).apply(_argmin_last, raw=True)\n\n\ndef delta(df: pd.DataFrame, d: int) -> pd.DataFrame:\n    \"\"\"First difference at lag ``d``: ``df - df.shift(d)``.\n\n    Lookahead ban: ``d >= 1`` strictly. Negative lag forbidden.\n    \"\"\"\n    if d < 1:\n        raise ValueError(f\"delta lag must be >= 1 (lookahead ban), got {d}\")\n    return df - df.shift(d)\n\n","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/base.py#L228-L264","documentation":"ts_argmin returns the 0-based index of the min in each rolling window, using bottleneck.move_argmin with an index correction. Window n must be >= 1; the ValueError is a fail-fast guard before the rolling computation.","triggerScenarios":"Calling ts_argmin(df, 0) or with a negative window, or parameter sweeps (bench_operators) that include 0.","commonSituations":"Window sweep configs including 0, converting external factor definitions with different window conventions, or arithmetic producing 0 on small inputs.","solutions":["Use n >= 1","Validate window lists before benchmarking","Clamp: max(1, n) when windows are computed"],"exampleFix":"// before\nts_argmin(df, 0)\n// after\nts_argmin(df, 1)","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":["Filter benchmark window sweeps","Document window conventions in factor specs"],"tags":["rolling-window","argmin","bottleneck"],"backgroundTag":"invalid-window-size","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}