HKUDS/Vibe-Trading · error · ValueError
Spot, strike, and barrier must be strictly positive, got S={
Error message
Spot, strike, and barrier must be strictly positive, got S={S}, K={K}, H={H} What it means
barrier_option_price requires spot S, strike K, and barrier H all strictly positive because the closed-form Reiner-Rubinstein-style solution relies on log-normal dynamics in all three levels. A non-positive value would make the log ratios (log(S/H), log(K/H)) undefined, so validation happens before any pricing branch.
Source
Thrown at agent/src/quantlib/options.py:548
S: Current spot price, strictly positive.
K: Strike price, strictly positive.
H: Barrier price level, strictly positive.
T: Time to expiration in years.
r: Continuously compounded risk-free rate.
sigma: Annualised volatility.
barrier_type: One of :data:`BARRIER_TYPES` (or aliases e.g. ``'down-and-out'``, ``'ui'``).
option_type: ``'call'`` or ``'put'``.
q: Continuously compounded dividend yield.
rebate: Fixed cash rebate paid at expiration if knocked out (or never knocked in).
Returns:
Option price as a non-negative float.
Raises:
ValueError: If S, K, or H <= 0, or barrier_type is unknown.
"""
if S <= 0.0 or K <= 0.0 or H <= 0.0:
raise ValueError(f"Spot, strike, and barrier must be strictly positive, got S={S}, K={K}, H={H}")
b_type = normalise_barrier_type(barrier_type)
opt_type = normalise_option_type(option_type)
# Degenerate expiry or zero/negative volatility
if T <= 0.0 or sigma <= 0.0:
vanilla = bs_price(S, K, T, r, sigma, opt_type, q)
rebate_pv = rebate * float(np.exp(-r * T))
is_down = "down" in b_type
if T > 0.0 and sigma <= 0.0:
F = S * float(np.exp((r - q) * T))
breached = (min(S, F) <= H) if is_down else (max(S, F) >= H)
else:
breached = (S <= H) if is_down else (S >= H)
if "out" in b_type:
return rebate_pv if breached else vanilla
else: # "in"
return vanilla if breached else rebate_pvView on GitHub (pinned to 80ffdda44c)
Solutions
- Set an explicit positive barrier H consistent with the barrier type (below spot for down-*, above spot for up-*).
- Validate the config schema with required positive fields before pricing.
- Quarantine market data rows with non-positive spot.
Example fix
# before price = barrier_option_price(S=100, K=90, H=0, T=1, r=0.05, sigma=0.2, barrier_type='down-and-out') # after price = barrier_option_price(100, 90, H=85, T=1, r=0.05, sigma=0.2, barrier_type='down-and-out')
Defensive patterns
Strategy: validation
Validate before calling
assert S > 0 and K > 0 and H > 0, f'need positive S={S}, K={K}, H={H}' Type guard
def valid_barrier_levels(S: float, K: float, H: float) -> bool:
return all(isinstance(v, (int, float)) and v > 0 for v in (S, K, H)) Try / catch
try:
px = barrier_option_price(S, K, T, r, sigma, H, barrier_type, option_type)
except ValueError as e:
if 'strictly positive' in str(e):
raise ConfigError('barrier config missing H or bad levels') from e
raise Prevention
- Make H a required field in trade/config schemas (no 0.0 default).
- Check barrier placement vs spot (down-* needs H < S, up-* needs H > S) as a second validation.
- Test fixtures must set all three levels explicitly.
When it happens
Trigger: Calling barrier_option_price(S=0, ...) or with K=-100 or H=0; a barrier level of 0 from an unset config field defaulting to 0.0.
Common situations: Config omission where barrier: H is forgotten and YAML gives 0; delisted/crashed underlying feeding a 0 spot; test fixtures built without setting all three levels.
Related errors
- unknown barrier type {barrier_type!r}; valid types: {BARRIER
- S and K must be > 0, got S={S}, K={K}
- unrecognised option_type {option_type!r}. Accepted (any case
- Unhandled barrier type {b_type}
- delay requires n >= 1 (lookahead ban)
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/302d0971ac6e6a92.
Report an issue: GitHub.