HKUDS/Vibe-Trading · error · ValueError

the exposure matrix is collinear with the market factor or…

Error message

the exposure matrix is collinear with the market factor or with itself, so the coefficients are not identified

What it means

cross_sectional_factor_returns runs weighted least squares with an intercept; if the exposure matrix (after weighting) has rank below its column count — a constant exposure column is collinear with the intercept, or two factors are perfect multiples — the coefficients are not identified and the library raises instead of relying on lstsq's silent minimum-norm solution.

Solutions

  1. Check rank: np.linalg.matrix_rank(exposures.values) vs exposures.shape[1].
  2. Drop/merge duplicate or constant columns; ensure each factor uses a genuinely distinct characteristic.

Example fix

# before
fr = cross_sectional_factor_returns(returns, exposures)  # 'size' == 'log_size' duplicate
# after
exposures = exposures.drop(columns=["log_size"])
fr = cross_sectional_factor_returns(returns, exposures)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
assert np.linalg.matrix_rank(exposures.values) == exposures.shape[1]

Prevention

When it happens

Trigger: A standardisation bug leaving an all-ones/zeros column, two exposure columns built from the same underlying characteristic, or one factor expressed as an exact linear combination of others (e.g. size and log-size with a degenerate range).

Common situations: Definitions accidentally referencing the same column twice, exposures not centred so a nearly-constant column becomes exactly constant after rounding, or duplicated columns after a DataFrame join.

Related errors


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

Appendix: source

Thrown at agent/src/quantlib/factormodel.py:443

    if market_caps is None:
        weights = np.ones(len(common))
    else:
        caps = pd.Series(market_caps, dtype=float).reindex(common)
        if caps.isna().any() or (caps <= 0).any():
            raise ValueError(
                "market_caps must be positive and defined for every asset in the "
                "regression"
            )
        weights = np.sqrt(caps.to_numpy(dtype=float))

    sqrt_w = np.sqrt(weights)
    design_w = design * sqrt_w[:, None]
    y_w = y * sqrt_w

    rank = np.linalg.matrix_rank(design_w)
    if rank < design_w.shape[1]:
        raise ValueError(
            "the exposure matrix is collinear with the market factor or with "
            "itself, so the coefficients are not identified"
        )

    coefficients, *_ = np.linalg.lstsq(design_w, y_w, rcond=None)
    fitted = design @ coefficients
    residuals = y - fitted

    dof = len(common) - design.shape[1]
    weighted_residuals = y_w - design_w @ coefficients
    sigma_squared = float(weighted_residuals @ weighted_residuals / dof) if dof > 0 else np.nan
    try:
        covariance = sigma_squared * np.linalg.inv(design_w.T @ design_w)
        standard_errors = np.sqrt(np.diag(covariance))
    except np.linalg.LinAlgError:  # pragma: no cover - guarded by the rank check
        standard_errors = np.full(design.shape[1], np.nan)

    with np.errstate(divide="ignore", invalid="ignore"):

View on GitHub (pinned to 80ffdda44c)