{"record":{"id":"b43fbb2eb90408b5","repo":"HKUDS/Vibe-Trading","slug":"parametric-var-needs-at-least-2-observations-for-a","errorCode":null,"errorMessage":"parametric_var needs at least 2 observations for a std estimate","messagePattern":"parametric_var needs at least 2 observations for a std estimate","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/risk.py","lineNumber":215,"sourceCode":"    Args:\n        returns: Periodic (usually daily) return series. The mean and the\n            sample standard deviation (ddof=1) are estimated from it.\n        confidence: Confidence level, commonly 0.95 or 0.99.\n        horizon: Holding period in periods, scaled by square-root-of-time.\n\n    Returns:\n        The VaR as a positive loss magnitude: ``-(mu + z * sigma) * sqrt(horizon)``\n        where ``z = norm.ppf(1 - confidence)``.\n\n    Raises:\n        ValueError: If ``returns`` holds fewer than two finite observations,\n            ``confidence`` is outside (0, 1), or ``horizon`` is below 1.\n    \"\"\"\n    _validate_confidence(confidence)\n    _validate_horizon(horizon)\n    values = _clean_returns(returns)\n    if values.size < 2:\n        raise ValueError(\"parametric_var needs at least 2 observations for a std estimate\")\n    mu = float(values.mean())\n    sigma = float(values.std(ddof=1))\n    z = float(norm.ppf(1.0 - confidence))\n    return float(-(mu + z * sigma) * np.sqrt(horizon))\n\n\ndef historical_cvar(\n    returns: pd.Series | np.ndarray | Sequence[float],\n    confidence: float = 0.95,\n    horizon: int = 1,\n) -> float:\n    \"\"\"Conditional VaR (expected shortfall) from the empirical distribution.\n\n    The average loss *given* that the VaR threshold was breached. Unlike VaR it\n    is subadditive, so it can be decomposed across a portfolio, which is why\n    Basel III moved to it.\n\n    Args:","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/risk.py#L197-L233","documentation":"parametric_var fits a normal distribution to the sample, which requires a sample standard deviation (ddof=1). With fewer than 2 finite observations the std is undefined, so the function refuses rather than dividing by zero.","triggerScenarios":"parametric_var([0.01], 0.95) with a single return, or a two-row price series whose diff yields one NaN dropped by _clean_returns leaving one point.","commonSituations":"Backtesting loops where a rolling window is shorter than expected; newly started strategies with one day of returns; filtered datasets that shrink to a single row.","solutions":["Use historical_var instead if you must handle tiny samples (it works with 1 point, though the estimate is crude)","Ensure the rolling window is at least 2 (preferably far more) before calling","Skip the metric when values.size < 2 and report insufficient data"],"exampleFix":"// before\nvar = parametric_var(window_returns, 0.95)  # window of 1\n// after\nvar = (parametric_var(window_returns, 0.95) if len(window_returns) >= 2 else historical_var(window_returns, 0.95))","handlingStrategy":"validation","validationCode":"import numpy as np\nfinite = np.asarray(returns, dtype=float)\nfinite = finite[np.isfinite(finite)]\nif finite.size >= 2:\n    var = parametric_var(finite, 0.95)\nelse:\n    var = historical_var(finite, 0.95) if finite.size else float(\"nan\")","typeGuard":"def enough_for_parametric(r) -> bool:\n    import numpy as np\n    return int(np.isfinite(np.asarray(r, dtype=float)).sum()) >= 2","tryCatchPattern":"try:\n    var = parametric_var(window, 0.95)\nexcept ValueError as e:\n    if \"at least 2 observations\" in str(e):\n        var = historical_var(window, 0.95)\n    else:\n        raise","preventionTips":["Prefer window sizes >> 2 in rolling backtests","Branch on sample size before choosing parametric vs historical","Report 'insufficient data' rather than crashing reports"],"tags":["quantlib","risk","parametric-var","insufficient-data","valueerror"],"backgroundTag":"insufficient-sample-size","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}