HKUDS/Vibe-Trading · error · ValueError

ts_argmin window must be >= 1, got {n}

Error message

ts_argmin window must be >= 1, got {n}

What it means

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.

Source

Thrown at agent/src/factors/base.py:246

    if n < 1:
        raise ValueError(f"ts_argmax window must be >= 1, got {n}")
    if HAS_BOTTLENECK:
        arr = df.to_numpy(dtype=np.float64)
        raw = bn.move_argmax(arr, window=n, min_count=n, axis=0)
        corrected = (n - 1) - raw
        return pd.DataFrame(corrected, index=df.index, columns=df.columns)
    return df.rolling(window=n, min_periods=n).apply(_argmax_last, raw=True)


def ts_argmin(df: pd.DataFrame, n: int) -> pd.DataFrame:
    """Rolling argmin (0-based index into the window), warmup → NaN.

    Uses ``bottleneck.move_argmin`` when available (~350x faster).
    Correction: ``bn.move_argmin`` returns distance from window end,
    so we convert via ``(n - 1) - bn_result`` to get 0-based index from start.
    """
    if n < 1:
        raise ValueError(f"ts_argmin window must be >= 1, got {n}")
    if HAS_BOTTLENECK:
        arr = df.to_numpy(dtype=np.float64)
        raw = bn.move_argmin(arr, window=n, min_count=n, axis=0)
        corrected = (n - 1) - raw
        return pd.DataFrame(corrected, index=df.index, columns=df.columns)
    return df.rolling(window=n, min_periods=n).apply(_argmin_last, raw=True)


def delta(df: pd.DataFrame, d: int) -> pd.DataFrame:
    """First difference at lag ``d``: ``df - df.shift(d)``.

    Lookahead ban: ``d >= 1`` strictly. Negative lag forbidden.
    """
    if d < 1:
        raise ValueError(f"delta lag must be >= 1 (lookahead ban), got {d}")
    return df - df.shift(d)

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Use n >= 1
  2. Validate window lists before benchmarking
  3. Clamp: max(1, n) when windows are computed

Example fix

// before
ts_argmin(df, 0)
// after
ts_argmin(df, 1)
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(n, int) or n < 1: raise ValueError(f'window must be int >= 1, got {n!r}')

Type guard

def is_valid_window(n: object) -> bool:
    return isinstance(n, int) and not isinstance(n, bool) and n >= 1

Prevention

When it happens

Trigger: Calling ts_argmin(df, 0) or with a negative window, or parameter sweeps (bench_operators) that include 0.

Common situations: Window sweep configs including 0, converting external factor definitions with different window conventions, or arithmetic producing 0 on small inputs.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/79bbe3012b239e09. Report an issue: GitHub.