HKUDS/Vibe-Trading · error · ValueError

equity contains no finite observation

Error message

equity contains no finite observation

What it means

drawdown_series filters the equity input to finite values and raises if nothing remains — the input was empty or entirely NaN/inf. Drawdown percentages are meaningless without at least one valid equity point.

Source

Thrown at agent/src/quantlib/risk.py:278

    Returns:
        A pandas Series of drawdown fractions in ``[0.0, 1.0)`` where 0.0 means
        at peak and 0.25 means 25% below the running peak.

    Raises:
        ValueError: If ``equity`` is not 1-D, has no finite observations, or contains values <= 0.
    """
    if not isinstance(equity, pd.Series):
        array = np.asarray(equity, dtype=float)
        if array.ndim > 1:
            raise ValueError(f"equity must be 1-D, got shape {array.shape}")
        series = pd.Series(array)
    else:
        series = equity.copy()

    series = series.astype(float)
    series = series[np.isfinite(series.to_numpy())]
    if series.empty:
        raise ValueError("equity contains no finite observation")
    values = series.to_numpy()
    if (values <= 0.0).any():
        raise ValueError("equity must be strictly positive to express drawdown as a fraction")

    running_peak = np.maximum.accumulate(values)
    dd = -(values / running_peak - 1.0)  # non-negative loss fraction
    return pd.Series(dd, index=series.index, name="drawdown")


def ulcer_index(equity: pd.Series | np.ndarray | Sequence[float]) -> float:
    """Calculate Peter Martin's Ulcer Index measuring downside drawdown volatility.

    Ulcer Index is the root-mean-square percentage drawdown:
        UI = sqrt( (1/N) * sum( (DD_t)^2 ) )

    Args:
        equity: Net-value / equity series, strictly positive.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Verify the column name exists and the Series is non-empty before calling
  2. Drop NaNs upstream: equity = equity.dropna()
  3. Check the data-loading step (file path, sheet, column casing)

Example fix

// before
dd = drawdown_series(df["equity"])  # column missing -> all NaN
// after
if "equity" in df.columns and df["equity"].notna().any():
    dd = drawdown_series(df["equity"].dropna())
Defensive patterns

Strategy: validation

Validate before calling

s = pd.Series(equity).dropna()
assert not s.empty, "equity series is empty after dropna"
dd = drawdown_series(s)

Type guard

import numpy as np

def has_finite_equity(x) -> bool:
    return bool(np.isfinite(np.asarray(x, dtype=float).ravel()).any())

Try / catch

try:
    dd = drawdown_series(equity)
except ValueError as e:
    if "no finite observation" in str(e):
        dd = pd.Series(dtype=float)  # or skip this asset
    else:
        raise

Prevention

When it happens

Trigger: drawdown_series([]), drawdown_series([np.nan]*5), or a Series produced by a misaligned join that yields all NaN.

Common situations: Reading an equity column that doesn't exist in the CSV (all NaN), date-indexed data joined on mismatched timestamps, or an upstream simulation returning an empty result.

Related errors


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