{"record":{"id":"92ef3299ecf0112f","repo":"HKUDS/Vibe-Trading","slug":"a-cross-section-needs-at-least-min-cross-section","errorCode":null,"errorMessage":"a cross-section needs at least {MIN_CROSS_SECTION} finite values to standardise, got {finite.size}","messagePattern":"a cross-section needs at least (.+?) finite values to standardise, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/factormodel.py","lineNumber":273,"sourceCode":"        market_caps: Market capitalisation on the same index, used for the mean.\n            When None, the mean is equal-weighted.\n        winsorise: Fraction trimmed from each tail, in ``[0, 0.5)``.\n\n    Returns:\n        Standardised exposures on the input index.\n\n    Raises:\n        ValueError: If ``winsorise`` is outside ``[0, 0.5)``, if fewer than\n            :data:`MIN_CROSS_SECTION` finite values are present, or if\n            ``market_caps`` does not cover the same index.\n    \"\"\"\n    if not 0.0 <= winsorise < 0.5:\n        raise ValueError(f\"winsorise must be in [0, 0.5), got {winsorise}\")\n\n    series = pd.Series(values, dtype=float)\n    finite = series.dropna()\n    if finite.size < MIN_CROSS_SECTION:\n        raise ValueError(\n            f\"a cross-section needs at least {MIN_CROSS_SECTION} finite values to \"\n            f\"standardise, got {finite.size}\"\n        )\n\n    if winsorise > 0:\n        lower, upper = finite.quantile(winsorise), finite.quantile(1.0 - winsorise)\n        clipped = series.clip(lower=lower, upper=upper)\n    else:\n        clipped = series\n\n    if market_caps is None:\n        centre = float(clipped.dropna().mean())\n    else:\n        caps = pd.Series(market_caps, dtype=float)\n        missing = series.index.difference(caps.index)\n        if len(missing):\n            raise ValueError(\n                f\"market_caps is missing {len(missing)} asset(s) present in values\"","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/factormodel.py#L255-L291","documentation":"standardise_exposures needs at least MIN_CROSS_SECTION finite values in the cross-section to compute a meaningful dispersion for z-scoring; with fewer names the standard deviation estimate is too noisy to be a useful exposure.","triggerScenarios":"Calling with a values array/Series containing fewer than MIN_CROSS_SECTION non-NaN entries — e.g. a universe of 5 stocks, or heavy NaN coverage from a sparse characteristic.","commonSituations":"Small pilot universes, point-in-time data where a characteristic only covers large caps, or filtering steps that shrink the cross-section below the floor.","solutions":["Count finite values first: s = pd.Series(values); s.notna().sum().","Widen the universe or use a characteristic with better coverage; drop the factor for dates where coverage is below the floor."],"exampleFix":"# before\nz = standardise_exposures(char_values)  # only 8 finite\n# after\nif char_values.dropna().size >= MIN_CROSS_SECTION:\n    z = standardise_exposures(char_values)\nelse:\n    z = None  # skip factor for this date","handlingStrategy":"validation","validationCode":"from quantlib.factormodel import MIN_CROSS_SECTION\nassert pd.Series(values).dropna().size >= MIN_CROSS_SECTION","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track characteristic coverage per date; skip thin dates.","Pre-filter the universe to names with the characteristic."],"tags":["factormodel","minimum-sample","cross-section"],"backgroundTag":"insufficient-data-validation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}