{"record":{"id":"459067b673825bf5","repo":"HKUDS/Vibe-Trading","slug":"index-levels-is-empty-a-public-market-equivalent","errorCode":null,"errorMessage":"index_levels is empty; a public market equivalent needs a benchmark to compare against","messagePattern":"index_levels is empty; a public market equivalent needs a benchmark to compare against","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/fundmath.py","lineNumber":1369,"sourceCode":"            the index's level on each date (a price or a total-return index\n            value, not a return).\n\n    Returns:\n        Mapping from ``datetime.date`` to the index level on that date.\n\n    Raises:\n        TypeError: If ``index_levels`` is not a ``pandas.Series``.\n        ValueError: If it is empty, a level is not finite and positive, or two\n            entries normalize to the same date (an ambiguous lookup, refused\n            rather than guessed at by taking the first or last).\n    \"\"\"\n    if not isinstance(index_levels, pd.Series):\n        raise TypeError(\n            \"index_levels must be a pandas Series of index levels indexed by \"\n            f\"date, got {type(index_levels).__name__}\"\n        )\n    if index_levels.empty:\n        raise ValueError(\n            \"index_levels is empty; a public market equivalent needs a \"\n            \"benchmark to compare against\"\n        )\n    lookup: dict[_dt.date, float] = {}\n    for raw_date, raw_level in index_levels.items():\n        day = normalize_date(raw_date, field_name=\"index_levels date\")\n        if day in lookup:\n            raise ValueError(\n                f\"index_levels has more than one entry for {day}; resolve the \"\n                \"duplicate before calling, rather than have this function \"\n                \"guess which one is authoritative\"\n            )\n        level = float(raw_level)\n        if not math.isfinite(level) or level <= 0.0:\n            raise ValueError(\n                f\"index level on {day} is {raw_level!r}; index levels must be \"\n                \"finite and positive to serve as a growth-factor denominator\"\n            )","sourceCodeStart":1351,"sourceCodeEnd":1387,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/fundmath.py#L1351-L1387","documentation":"A public-market-equivalent calculation needs at least one benchmark level to compute growth factors against; an empty index_levels Series is refused rather than producing NaN results.","triggerScenarios":"Calling ks_pme/pme_plus/direct_alpha with index_levels=pd.Series(dtype=float) — e.g. a benchmark query whose date filter matched nothing.","commonSituations":"Ticker symbol typo yielding an empty download; date-range filter that excludes all rows; empty CSV; upstream API returning zero rows.","solutions":["Inspect why the benchmark series is empty (symbol, date range, filter)","Widen the date range to cover all cash-flow dates","Skip the PME calc for assets with no benchmark data rather than calling it"],"exampleFix":"# before\nlevels = bench[bench.index >= \"2025-01-01\"][\"close\"]  # empty if data ends 2024\nks_pme(series, levels)\n\n# after\nlevels = bench[\"close\"].dropna()\nif not levels.empty:\n    ks_pme(series, levels)","handlingStrategy":"validation","validationCode":"if index_levels.empty:\n    raise DataAvailabilityError(\"benchmark series is empty\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate benchmark downloads for non-emptiness at ingest","Alert on zero-row vendor responses"],"tags":["fund-math","pme","empty-data","benchmark"],"backgroundTag":"empty-dataset","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}