HKUDS/Vibe-Trading · error · ValueError

paths must be 2-D with >= 2 columns, got shape {matrix.shape

Error message

paths must be 2-D with >= 2 columns, got shape {matrix.shape}

What it means

analyze_mc_results expects a 2-D matrix of simulated paths where each row is a path and column 0 is the starting price; it computes terminal returns as matrix[:, -1]/matrix[:, 0] - 1. Fewer than 2 columns means there is no terminal point distinct from the start, so no return exists; 1-D or 3-D input is likewise rejected.

Source

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

    Returns:
        dict with keys:
            mean_return, median_return, std_return (float): Signed total
                returns over the simulation, so a bad outcome is negative.
            var, cvar (float): Positive loss magnitudes, computed with the same
                order-statistic convention as ``historical_var`` /
                ``historical_cvar``, so ``cvar >= var``.
            prob_loss (float): Fraction of paths ending below their start.
            worst_5pct_return, best_5pct_return (float): Signed 5th and 95th
                percentiles of the terminal return (linear interpolation).

    Raises:
        ValueError: If ``paths`` is not 2-D with at least two columns, holds a
            non-positive starting price, or ``confidence`` is outside (0, 1).
    """
    _validate_confidence(confidence)
    matrix = np.asarray(paths, dtype=float)
    if matrix.ndim != 2 or matrix.shape[1] < 2:
        raise ValueError(f"paths must be 2-D with >= 2 columns, got shape {matrix.shape}")
    start = matrix[:, 0]
    if (start <= 0.0).any():
        raise ValueError("paths column 0 (the starting price) must be strictly positive")

    returns = matrix[:, -1] / start - 1.0
    return {
        "mean_return": float(np.mean(returns)),
        "median_return": float(np.median(returns)),
        "std_return": float(np.std(returns, ddof=1)) if returns.size > 1 else 0.0,
        "var": historical_var(returns, confidence),
        "cvar": historical_cvar(returns, confidence),
        "prob_loss": float(np.mean(returns < 0.0)),
        "worst_5pct_return": float(np.percentile(returns, 5.0)),
        "best_5pct_return": float(np.percentile(returns, 95.0)),
    }


def fit_gpd_tail(

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Ensure shape is (n_paths, n_steps+1) with column 0 = s0 (as monte_carlo_gbm returns)
  2. Add a batch dimension for one path: path[None, :]
  3. Do not flatten the matrix; check matrix.ndim == 2 and shape[1] >= 2 before calling

Example fix

// before
stats = analyze_mc_results(single_path)  # 1-D
// after
stats = analyze_mc_results(single_path[None, :])  # shape (1, n+1), s0 in col 0
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np
m = np.asarray(paths, dtype=float)
assert m.ndim == 2 and m.shape[1] >= 2, f"need (n_paths, n_steps+1), got {m.shape}"

Type guard

import numpy as np

def is_valid_path_matrix(x) -> bool:
    m = np.asarray(x, dtype=float)
    return m.ndim == 2 and m.shape[1] >= 2

Try / catch

try:
    stats = analyze_mc_results(paths)
except ValueError as e:
    if "2-D with >= 2 columns" in str(e):
        stats = analyze_mc_results(np.atleast_2d(paths))
    else:
        raise

Prevention

When it happens

Trigger: analyze_mc_results(np.array([100, 105, 98])) (a single 1-D path), a matrix with shape (n, 1) (start only, no steps), or an (n, k, m) tensor.

Common situations: Analyzing one path instead of the batch (forgetting paths[None, :]); simulation returning paths without the s0 column; accidental .ravel() flattening the matrix before analysis.

Related errors


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