HKUDS/Vibe-Trading · error · ValueError
{design.shape[1]} regressors but only {design.shape[0]} asse
Error message
{design.shape[1]} regressors but only {design.shape[0]} assets; the fit would be exactly determined and meaningless What it means
The Fama-MacBeth design matrix includes an intercept (the market factor) plus one column per exposure; if the number of regressors exceeds the number of assets, the OLS fit would be exactly determined (zero residual degrees of freedom) and the 'factor returns' would be meaningless interpolation, so it is rejected.
Source
Thrown at agent/src/quantlib/factormodel.py:421
the inputs, if the design matrix has more columns than rows, or if
the exposures are perfectly collinear.
"""
common = returns.dropna().index.intersection(exposures.dropna(how="any").index)
if len(common) < MIN_CROSS_SECTION:
raise ValueError(
f"cross-sectional regression needs at least {MIN_CROSS_SECTION} assets "
f"with both a return and full exposures, got {len(common)}"
)
y = returns.loc[common].to_numpy(dtype=float)
factor_names = list(exposures.columns)
design = np.column_stack(
[np.ones(len(common)), exposures.loc[common].to_numpy(dtype=float)]
)
names = [MARKET_FACTOR, *factor_names]
if design.shape[1] > design.shape[0]:
raise ValueError(
f"{design.shape[1]} regressors but only {design.shape[0]} assets; "
"the fit would be exactly determined and meaningless"
)
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_wView on GitHub (pinned to 80ffdda44c)
Solutions
- Reduce the number of factors (subset the exposure columns) or enlarge the universe so assets >= factors + 1.
- Check that exposures wasn't accidentally transposed (factors as rows).
Example fix
# before fr = cross_sectional_factor_returns(returns, exposures) # 20 cols, 12 assets # after keep = ["value", "momentum", "size"] fr = cross_sectional_factor_returns(returns, exposures[keep])
Defensive patterns
Strategy: validation
Validate before calling
assert exposures.shape[1] + 1 <= returns.dropna().index.intersection(exposures.dropna(how='any').index).size
Prevention
- Scale the factor set to the universe size.
- Guard against accidentally transposed exposure frames.
When it happens
Trigger: More style factors than assets in the cross-section — e.g. 20 factor columns but only 12 stocks passing the completeness filter, common when a broad definition set meets a small pilot universe.
Common situations: Running the full style definition set on a narrow universe or a single sector, or after the complete-row filter in error 576 slashes the sample.
Related errors
- the exposure matrix is collinear with the market factor or w
- winsorise must be in [0, 0.5), got {winsorise}
- a cross-section needs at least {MIN_CROSS_SECTION} finite va
- market_caps is missing {len(missing)} asset(s) present in va
- no asset has both a finite value and a positive market cap
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/5af6c94df08745f3.
Report an issue: GitHub.