HKUDS/Vibe-Trading · error · ValueError
parametric_var needs at least 2 observations for a std estim
Error message
parametric_var needs at least 2 observations for a std estimate
What it means
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.
Source
Thrown at agent/src/quantlib/risk.py:215
Args:
returns: Periodic (usually daily) return series. The mean and the
sample standard deviation (ddof=1) are estimated from it.
confidence: Confidence level, commonly 0.95 or 0.99.
horizon: Holding period in periods, scaled by square-root-of-time.
Returns:
The VaR as a positive loss magnitude: ``-(mu + z * sigma) * sqrt(horizon)``
where ``z = norm.ppf(1 - confidence)``.
Raises:
ValueError: If ``returns`` holds fewer than two finite observations,
``confidence`` is outside (0, 1), or ``horizon`` is below 1.
"""
_validate_confidence(confidence)
_validate_horizon(horizon)
values = _clean_returns(returns)
if values.size < 2:
raise ValueError("parametric_var needs at least 2 observations for a std estimate")
mu = float(values.mean())
sigma = float(values.std(ddof=1))
z = float(norm.ppf(1.0 - confidence))
return float(-(mu + z * sigma) * np.sqrt(horizon))
def historical_cvar(
returns: pd.Series | np.ndarray | Sequence[float],
confidence: float = 0.95,
horizon: int = 1,
) -> float:
"""Conditional VaR (expected shortfall) from the empirical distribution.
The average loss *given* that the VaR threshold was breached. Unlike VaR it
is subadditive, so it can be decomposed across a portfolio, which is why
Basel III moved to it.
Args:View on GitHub (pinned to 80ffdda44c)
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
Example fix
// before var = parametric_var(window_returns, 0.95) # window of 1 // after var = (parametric_var(window_returns, 0.95) if len(window_returns) >= 2 else historical_var(window_returns, 0.95))
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
finite = np.asarray(returns, dtype=float)
finite = finite[np.isfinite(finite)]
if finite.size >= 2:
var = parametric_var(finite, 0.95)
else:
var = historical_var(finite, 0.95) if finite.size else float("nan") Type guard
def enough_for_parametric(r) -> bool:
import numpy as np
return int(np.isfinite(np.asarray(r, dtype=float)).sum()) >= 2 Try / catch
try:
var = parametric_var(window, 0.95)
except ValueError as e:
if "at least 2 observations" in str(e):
var = historical_var(window, 0.95)
else:
raise Prevention
- Prefer window sizes >> 2 in rolling backtests
- Branch on sample size before choosing parametric vs historical
- Report 'insufficient data' rather than crashing reports
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- returns contains no finite observation
- confidence must be in (0, 1), got {confidence}
- horizon must be >= 1, got {horizon}
- equity must be 1-D, got shape {array.shape}
- equity contains no finite observation
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/b43fbb2eb90408b5.
Report an issue: GitHub.