{"record":{"id":"44c09f4ffc120ad0","repo":"HKUDS/Vibe-Trading","slug":"index-levels-has-no-entry-for-day-needed-for-f","errorCode":null,"errorMessage":"index_levels has no entry for {day} (needed for {flow_description}); forward-filling across the gap is not done automatically, because it would price a flow that lands inside a missing stretch against a level that was never actually observed on that date. Supply an index level for every cash-flow date this calculation touches.","messagePattern":"index_levels has no entry for (.+?) \\(needed for (.+?)\\); forward-filling across the gap is not done automatically, because it would price a flow that lands inside a missing stretch against a level that was never actually observed on that date\\. Supply an index level for every cash-flow date this calculation touches\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/fundmath.py","lineNumber":1415,"sourceCode":"    Args:\n        lookup: Table built by :func:`_index_levels_by_date`.\n        day: Date to look up.\n        flow_description: Human-readable description of what needed this\n            date, quoted in the error message.\n\n    Returns:\n        The index level on ``day``.\n\n    Raises:\n        ValueError: If ``day`` has no entry. Forward-filling across the gap\n            is deliberately not attempted: a flow that lands inside a missing\n            stretch would then be discounted against a price that was never\n            actually observed on that date.\n    \"\"\"\n    try:\n        return lookup[day]\n    except KeyError as exc:\n        raise ValueError(\n            f\"index_levels has no entry for {day} (needed for {flow_description}); \"\n            \"forward-filling across the gap is not done automatically, because \"\n            \"it would price a flow that lands inside a missing stretch against \"\n            \"a level that was never actually observed on that date. Supply an \"\n            \"index level for every cash-flow date this calculation touches.\"\n        ) from exc\n\n\ndef _terminal_mark(series: CashFlowSeries) -> CashFlow | None:\n    \"\"\"The most recent valuation record in a series, if any.\n\n    Selects the same record :func:`residual_value` would report the amount\n    of, but also returns the record itself so its date is available -- which\n    :func:`residual_value` has no reason to expose, but the PME functions\n    need in order to look up an index level for it.\n\n    Args:\n        series: The cash flows.","sourceCodeStart":1397,"sourceCodeEnd":1433,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/fundmath.py#L1397-L1433","documentation":"The PME lookup needs a benchmark level on (or resolvable to) an exact cash-flow date, and none was found. The library deliberately does not forward-fill across gaps, because that would price a flow against a level never actually observed on that date — so the caller must supply levels for every touched date.","triggerScenarios":"Calling ks_pme/pme_plus/direct_alpha when a contribution or distribution falls on a weekend/holiday absent from the benchmark index, or when the benchmark date range starts after the first flow.","commonSituations":"Fund cash flows on month-ends that are weekends; benchmark starting later than the fund's first draw; trading-day benchmark vs calendar-day flows.","solutions":["Reindex the benchmark to all flow dates and forward-fill explicitly yourself: levels = levels.reindex(all_dates, method='ffill') — making the interpolation policy your explicit choice","Extend the benchmark history to cover the first cash-flow date","Shift flows to the nearest observed benchmark date if your methodology allows"],"exampleFix":"# before\nks_pme(series, daily_close)  # flow on Saturday -> KeyError -> ValueError\n\n# after\nall_dates = sorted(series.dates())\nlevels = daily_close.reindex(pd.to_datetime(all_dates), method=\"ffill\")\nks_pme(series, levels)","handlingStrategy":"fallback","validationCode":"all_dates = sorted(series.dates())\nmissing = [d for d in all_dates if pd.Timestamp(d).normalize() not in set(levels.index.normalize())]\nif missing:\n    levels = levels.reindex(pd.to_datetime(all_dates), method=\"ffill\")  # explicit policy","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reindex the benchmark onto all flow dates with an explicit fill policy before calling","Prefer benchmarks whose history starts before the first cash flow","Document your weekend/holiday interpolation convention"],"tags":["fund-math","pme","missing-data","date-alignment"],"backgroundTag":"missing-benchmark-data","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}