HKUDS/Vibe-Trading · error · ValueError
T must be > 0 to imply a volatility, got {T}
Error message
T must be > 0 to imply a volatility, got {T} What it means
implied_volatility solves for the sigma that reproduces a market price, and with T <= 0 the option has expired or the time argument is invalid — variance scales with T, so no positive volatility can be identified (and the pricer degenerates). The function demands strictly positive time to maturity before attempting any solve.
Source
Thrown at agent/src/quantlib/options.py:443
``tol`` and any of them would "converge". A 20-day call struck at half
the spot prices identically to 16 decimal places for every ``sigma``
from 0.05 to 0.60, so a solver that answers there is reporting the
arbitrary endpoint of its own search, not a market volatility. This
function refuses that: it checks vega at the candidate solution and
returns ``nan`` when the price carries no volatility information. That
is a property of the quote rather than a solver failure, and no
price-tolerance method can do better -- but a confident wrong number is
worse than an admitted absence.
Raises:
ValueError: If ``option_type`` is invalid, if ``T``, ``S`` or ``K`` is
non-positive, or if ``market_price`` lies outside the no-arbitrage
interval, which includes the intrinsic-value violation
``market_price < discounted intrinsic``.
"""
option_type = normalise_option_type(option_type)
if T <= 0:
raise ValueError(f"T must be > 0 to imply a volatility, got {T}")
if S <= 0 or K <= 0:
raise ValueError(f"S and K must be > 0, got S={S}, K={K}")
lower, upper = _no_arbitrage_bounds(S, K, T, r, option_type, q)
if market_price < lower - tol:
raise ValueError(
f"market price {market_price} is below intrinsic value {lower}"
)
if market_price >= upper:
raise ValueError(
f"market price {market_price} is at or above the no-arbitrage "
f"ceiling {upper}; no implied volatility exists"
)
def identified(candidate: float) -> float:
"""Return the candidate only if the quote actually pins it down.
The test is whether one volatility point of movement shifts the price byView on GitHub (pinned to 80ffdda44c)
Solutions
- Check the date arithmetic: use precise year fractions (e.g. act/365 with intraday time) and verify expiry > as_of.
- Filter out expired contracts before the implied-vol loop.
- If T is legitimately tiny, use a minimum floor like T = max(T, 1/365/24) only if your risk convention allows approximation, or price at intrinsic instead.
Example fix
# before
T = (expiry - today).days / 365.0 # 0.0 when expiry == today
iv = implied_volatility(px, S, K, T, r, 'call')
# after
T = (expiry - today).days / 365.0
if T <= 0:
skip('contract expired')
iv = implied_volatility(px, S, K, T, r, 'call') Defensive patterns
Strategy: validation
Validate before calling
assert T > 0, f'expired or invalid T={T}'
if T <= 0:
handle_expired(contract) Type guard
def has_positive_maturity(T: float) -> bool:
return isinstance(T, (int, float)) and T > 0 Try / catch
try:
iv = implied_volatility(px, S, K, T, r, option_type)
except ValueError as e:
if 'T must be > 0' in str(e):
mark_expired(contract_id)
else:
raise Prevention
- Compute year fractions with a tested day-count helper including intraday time.
- Filter expiries <= as_of before the vol sweep.
- Use timezone-aware expiry parsing.
When it happens
Trigger: Calling implied_volatility(..., T=0) or T=-0.1; computing T as (expiry - today).days / 365 when expiry is today or in the past due to a date bug or timezone offset.
Common situations: Day-count bugs where T rounds to 0 for near-dated options; expiry dates parsed with the wrong timezone making today > expiry; stale market data feeds containing already-expired contracts.
Related errors
- S and K must be > 0, got S={S}, K={K}
- market price {market_price} is below intrinsic value {lower}
- market price {market_price} is at or above the no-arbitrage
- legs must be a non-empty array
- legs may contain at most {_MAX_LEGS} entries
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/07334108e9449b40.
Report an issue: GitHub.