CHRT Black-Scholes Model
The Nobel Prize equation that's technically wrong but runs the entire options market
Learning Objectives
- •Understand the Black-Scholes formula and its assumptions
- •Learn to price European options using Black-Scholes
- •Know WHY the model is wrong and what that means
Explain Like I'm 5
Black-Scholes is THE formula. Plug in stock price, strike, volatility, time, and interest rate — out pops the "fair" option price. It literally won the Nobel Prize. It's also wrong (assumes constant vol, normal returns, no jumps). But it's wrong in a way everyone understands, which makes it MORE useful than something complex that nobody can reason about.
Think of It This Way
Black-Scholes is like Newton's Laws of Motion. Technically "wrong" (Einstein showed us relativity), but enormously useful for everyday situations. You use Newton to build bridges, not general relativity. Similarly, you use Black-Scholes as a starting point and adjust for real-world messiness. The model is the map, not the territory.
1The Black-Scholes Formula
2Assumptions (All Violated in Practice)
3Why It Matters Even If You Trade Spot
4The Implied Volatility Game
Black-Scholes Call Price vs Underlying Price (K=100, sigma=20%, T=0.25)
Key Formulas
Black-Scholes Call Price
Price of a European call option. S_0 N(d_1) is the expected asset receipt. Ke^{-rT}N(d_2) is the expected cost of exercise. The difference is the option value.
Black-Scholes d1
d_1 measures how far the option is in/out of the money, adjusted for drift and volatility. Think of it as the z-score of the option's "moneyness."
Hands-On Code
Black-Scholes Option Pricing
import numpy as np
from scipy.stats import norm
def black_scholes(S, K, T, r, sigma, option_type='call'):
"""Black-Scholes European option pricing."""
d1 = (np.log(S / K) + (r + sigma**2 / 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
if option_type == 'call':
price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
else:
price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
print(f"=== BLACK-SCHOLES PRICING ===")
print(f" S={S}, K={K}, T={T:.3f}, r={r:.3f}")
print(f" d1={d1:.4f}, d2={d2:.4f}")
print(f" {option_type.upper()} price: {price:.4f}")
return price
def implied_vol(market_price, S, K, T, r, option_type='call', tol=1e-6):
"""Compute implied volatility using Newton's method."""
sigma = 0.20 # initial guess
for _ in range(100):
price = black_scholes(S, K, T, r, sigma, option_type)
d1 = (np.log(S / K) + (r + sigma**2 / 2) * T) / (sigma * np.sqrt(T))
vega = S * norm.pdf(d1) * np.sqrt(T)
diff = price - market_price
if abs(diff) < tol:
break
sigma -= diff / vega # Newton step
print(f" Implied Vol: {sigma:.2%}")
return sigmaImplements the Black-Scholes formula for European options plus Newton's method for reverse-engineering implied volatility from market prices.
Knowledge Check
Q1.All Black-Scholes inputs are directly observable EXCEPT:
Assignment
Implement Black-Scholes and compute call/put prices for a range of strikes and maturities. Then compute implied volatility from market prices and plot the "volatility smile."