HKUDS/Vibe-Trading · error · ValueError
market price {market_price} is below intrinsic value {lower}
Error message
market price {market_price} is below intrinsic value {lower} What it means
implied_volatility first checks the quote against no-arbitrage bounds: the discounted intrinsic value is the lower bound (within tolerance tol). A market price below intrinsic is arbitrageable and cannot be matched by any volatility, so the function refuses instead of returning sigma ~ 0 or a nonsense negative vol.
Source
Thrown at agent/src/quantlib/options.py:449
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 by
more than the tolerance the solve was run to. If it does not, then a
whole band of volatilities reprices within ``tol`` and whichever one the
search happens to land on is an artefact of the search, not a reading of
the market. Comparing vega against an absolute floor cannot express
this, because the threshold has to scale with ``tol``.
View on GitHub (pinned to 80ffdda44c)
Solutions
- Verify r, q, S, K, and option_type are all correct for this contract.
- If the quote is stale, refresh data or skip the contract.
- If the shortfall is within tolerance, raise tol — but only after confirming it is a rounding-level discrepancy.
Example fix
# before iv = implied_volatility(market_price=4.90, S=100, K=95, T=0.01, r=0.0, option_type='call', tol=1e-8) # intrinsic ~5 -> raises # after iv = implied_volatility(4.90, 100, 95, 0.01, 0.0, 'call', tol=0.25) # explicit, documented slack
Defensive patterns
Strategy: validation
Validate before calling
S_disc = S * math.exp(-q * T) if option_type == 'call' else K * math.exp(-r * T) assert market_price >= intrinsic_lower_bound - tol # recompute or use doc'd bound
Type guard
def quote_above_intrinsic(price: float, S: float, K: float, put: bool) -> bool:
return price >= (max(0.0, K - S) if put else max(0.0, S - K)) - 1e-9 Try / catch
try:
iv = implied_volatility(px, S, K, T, r, option_type)
except ValueError as e:
if 'below intrinsic' in str(e):
skip_quote(quote_id, reason='sub-intrinsic')
else:
raise Prevention
- Cross-check r and q against the contract's conventions.
- Screen out sub-intrinsic quotes in the market-data layer.
- Never widen tol to force a solve — investigate the quote first.
When it happens
Trigger: Quoting 3.0 for a 100/120 call with S=100 (intrinsic 0) is fine, but quoting 0.5 for a 100/95 call near expiry (intrinsic ~5) triggers it; also stale prices where the spot moved but the option quote did not, or a wrong dividend rate q inflating the computed lower bound.
Common situations: Crossed/stale quotes in market data snapshots; using the wrong interest rate or dividend yield so the computed intrinsic exceeds the quote; mixed up bid/ask sides or price multiplied by the wrong contract multiplier.
Related errors
- market price {market_price} is at or above the no-arbitrage
- T must be > 0 to imply a volatility, got {T}
- S and K must be > 0, got S={S}, K={K}
- unknown barrier type {barrier_type!r}; valid types: {BARRIER
- unrecognised option_type {option_type!r}. Accepted (any case
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/6429ccf2b2d76bca.
Report an issue: GitHub.