HKUDS/Vibe-Trading · error · ValueError

index_levels has no entry for {day} (needed for {flow_descri

Error message

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.

What it means

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.

Source

Thrown at agent/src/quantlib/fundmath.py:1415

    Args:
        lookup: Table built by :func:`_index_levels_by_date`.
        day: Date to look up.
        flow_description: Human-readable description of what needed this
            date, quoted in the error message.

    Returns:
        The index level on ``day``.

    Raises:
        ValueError: If ``day`` has no entry. Forward-filling across the gap
            is deliberately not attempted: a flow that lands inside a missing
            stretch would then be discounted against a price that was never
            actually observed on that date.
    """
    try:
        return lookup[day]
    except KeyError as exc:
        raise ValueError(
            f"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."
        ) from exc


def _terminal_mark(series: CashFlowSeries) -> CashFlow | None:
    """The most recent valuation record in a series, if any.

    Selects the same record :func:`residual_value` would report the amount
    of, but also returns the record itself so its date is available -- which
    :func:`residual_value` has no reason to expose, but the PME functions
    need in order to look up an index level for it.

    Args:
        series: The cash flows.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. 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
  2. Extend the benchmark history to cover the first cash-flow date
  3. Shift flows to the nearest observed benchmark date if your methodology allows

Example fix

# before
ks_pme(series, daily_close)  # flow on Saturday -> KeyError -> ValueError

# after
all_dates = sorted(series.dates())
levels = daily_close.reindex(pd.to_datetime(all_dates), method="ffill")
ks_pme(series, levels)
Defensive patterns

Strategy: fallback

Validate before calling

all_dates = sorted(series.dates())
missing = [d for d in all_dates if pd.Timestamp(d).normalize() not in set(levels.index.normalize())]
if missing:
    levels = levels.reindex(pd.to_datetime(all_dates), method="ffill")  # explicit policy

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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