HKUDS/Vibe-Trading · error · ValueError

breaches must be 1-D, got shape {flags.shape}

Error message

breaches must be 1-D, got shape {flags.shape}

What it means

christoffersen_independence requires breaches to be a 1-D sequence of boolean breach flags because it computes lag-1 transition counts between consecutive observations. A 2-D array (e.g. shape (n, 1) from a DataFrame column reshape) has no well-defined 'previous' element, so it is rejected.

Source

Thrown at agent/src/quantlib/var_backtest.py:430

        breaches: Boolean sequence in chronological order, True on breach days.
        significance: Level at which ``rejected`` is decided.

    Returns:
        An :class:`IndependenceResult`. When the sample holds no breach, or
        holds breaches only in its final position, the transition probabilities
        are not separately identified; the statistic is then 0 with
        ``identified=False`` rather than an arbitrary number.

    Raises:
        ValueError: If ``breaches`` holds fewer than two observations or is not
            1-D, or if ``significance`` is not strictly between 0 and 1.
    """
    if not 0.0 < significance < 1.0:
        raise ValueError(f"significance must be in (0, 1), got {significance}")

    flags = np.asarray(breaches)
    if flags.ndim != 1:
        raise ValueError(f"breaches must be 1-D, got shape {flags.shape}")
    if flags.size < 2:
        raise ValueError(
            f"breaches needs at least 2 observations to hold a transition, got {flags.size}"
        )
    flags = flags.astype(bool)

    prev, curr = flags[:-1], flags[1:]
    n00 = int(np.sum(~prev & ~curr))
    n01 = int(np.sum(~prev & curr))
    n10 = int(np.sum(prev & ~curr))
    n11 = int(np.sum(prev & curr))

    from_calm = n00 + n01
    from_breach = n10 + n11
    total = from_calm + from_breach

    pi01 = n01 / from_calm if from_calm else 0.0
    pi11 = n11 / from_breach if from_breach else 0.0

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Pass a 1-D array or pandas Series: breaches = flags.ravel().
  2. Use df['breach'].to_numpy() (Series) rather than df[['breach']].to_numpy() (2-D).
  3. Loop over columns if you have breach flags for multiple VaR quantiles.

Example fix

# before
christoffersen_independence(df[['breach']].to_numpy())
# after
christoffersen_independence(df['breach'].to_numpy())
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
flags = np.asarray(breaches)
if flags.ndim != 1:
    flags = flags.ravel()
christoffersen_independence(flags, significance=0.05)

Type guard

def is_1d_flags(x) -> bool:
    import numpy as np
    return np.asarray(x).ndim == 1

Prevention

When it happens

Trigger: Passing np.array([[0],[1],[0]]), a 2-D array, or a pandas DataFrame (which converts to a 2-D ndarray) to christoffersen_independence, or to christoffersen_conditional_coverage/var_backtest which forward it.

Common situations: Feeding a single-column pandas DataFrame instead of a Series, or forgetting .ravel()/.flatten() after reshaping model output. Also passing a matrix of breach flags for multiple VaR levels at once.

Related errors


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