HKUDS/Vibe-Trading · error · ValueError
every p-value must lie in [0, 1]
Error message
every p-value must lie in [0, 1]
What it means
benjamini_hochberg validates that every supplied p-value lies in the closed interval [0, 1]. P-values are probabilities, so any value outside that range indicates an upstream statistical bug (e.g. a malformed test statistic or a negative likelihood ratio), and the BH procedure would produce meaningless adjusted p-values. The library refuses the whole input rather than silently clipping or dropping offenders.
Source
Thrown at agent/src/quantlib/multipletesting.py:407
Returns:
An :class:`FDRResult` whose ``rejected`` and ``adjusted_p_values`` are in
the caller's original order.
Raises:
ValueError: If ``p_values`` is empty, holds a value outside ``[0, 1]``
or a non-finite value, or if ``fdr`` is not in ``(0, 1)``.
"""
if not 0.0 < fdr < 1.0:
raise ValueError(f"fdr must be in (0, 1), got {fdr}")
values = np.asarray(p_values, dtype=float).ravel()
if values.size == 0:
raise ValueError("p_values is empty")
if not np.isfinite(values).all():
raise ValueError("p_values holds a non-finite value")
if ((values < 0.0) | (values > 1.0)).any():
raise ValueError("every p-value must lie in [0, 1]")
n = values.size
order = np.argsort(values, kind="stable")
sorted_p = values[order]
ranks = np.arange(1, n + 1)
# Step-up: the largest rank whose p-value clears its own threshold, and
# everything below it, is rejected.
below = sorted_p <= (ranks / n) * fdr
if below.any():
cutoff_rank = int(ranks[below].max())
threshold = float(sorted_p[cutoff_rank - 1])
else:
cutoff_rank = 0
threshold = 0.0
rejected_sorted = ranks <= cutoff_rank
View on GitHub (pinned to 80ffdda44c)
Solutions
- Check the upstream test that produced the p-values and fix the sign/formula error.
- Clip only genuine floating-point overshoot: np.clip(p, 0.0, 1.0), but only after confirming values like 1.0000000001.
- Verify you are actually passing p-values, not z-scores, ratios, or percentages.
- Add a unit test asserting 0 <= p <= 1 on generated p-values before batch jobs run.
Example fix
# before adjusted = benjamini_hochberg([0.02, -0.01, 0.5]) # raises # after p = np.asarray(raw_p, dtype=float) assert np.isfinite(p).all() p = np.clip(p, 0.0, 1.0) # only for float overshoot adjusted = benjamini_hochberg(p)
Defensive patterns
Strategy: validation
Validate before calling
p = np.asarray(p_values, dtype=float) assert p.size and np.isfinite(p).all() and ((p >= 0) & (p <= 1)).all(), 'invalid p-values'
Type guard
def are_valid_p_values(p) -> bool:
a = np.asarray(p, dtype=float)
return a.size > 0 and np.isfinite(a).all() and ((a >= 0.0) & (a <= 1.0)).all() Try / catch
try:
res = benjamini_hochberg(p)
except ValueError as e:
if 'p-value must lie' in str(e):
p = np.clip(p, 0.0, 1.0)
res = benjamini_hochberg(p)
else:
raise Prevention
- Unit-test p-value generators for the [0,1] invariant.
- Never feed test statistics where p-values are expected; label columns explicitly.
- Clip only documented floating-point overshoot, never negative values.
When it happens
Trigger: Calling benjamini_hochberg(p_values=[0.01, 1.5]) or with any negative value; also p-values computed with a sign error or from an approximate formula that can exceed 1 (e.g. some tail approximations), or data-entry mistakes like passing returns or z-scores instead of p-values.
Common situations: Passing raw test statistics, correlation coefficients, or 1-p values by mistake; numerical p-value approximations (chi-square/Lilliefors style) that overshoot 1.0 due to floating point; feeding in percentages (0-100) instead of fractions.
Related errors
- delay requires n >= 1 (lookahead ban)
- delay requires n >= 1 (lookahead ban)
- delay requires n >= 1 (lookahead ban)
- delay requires n >= 1 (lookahead ban)
- delay requires n >= 1 (lookahead ban)
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/6ff01858e31618df.
Report an issue: GitHub.