HKUDS/Vibe-Trading · error · ValueError

latest valuation on {marks[-1].date} is {value!r}; a residua

Error message

latest valuation on {marks[-1].date} is {value!r}; a residual value must be non-negative. If the vehicle really carries negative equity, record it under a custom kind and compute the multiple explicitly.

What it means

The fund-math residual_value helper takes the last valuation mark in the cash-flow series as the residual (unrealized) value and refuses negative amounts. A negative latest mark would make RVPI/TVPI/MOIC misleading, so the library raises rather than silently producing a nonsensical multiple. Negative equity must be modeled explicitly by the caller.

Source

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

            ``residual_value``, ``valuation``).

    Returns:
        The latest mark's amount, or ``0.0`` when the series holds no mark --
        which is the right answer for a fully liquidated fund.

    Raises:
        TypeError: If ``series`` is not a ``CashFlowSeries``.
        ValueError: If the latest mark is negative. A negative NAV is possible
            in a levered vehicle but is never what a mis-signed file means, so
            it must be stated as a custom kind rather than inferred here.
    """
    _require_series(series)
    marks = [flow for flow in series if flow.is_valuation]
    if not marks:
        return 0.0
    value = marks[-1].amount
    if value < 0.0:
        raise ValueError(
            f"latest valuation on {marks[-1].date} is {value!r}; a residual "
            "value must be non-negative. If the vehicle really carries negative "
            "equity, record it under a custom kind and compute the multiple "
            "explicitly."
        )
    return value


def _require_paid_in(paid_in: float) -> float:
    """Reject a zero or negative denominator for a capital multiple.

    Args:
        paid_in: Paid-in capital as a positive magnitude.

    Returns:
        The same value.

    Raises:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Check the sign convention of your valuation records; NAV marks should be non-negative
  2. If the vehicle truly has negative equity, record it under a custom flow kind and compute the multiple manually instead of relying on residual_value
  3. Drop or correct the offending final valuation mark and re-run the multiple

Example fix

# before
series.append(Flow(date=d, amount=-250_000.0, kind="valuation"))
rvpi(series, paid_in=1_000_000.0)  # raises ValueError

# after
series.append(Flow(date=d, amount=0.0, kind="valuation"))
# negative equity tracked separately under a custom kind and handled explicitly
Defensive patterns

Strategy: validation

Validate before calling

latest = [f for f in series if f.is_valuation]
if latest and latest[-1].amount < 0:
    raise CustomDataError("negative final NAV; model explicitly")

Prevention

When it happens

Trigger: Calling rvpi, tvpi, moic, fund_multiples, european_waterfall, or ks_pme on a CashFlowSeries whose most recent is_valuation flow has amount < 0 (e.g. a final mark of -1_000_000).

Common situations: Loading a NAV file where the final period shows negative equity (liabilities exceed assets), or a sign-convention mistake where outflows were recorded as negative valuations instead of negative contributions.

Related errors


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