HKUDS/Vibe-Trading · error · ValueError

no asset has both a finite value and a positive market cap

Error message

no asset has both a finite value and a positive market cap

What it means

With market_caps given, standardise_exposures computes a cap-weighted mean as the centring constant; if no asset simultaneously has a finite characteristic value and a strictly positive cap, that weighted mean is undefined and this error is raised.

Source

Thrown at agent/src/quantlib/factormodel.py:296

    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:
        caps = pd.Series(market_caps, dtype=float)
        missing = series.index.difference(caps.index)
        if len(missing):
            raise ValueError(
                f"market_caps is missing {len(missing)} asset(s) present in values"
            )
        aligned_caps = caps.reindex(clipped.index)
        usable = clipped.notna() & aligned_caps.notna() & (aligned_caps > 0)
        if not usable.any():
            raise ValueError("no asset has both a finite value and a positive market cap")
        weights = aligned_caps[usable]
        centre = float((clipped[usable] * weights).sum() / weights.sum())

    spread = float(clipped.dropna().std(ddof=1))
    if not np.isfinite(spread) or spread <= 0.0:
        raise ValueError(
            "the characteristic has no cross-sectional variation, so a z-score "
            "would divide by zero"
        )
    return (clipped - centre) / spread


def build_style_exposures(
    characteristics: pd.DataFrame,
    market_caps: pd.Series | None = None,
    definitions: Mapping[str, Mapping[str, int]] = STYLE_FACTOR_DEFINITIONS,
    winsorise: float = DEFAULT_WINSORISE,
) -> tuple[pd.DataFrame, dict[str, int]]:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Inspect the usable mask: usable = values.notna() & caps.notna() & (caps > 0); print(usable.sum()).
  2. Fix cap units/zeros (floor small caps at a positive epsilon) or repair NaN coverage so the intersection is non-empty.

Example fix

# before
z = standardise_exposures(values, market_caps=caps)  # caps has zeros
# after
caps = caps.where(caps > 0, 1.0)  # floor zero/NaN caps at 1 (equal weight)
z = standardise_exposures(values, market_caps=caps)
Defensive patterns

Strategy: validation

Validate before calling

usable = values.notna() & caps.notna() & (caps > 0)
assert usable.any()

Prevention

When it happens

Trigger: All caps NaN/zero for the assets with finite values — e.g. caps expressed in thousands so tiny values round to zero, or NaN characteristic exactly where caps exist, producing an empty usable set.

Common situations: Unit mismatch (caps in millions vs raw counts with zeros), stale caps files with NaNs, or characteristics whose coverage does not overlap the capped universe at all.

Related errors


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