{"record":{"id":"56f02926090e6bf8","repo":"HKUDS/Vibe-Trading","slug":"no-split-produced-a-usable-sharpe-every-strategy","errorCode":null,"errorMessage":"no split produced a usable Sharpe; every strategy may have zero variance within the subsets","messagePattern":"no split produced a usable Sharpe; every strategy may have zero variance within the subsets","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/multipletesting.py","lineNumber":544,"sourceCode":"        finite_out = np.isfinite(out_scores)\n        if not finite_out[best] or finite_out.sum() < 2:\n            continue\n\n        # Relative rank of the selected strategy among all strategies OOS, on\n        # (0, 1). Ties are resolved by average rank so a plateau does not push\n        # the logit to an endpoint.\n        ranked = pd.Series(np.where(finite_out, out_scores, np.nan)).rank(\n            method=\"average\"\n        )\n        omega = float(ranked.iloc[best] / (finite_out.sum() + 1))\n        omega = min(max(omega, 1e-12), 1.0 - 1e-12)\n\n        logits.append(math.log(omega / (1.0 - omega)))\n        in_sample_sharpes.append(float(in_scores[best]))\n        out_sample_sharpes.append(float(out_scores[best]))\n\n    if not logits:\n        raise ValueError(\n            \"no split produced a usable Sharpe; every strategy may have zero \"\n            \"variance within the subsets\"\n        )\n\n    logit_array = np.array(logits)\n    in_array = np.array(in_sample_sharpes)\n    out_array = np.array(out_sample_sharpes)\n\n    if in_array.size >= 2 and float(in_array.std()) > 0:\n        degradation = float(np.polyfit(in_array, out_array, 1)[0])\n    else:\n        degradation = float(\"nan\")\n\n    return CSCVResult(\n        pbo=float((logit_array <= 0).mean()),\n        logits=logit_array,\n        n_splits=len(logits),\n        n_strategies=n_strategies,","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/multipletesting.py#L526-L562","documentation":"After looping over all CSCV splits, probability_of_backtest_overfitting needs at least one split where an in-sample Sharpe could be computed. If every subset has zero variance for every strategy (constant returns), all logits are undefined and the list is empty, so the function raises this error rather than returning a fabricated PBO.","triggerScenarios":"Passing a constant matrix (all rows identical) as performance; a pipeline bug that feeds cumulative equity curves' first differences of zero; strategies whose per-block returns are all exactly 0.0 due to a data alignment bug producing duplicate rows.","commonSituations":"Zero-filled data from a failed fetch or an uninitialised array; returns computed from a stale/cached price series so all diffs are zero; feed-forward of a constants-only synthetic fixture in tests.","solutions":["Inspect performance for zero-variance columns: np.var(perf, axis=0) — every column should be > 0.","Fix the upstream return computation (e.g. you passed prices or a constant seed) and re-run.","If synthetic data is intended, add noise so Sharpe is defined."],"exampleFix":"# before\nperf = np.zeros((100, 5))\npbo = probability_of_backtest_overfitting(perf, 16)  # raises\n\n# after\nrng = np.random.default_rng(0)\nperf = rng.normal(0, 0.01, size=(100, 5))\npbo = probability_of_backtest_overfitting(perf, 16)","handlingStrategy":"validation","validationCode":"v = np.var(np.asarray(performance, dtype=float), axis=0)\nassert (v > 0).all(), f'zero-variance strategy columns: {np.where(v == 0)[0]}'","typeGuard":"def all_strategies_vary(p) -> bool:\n    return (np.var(np.asarray(p, dtype=float), axis=0) > 0).all()","tryCatchPattern":"try:\n    pbo = probability_of_backtest_overfitting(perf, n_splits)\nexcept ValueError as e:\n    if 'usable Sharpe' in str(e):\n        raise DataQualityError('constant returns fed to CSCV') from e\n    raise","preventionTips":["Sanity-check return series for zero variance before CSCV.","Verify returns (diffs) are being passed, not price levels.","Fail loudly on all-zero synthetic fixtures in CI."],"tags":["backtesting","cscv","zero-variance","data-quality"],"backgroundTag":"degenerate-input-data","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}