{"record":{"id":"07334108e9449b40","repo":"HKUDS/Vibe-Trading","slug":"t-must-be-0-to-imply-a-volatility-got-t","errorCode":null,"errorMessage":"T must be > 0 to imply a volatility, got {T}","messagePattern":"T must be > 0 to imply a volatility, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/options.py","lineNumber":443,"sourceCode":"        ``tol`` and any of them would \"converge\". A 20-day call struck at half\n        the spot prices identically to 16 decimal places for every ``sigma``\n        from 0.05 to 0.60, so a solver that answers there is reporting the\n        arbitrary endpoint of its own search, not a market volatility. This\n        function refuses that: it checks vega at the candidate solution and\n        returns ``nan`` when the price carries no volatility information. That\n        is a property of the quote rather than a solver failure, and no\n        price-tolerance method can do better -- but a confident wrong number is\n        worse than an admitted absence.\n\n    Raises:\n        ValueError: If ``option_type`` is invalid, if ``T``, ``S`` or ``K`` is\n            non-positive, or if ``market_price`` lies outside the no-arbitrage\n            interval, which includes the intrinsic-value violation\n            ``market_price < discounted intrinsic``.\n    \"\"\"\n    option_type = normalise_option_type(option_type)\n    if T <= 0:\n        raise ValueError(f\"T must be > 0 to imply a volatility, got {T}\")\n    if S <= 0 or K <= 0:\n        raise ValueError(f\"S and K must be > 0, got S={S}, K={K}\")\n\n    lower, upper = _no_arbitrage_bounds(S, K, T, r, option_type, q)\n    if market_price < lower - tol:\n        raise ValueError(\n            f\"market price {market_price} is below intrinsic value {lower}\"\n        )\n    if market_price >= upper:\n        raise ValueError(\n            f\"market price {market_price} is at or above the no-arbitrage \"\n            f\"ceiling {upper}; no implied volatility exists\"\n        )\n\n    def identified(candidate: float) -> float:\n        \"\"\"Return the candidate only if the quote actually pins it down.\n\n        The test is whether one volatility point of movement shifts the price by","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/options.py#L425-L461","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nT = (expiry - today).days / 365.0  # 0.0 when expiry == today\niv = implied_volatility(px, S, K, T, r, 'call')\n\n# after\nT = (expiry - today).days / 365.0\nif T <= 0:\n    skip('contract expired')\niv = implied_volatility(px, S, K, T, r, 'call')","handlingStrategy":"validation","validationCode":"assert T > 0, f'expired or invalid T={T}'\nif T <= 0:\n    handle_expired(contract)","typeGuard":"def has_positive_maturity(T: float) -> bool:\n    return isinstance(T, (int, float)) and T > 0","tryCatchPattern":"try:\n    iv = implied_volatility(px, S, K, T, r, option_type)\nexcept ValueError as e:\n    if 'T must be > 0' in str(e):\n        mark_expired(contract_id)\n    else:\n        raise","preventionTips":["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."],"tags":["options","implied-volatility","time-to-maturity","validation"],"backgroundTag":"non-positive-argument","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}