The Black-Scholes model
The standard model for theoretical option pricing — not because real markets perfectly follow its assumptions, but because it's the common language every options trader, broker margin calculator, and IV calculation (chapter 120) is built on top of.
import math
from scipy.stats import norm
def black_scholes(S: float, K: float, T: float, r: float, sigma: float, option_type: str = "CE") -> float:
"""
S: spot price, K: strike price, T: time to expiry in YEARS,
r: risk-free rate (annualized, decimal, e.g. 0.07 for 7%),
sigma: implied/annualized volatility (decimal, e.g. 0.20 for 20%),
option_type: 'CE' or 'PE'
"""
if T <= 0:
return max(S - K, 0) if option_type == "CE" else max(K - S, 0) # expired/at-expiry intrinsic value
d1 = (math.log(S / K) + (r + sigma**2 / 2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
if option_type == "CE":
return S * norm.cdf(d1) - K * math.exp(-r * T) * norm.cdf(d2)
else:
return K * math.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
Converting real inputs into what the formula needs
def days_to_years(days: int) -> float:
return days / 365.0
def get_time_to_expiry(expiry_date, as_of_date=None) -> float:
import datetime
as_of_date = as_of_date or datetime.date.today()
days_remaining = (expiry_date - as_of_date).days
return days_to_years(max(days_remaining, 0))
The risk-free rate for Indian markets
RISK_FREE_RATE = 0.07 # approximate — use the current 91-day T-bill rate or RBI repo rate as a proxy,
# update periodically rather than hardcoding indefinitely
There's no single universally "correct" risk-free rate to use — Indian options pricing commonly references short-term government T-bill yields or the repo rate as a proxy. The exact choice matters less for near-term options (low T) and more for far-dated ones.
Worked example
theoretical_price = black_scholes(
S=24500, # NIFTY spot
K=24500, # ATM strike
T=days_to_years(7), # 7 days to expiry
r=0.07,
sigma=0.14, # 14% annualized IV
option_type="CE",
)
print(theoretical_price) # compare against the actual market-quoted premium (ch 25)
What Black-Scholes assumes, and where those assumptions break for Indian index options
- Constant volatility — false in reality; volatility itself has a term structure and a skew across strikes (chapter 123 covers IV behavior in more depth).
- No dividends — a real simplification for stock options (dividend -paying stocks need an adjusted model); largely fine for index options.
- European-style exercise — NSE index options (NIFTY, BANKNIFTY) ARE European-style (exercised only at expiry), so this assumption holds. Stock options on NSE, however, are also European-style as of current rules (verify current exchange rules — this has been standardized over time) — check current exchange circulars if this matters for a specific instrument.
- Continuous trading, no jumps — real markets gap (especially overnight and around events like RBI policy, budget day, election results) — a real limitation for any pricing model assuming smooth, continuous price paths.
Why you need this even if you never price an option manually while trading
Every Greek (chapter 119), every implied volatility calculation (chapter 120), and every payoff diagram (chapter 124) in this course builds directly on this function — understanding its inputs and limitations is a prerequisite for trusting anything downstream of it.