{"record":{"id":"65252037b071ec47","repo":"HKUDS/Vibe-Trading","slug":"need-min-bars-bars-in-each-window-calm-len","errorCode":null,"errorMessage":"need >= {min_bars} bars in each window (calm={len(calm)}, event={len(event)})","messagePattern":"need >= (.+?) bars in each window \\(calm=(.+?), event=(.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/skills/correlation-regime/SKILL.md","lineNumber":396,"sourceCode":"\n    Score = row mean of |Δρ| between the event-window correlation matrix and\n    the calm-baseline correlation matrix. High score = the asset's\n    relationship to the rest of the market changed the most.\n\n    Args:\n        returns: Multi-asset return matrix, columns are symbols\n        calm_mask: Boolean series marking calm-baseline bars\n            (e.g. ``regimes[\"fused\"] == 0`` from Mode 1)\n        event_mask: Boolean series marking the episode under examination\n        min_bars: Minimum bars required in each window\n\n    Returns:\n        DataFrame indexed by symbol with ``rewiring_score``, sorted descending\n    \"\"\"\n    calm = returns.loc[calm_mask.reindex(returns.index, fill_value=False)]\n    event = returns.loc[event_mask.reindex(returns.index, fill_value=False)]\n    if len(calm) < min_bars or len(event) < min_bars:\n        raise ValueError(\n            f\"need >= {min_bars} bars in each window \"\n            f\"(calm={len(calm)}, event={len(event)})\"\n        )\n\n    delta = (event.corr() - calm.corr()).abs()\n    matrix = delta.to_numpy(copy=True)  # copy: DataFrame internals may be read-only\n    np.fill_diagonal(matrix, np.nan)\n    scores = pd.Series(np.nanmean(matrix, axis=1), index=delta.index)\n    return scores.sort_values(ascending=False).to_frame(\"rewiring_score\")\n```\n\n---\n\n## Dependencies\n\n```bash\npip install pandas numpy\n```","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/skills/correlation-regime/SKILL.md#L378-L414","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"# before\nrewiring = rewiring_scores(returns, calm_mask, event_mask, min_bars=60)  # event regime has only 20 bars\n\n# after\nprint(calm_mask.sum(), event_mask.sum())  # inspect coverage\nrewiring = rewiring_scores(returns, calm_mask, event_mask, min_bars=min(20, int(event_mask.sum())))","handlingStrategy":"validation","validationCode":"def masks_have_min_bars(returns, calm_mask, event_mask, min_bars: int) -> bool:\n    calm = returns.loc[calm_mask.reindex(returns.index, fill_value=False)]\n    event = returns.loc[event_mask.reindex(returns.index, fill_value=False)]\n    return len(calm) >= min_bars and len(event) >= min_bars\n\ndef bars_available(returns, calm_mask, event_mask, min_bars: int):\n    calm_n = int(calm_mask.reindex(returns.index, fill_value=False).sum())\n    event_n = int(event_mask.reindex(returns.index, fill_value=False).sum())\n    return {\"calm\": calm_n, \"event\": event_n}","typeGuard":"null","tryCatchPattern":"try:\n    scores = rewiring_scores(returns, calm_mask, event_mask, min_bars=min_bars)\nexcept ValueError as e:\n    if \"need >=\" in str(e):\n        skip_symbol(symbol, reason=\"insufficient bars\")\n    else:\n        raise","preventionTips":["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"],"tags":["pandas","correlation","insufficient-data","index-alignment"],"backgroundTag":"insufficient-data-for-statistics","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}