HKUDS/Vibe-Trading · error · ValueError
winsorise must be in [0, 0.5), got {winsorise}
Error message
winsorise must be in [0, 0.5), got {winsorise} What it means
standardise_exposures winsorises the cross-section at the given tail fraction before z-scoring; a fraction of 0.5 or more would clip away the entire distribution (and negative values are meaningless), so winsorise must lie in [0, 0.5).
Source
Thrown at agent/src/quantlib/factormodel.py:268
Args:
values: Raw characteristic, indexed by asset. NaN entries survive as NaN
and are the caller's to fill (:func:`build_style_exposures` fills
them with zero and counts them).
market_caps: Market capitalisation on the same index, used for the mean.
When None, the mean is equal-weighted.
winsorise: Fraction trimmed from each tail, in ``[0, 0.5)``.
Returns:
Standardised exposures on the input index.
Raises:
ValueError: If ``winsorise`` is outside ``[0, 0.5)``, if fewer than
:data:`MIN_CROSS_SECTION` finite values are present, or if
``market_caps`` does not cover the same index.
"""
if not 0.0 <= winsorise < 0.5:
raise ValueError(f"winsorise must be in [0, 0.5), got {winsorise}")
series = pd.Series(values, dtype=float)
finite = series.dropna()
if finite.size < MIN_CROSS_SECTION:
raise ValueError(
f"a cross-section needs at least {MIN_CROSS_SECTION} finite values to "
f"standardise, got {finite.size}"
)
if winsorise > 0:
lower, upper = finite.quantile(winsorise), finite.quantile(1.0 - winsorise)
clipped = series.clip(lower=lower, upper=upper)
else:
clipped = series
if market_caps is None:
centre = float(clipped.dropna().mean())
else:View on GitHub (pinned to 80ffdda44c)
Solutions
- Use a per-tail fraction strictly below 0.5, e.g. winsorise=0.01 clips 1% from each tail.
- If your config stores a two-tailed total, halve it: winsorise=cfg_value / 2.
Example fix
# before expo = standardise_exposures(values, winsorise=0.02) # meant 2% total # after expo = standardise_exposures(values, winsorise=0.01) # 1% per tail
Defensive patterns
Strategy: validation
Validate before calling
assert 0.0 <= winsorise < 0.5
Type guard
def is_valid_winsorise(w: float) -> bool:
return isinstance(w, (int, float)) and 0.0 <= w < 0.5 Prevention
- Document per-tail semantics in config comments.
- Halve two-tailed fractions coming from other tools.
When it happens
Trigger: Passing winsorise=0.5, 1.0, or a negative number; commonly from a config that expresses the winsorisation as total two-tailed fraction (e.g. 0.02 meaning 1% per tail gets doubled).
Common situations: Porting winsorisation settings from another library with a different convention (per-tail vs both-tails), YAML config typos, or parameters derived from percentile tuples.
Related errors
- n_folds must be at least {MIN_FOLDS}, got {n_folds}
- {n_samples} samples cannot make {n_folds} folds
- embargo_fraction must be in [0, 1), got {embargo_fraction}
- event_window start must be <= end, got {event_window}
- estimation_gap must be >= 0, got {estimation_gap}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/b6d282774a289446.
Report an issue: GitHub.