HKUDS/Vibe-Trading · error · ValueError
ts_rank window must be >= 1, got {n}
Error message
ts_rank window must be >= 1, got {n} What it means
ts_rank validates its rolling window n and requires n >= 1; smaller values (0 or negatives) raise immediately. A window of 1 is meaningful here (the single value is its own rank). The function uses numpy sliding_window_view for speed, with warmup positions returning NaN.
Source
Thrown at agent/src/factors/base.py:104
"""
df = _as_float(df)
abs_sum = df.abs().sum(axis=1, skipna=True)
abs_sum = abs_sum.where(abs_sum > 0) # zero → NaN
return df.mul(a).div(abs_sum, axis=0)
def ts_rank(df: pd.DataFrame, n: int) -> pd.DataFrame:
"""Rolling rank (last value's rank within the n-window), per column.
Warmup (first ``n-1`` rows per column) returns NaN. Result is a percentile
in [0, 1] so it is compositionally compatible with cross-sectional rank.
Uses numpy ``sliding_window_view`` for vectorized computation (~45x faster
than pandas rolling().apply()). Note: ``bottleneck.move_rank`` computes
Spearman rank correlation, not percentile rank, so it is not used here.
"""
if n < 1:
raise ValueError(f"ts_rank window must be >= 1, got {n}")
def _last_rank(arr: np.ndarray) -> float:
if np.isnan(arr).all():
return np.nan
last = arr[-1]
if np.isnan(last):
return np.nan
valid = arr[~np.isnan(arr)]
if valid.size == 0:
return np.nan
# average rank for ties; pct
less = (valid < last).sum()
eq = (valid == last).sum()
rank_avg = less + 0.5 * (eq + 1)
return float(rank_avg / valid.size)
arr = df.to_numpy(dtype=np.float64)
T, C = arr.shapeView on GitHub (pinned to 80ffdda44c)
Solutions
- Pass a positive integer window (>= 1)
- Validate/clamp computed windows: n = max(1, n) only if that is semantically correct, otherwise raise early with context
- Check config values for window parameters before running the factor pipeline
Example fix
# before out = ts_rank(df, n=0) # after out = ts_rank(df, n=20)
Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(n, int) or n < 1:
raise ValueError(f'invalid ts_rank window: {n!r}')
out = ts_rank(df, n) Type guard
def is_valid_ts_rank_window(n) -> bool:
return isinstance(n, int) and n >= 1 Prevention
- Validate all window configs once at startup
- Floor auto-scaled windows to the operator minimum (with an explicit policy)
- Boundary-test operators with n at and below the minimum
When it happens
Trigger: ts_rank(df, 0), ts_rank(df, -5), or a computed window that evaluates to 0, e.g. n = len(df) - lookback with lookback == len(df). Called from compute() in factor pipelines and directly in tests.
Common situations: Config-driven window sizes where a parameter is unset and defaults to 0; dynamic windows derived from data length that underflow on short series; passing a percentage (0.05) instead of a count.
Related errors
- ts_corr window must be >= 2, got {n}
- ts_cov window must be >= 2, got {n}
- ts_mean window must be >= 1, got {n}
- ts_std window must be >= 2, got {n}
- granger_test needs max_lag >= 1, got {max_lag}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/e8057c1621a1e748.
Report an issue: GitHub.