from math import log, sqrt, exp
from scipy.stats import norm
def bs_price(is_put, spot, strike, T, r, sigma):
"""T = time to expiry in years, r = risk-free rate, sigma = IV."""
if T <= 0:
return max(strike - spot, 0) if is_put else max(spot - strike, 0)
d1 = (log(spot / strike) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt(T))
d2 = d1 - sigma * sqrt(T)
if is_put:
return strike * exp(-r * T) * norm.cdf(-d2) - spot * norm.cdf(-d1)
return spot * norm.cdf(d1) - strike * exp(-r * T) * norm.cdf(d2)
def bs_delta(is_put, spot, strike, T, r, sigma):
"""Returns delta: [-1, 0] for puts, [0, 1] for calls."""
if T <= 0:
if is_put:
return -1.0 if spot < strike else 0.0
return 1.0 if spot > strike else 0.0
d1 = (log(spot / strike) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt(T))
return norm.cdf(d1) - 1.0 if is_put else norm.cdf(d1)
def bid_price(is_put, spot, strike, T, r, sigma, spread_bps=300):
theo = bs_price(is_put, spot, strike, T, r, sigma)
return max(theo * (1 - spread_bps / 10000), 1e-6)