HKUDS/Vibe-Trading · error · ValueError

equity must be 1-D, got shape {array.shape}

Error message

equity must be 1-D, got shape {array.shape}

What it means

drawdown_series requires a 1-D equity curve. A 2-D array would be ambiguous (which column is the curve?), and flattening it would concatenate unrelated paths into a nonsense equity series, so non-1-D input is rejected up front.

Source

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


def drawdown_series(equity: pd.Series | np.ndarray | Sequence[float]) -> pd.Series:
    """Compute continuous percentage drawdown from running peak as a positive loss fraction.

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

    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:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Select a single column as a Series: df['equity'] not df[['equity']]
  2. For arrays, use paths[i] to pass one path
  3. Pass a pd.Series directly with your index intact

Example fix

// before
dd = drawdown_series(df[["equity"]])
// after
dd = drawdown_series(df["equity"])
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np, pandas as pd
eq = df["equity"] if isinstance(df, pd.DataFrame) else equity
assert np.asarray(eq, dtype=float).ndim <= 1

Type guard

import numpy as np
import pandas as pd

def is_1d_equity(x) -> bool:
    if isinstance(x, pd.Series):
        return True
    return np.asarray(x, dtype=float).ndim <= 1

Try / catch

try:
    dd = drawdown_series(equity)
except ValueError as e:
    if "must be 1-D" in str(e):
        dd = drawdown_series(np.asarray(equity).ravel())
    else:
        raise

Prevention

When it happens

Trigger: drawdown_series(np.array([[100,110],[99,105]])), or passing a DataFrame (which np.asarray converts to 2-D) instead of a Series or single column.

Common situations: Selecting a DataFrame column with double brackets df[["equity"]] (yields a DataFrame, not a Series); passing a matrix of Monte Carlo paths where one path was intended.

Related errors


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