{"record":{"id":"1edb72157dfee26e","repo":"HKUDS/Vibe-Trading","slug":"the-characteristic-has-no-cross-sectional-variatio","errorCode":null,"errorMessage":"the characteristic has no cross-sectional variation, so a z-score would divide by zero","messagePattern":"the characteristic has no cross-sectional variation, so a z-score would divide by zero","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/factormodel.py","lineNumber":302,"sourceCode":"    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\"\n            )\n        aligned_caps = caps.reindex(clipped.index)\n        usable = clipped.notna() & aligned_caps.notna() & (aligned_caps > 0)\n        if not usable.any():\n            raise ValueError(\"no asset has both a finite value and a positive market cap\")\n        weights = aligned_caps[usable]\n        centre = float((clipped[usable] * weights).sum() / weights.sum())\n\n    spread = float(clipped.dropna().std(ddof=1))\n    if not np.isfinite(spread) or spread <= 0.0:\n        raise ValueError(\n            \"the characteristic has no cross-sectional variation, so a z-score \"\n            \"would divide by zero\"\n        )\n    return (clipped - centre) / spread\n\n\ndef build_style_exposures(\n    characteristics: pd.DataFrame,\n    market_caps: pd.Series | None = None,\n    definitions: Mapping[str, Mapping[str, int]] = STYLE_FACTOR_DEFINITIONS,\n    winsorise: float = DEFAULT_WINSORISE,\n) -> tuple[pd.DataFrame, dict[str, int]]:\n    \"\"\"Assemble a style exposure matrix from raw characteristics.\n\n    Args:\n        characteristics: Raw values, rows indexed by asset, one column per\n            characteristic named in ``definitions``. Columns a definition asks\n            for but the frame does not carry cause that factor to be skipped,","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/factormodel.py#L284-L320","documentation":"standardise_exposures z-scores by dividing by the cross-sectional standard deviation; if every finite (winsorised) value is identical the spread is zero and the z-score would divide by zero, so the library raises instead of returning inf/NaN exposures.","triggerScenarios":"A characteristic that is constant across the universe for a date — e.g. 'days since listing' filled with a placeholder, a categorical field encoded as the same number, or a column accidentally broadcast from a scalar.","commonSituations":"Data pipeline bugs that overwrite a column with one value, placeholder/fillna(0) columns, or genuinely degenerate cross-sections on illiquid dates.","solutions":["Check spread: values.dropna().std(); if 0, the characteristic carries no information for that date.","Fix the upstream column construction; if the column is legitimately constant, exclude that factor for the date rather than standardising it."],"exampleFix":"# before\nz = standardise_exposures(df['leverage'])  # all identical\n# after\nif df['leverage'].dropna().std(ddof=1) > 0:\n    z = standardise_exposures(df['leverage'])\nelse:\n    z = pd.Series(0.0, index=df.index)  # neutral placeholder, factor skipped","handlingStrategy":"validation","validationCode":"assert pd.Series(values).dropna().std(ddof=1) > 0","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Alert on constant columns in data-quality checks.","Exclude degenerate factors per date instead of standardising."],"tags":["factormodel","z-score","zero-variance"],"backgroundTag":"zero-variance-standardization","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}