HKUDS/Vibe-Trading · error · ValueError
need >= {min_bars} bars in each window (calm={len(calm)}, ev
Error message
need >= {min_bars} bars in each window (calm={len(calm)}, event={len(event)}) What it means
This rewiring-score function compares correlation matrices between a 'calm' window and an 'event' window. Correlation estimates are meaningless below a minimum sample size, so it requires at least min_bars rows in BOTH windows and reports the actual counts in the error. The masks are reindexed to returns.index with fill_value=False, so non-overlapping masks silently yield empty windows and trigger this.
Source
Thrown at agent/src/skills/correlation-regime/SKILL.md:396
Score = row mean of |Δρ| between the event-window correlation matrix and
the calm-baseline correlation matrix. High score = the asset's
relationship to the rest of the market changed the most.
Args:
returns: Multi-asset return matrix, columns are symbols
calm_mask: Boolean series marking calm-baseline bars
(e.g. ``regimes["fused"] == 0`` from Mode 1)
event_mask: Boolean series marking the episode under examination
min_bars: Minimum bars required in each window
Returns:
DataFrame indexed by symbol with ``rewiring_score``, sorted descending
"""
calm = returns.loc[calm_mask.reindex(returns.index, fill_value=False)]
event = returns.loc[event_mask.reindex(returns.index, fill_value=False)]
if len(calm) < min_bars or len(event) < min_bars:
raise ValueError(
f"need >= {min_bars} bars in each window "
f"(calm={len(calm)}, event={len(event)})"
)
delta = (event.corr() - calm.corr()).abs()
matrix = delta.to_numpy(copy=True) # copy: DataFrame internals may be read-only
np.fill_diagonal(matrix, np.nan)
scores = pd.Series(np.nanmean(matrix, axis=1), index=delta.index)
return scores.sort_values(ascending=False).to_frame("rewiring_score")
```
---
## Dependencies
```bash
pip install pandas numpy
```View on GitHub (pinned to 80ffdda44c)
Solutions
- Lower min_bars if statistically acceptable for your window sizes
- Extend the data range so both calm and event windows contain >= min_bars bars
- Verify mask alignment: print calm_mask.index.equals(returns.index) and the sum of True values in each mask
- Rebuild masks on returns.index (e.g. calm_mask = calm_mask.reindex(returns.index, fill_value=False)) and confirm they actually label different regimes
Example fix
# before rewiring = rewiring_scores(returns, calm_mask, event_mask, min_bars=60) # event regime has only 20 bars # after print(calm_mask.sum(), event_mask.sum()) # inspect coverage rewiring = rewiring_scores(returns, calm_mask, event_mask, min_bars=min(20, int(event_mask.sum())))
Defensive patterns
Strategy: validation
Validate before calling
def masks_have_min_bars(returns, calm_mask, event_mask, min_bars: int) -> bool:
calm = returns.loc[calm_mask.reindex(returns.index, fill_value=False)]
event = returns.loc[event_mask.reindex(returns.index, fill_value=False)]
return len(calm) >= min_bars and len(event) >= min_bars
def bars_available(returns, calm_mask, event_mask, min_bars: int):
calm_n = int(calm_mask.reindex(returns.index, fill_value=False).sum())
event_n = int(event_mask.reindex(returns.index, fill_value=False).sum())
return {"calm": calm_n, "event": event_n} Type guard
null
Try / catch
try:
scores = rewiring_scores(returns, calm_mask, event_mask, min_bars=min_bars)
except ValueError as e:
if "need >=" in str(e):
skip_symbol(symbol, reason="insufficient bars")
else:
raise Prevention
- Assert calm_mask.index.equals(returns.index) before calling
- Check mask coverage (sum of True) per regime before analysis
- Scale min_bars to your data frequency and window construction
- Localize/timezone-normalize all DatetimeIndexes consistently
When it happens
Trigger: Calling with calm_mask/event_mask boolean Series whose True entries don't align with returns.index (different dates/timezones), a dataset shorter than 2*min_bars rows, or regime masks that select fewer than min_bars bars (e.g. an event regime lasting only 10 bars with min_bars=30).
Common situations: Masks built on a different date range than the returns frame, timezone-naive vs timezone-aware indexes failing to align, min_bars defaults tuned for daily data used on sparse intraday windows, or a short backtest dataset.
Related errors
- market_returns is missing {len(missing_market)} label(s) pre
- market_caps is missing {len(missing)} asset(s) present in va
- find_hedge_ratio needs y and x sharing one index
- find_hedge_ratio needs at least 3 aligned observations, got
- returns and var must cover exactly the same labels; {len(onl
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/65252037b071ec47.
Report an issue: GitHub.