Chapter 31
30 min read
Section 265 of 353

The Greeks: Delta, Gamma, Theta, Vega

The Black-Scholes Equation

Learning Objectives

By the end of this section, you will be able to:

  1. Recognize each Greek as an ordinary partial derivative of the Black-Scholes price.
  2. Explain the intuition behind Delta, Gamma, Theta, and Vega without any opaque finance jargon.
  3. Read the four-Greek "dashboard" for any option from a single picture of its curve.
  4. Decompose a trader's daily P&L into Δ, Γ, Θ, and ν contributions using a second-order Taylor expansion.
  5. Compute all Greeks two ways: closed-form in plain Python and automatically via PyTorch autograd.
  6. Construct a delta-hedged portfolio and see why Gamma drives the residual P&L.

The Big Picture: Greeks Are Just Calculus

Black-Scholes gave us a formula for an option price V=V(S,t;K,r,σ)V = V(S, t; K, r, \sigma). The Greeks are nothing more than its partial derivatives with respect to the variables that change between today and tomorrow:

GreekDefinitionReads asUnits
Delta Δ∂V / ∂SHow much V moves when the stock moves $1$ per $
Gamma Γ∂²V / ∂S²How much Δ itself moves when the stock moves $1Δ per $
Theta Θ∂V / ∂tHow much V drops per day of calendar time$ per day
Vega ν∂V / ∂σHow much V changes per 1% change in volatility$ per 1% σ
The whole table is just first-year calculus. If you can differentiate f(x,y)=xN(y)f(x,y) = x \cdot N(y), you can compute every Greek. The hard part is not the algebra; it is the intuition about what each derivative is telling you about the market.

Here is the analogy that makes everything click. Imagine you are driving a car. The price VV is your position. The stock SS is the road. Then:

  • Delta is your speed — how fast position changes as you move along the road.
  • Gamma is your acceleration — how fast your speed itself is changing.
  • Theta is the fuel gauge — value bleeds regardless of where the stock goes.
  • Vega is how sensitive your speedometer is to weather — volatility is the "weather forecast" for the stock.

Quick Recap: The Black-Scholes Price

For a European call on a non-dividend stock,

C(S,t)=SN(d1)Ker(Tt)N(d2)\displaystyle C(S,t) = S\, N(d_1) - K e^{-r(T-t)}\, N(d_2)

where N()N(\cdot) is the standard normal CDF and

d1=ln(S/K)+(r+12σ2)(Tt)σTt,d2=d1σTt.\displaystyle d_1 = \frac{\ln(S/K) + (r + \tfrac{1}{2}\sigma^2)(T-t)}{\sigma\sqrt{T-t}}, \quad d_2 = d_1 - \sigma\sqrt{T-t}.

The puts come from put-call parity: P=CS+Ker(Tt)P = C - S + K e^{-r(T-t)}.

Throughout this section we will write τ=Tt\tau = T - t for time-to-expiry and use the shorthand φ(x)=12πex2/2\varphi(x) = \tfrac{1}{\sqrt{2\pi}} e^{-x^2/2} for the standard-normal PDF. You will see φ(d1)\varphi(d_1) showing up everywhere — that is the "bell-curve weight" the option places on the at-the-money region.

Delta — The First Derivative

Differentiate the call price with respect to SS. Two terms in the product rule contain N(d1)d1/SN'(d_1) \cdot \partial d_1 / \partial S and a similar one for N(d2)d2/SN'(d_2) \cdot \partial d_2 / \partial S. After algebra (a beautifully clean cancellation that is worth doing once in your life), almost everything dies and you are left with:

Closed-Form Delta

Δcall=CS=N(d1),Δput=N(d1)1.\displaystyle \Delta_{\text{call}} = \frac{\partial C}{\partial S} = N(d_1), \qquad \Delta_{\text{put}} = N(d_1) - 1.
The cancellation is not a coincidence. It is the same risk-neutral argument that produced the Black-Scholes PDE in the first place: the hedged portfolio has no first-order exposure to SS, which is exactly what V/S\partial V/\partial S tells you to subtract off.

What Delta Really Means

Three different but equivalent ways to read Δ=N(d1)=0.57\Delta = N(d_1) = 0.57:

  1. Slope. If the stock rises by $1, the call gains about $0.57. That is the textbook reading.
  2. Hedge ratio. To neutralize the option's stock exposure right now, short 0.57 shares per call you sold. This is the basis of delta hedging.
  3. Probability. Under the risk-neutral measure, N(d1)N(d_1) is (almost) the probability the call ends in-the-money — actually it is the probability weighted by the stock's own dynamics, but to within a small correction it is the intuition every trader carries in their head.
Mnemonic: "Delta is shares-equivalent." A call with Δ = 0.57 behaves locally like owning 0.57 shares of the underlying.

Gamma — Curvature of the Option

Differentiate Delta one more time: Γ=Δ/S=2V/S2\Gamma = \partial \Delta / \partial S = \partial^2 V / \partial S^2. The product rule combined with the chain rule on N(d1)N(d_1) gives:

Γ=φ(d1)Sστ.\displaystyle \Gamma = \frac{\varphi(d_1)}{S\,\sigma\,\sqrt{\tau}}.

Why Gamma Is Always Positive

Every factor on the right — φ(d1)\varphi(d_1), SS, σ\sigma, τ\sqrt{\tau} — is positive. So a long option position always has positive curvature. Intuitively: the payoff function max(STK,0)\max(S_T - K, 0) is convex, and so its present value must be convex too.

Practical consequence: an option's P&L from a stock move is better than the linear approximation in both directions. If you are long an option and the stock moves either way, you get a free bonus from the curvature. That bonus is called "gamma rent" — and someone has to pay for it. They pay for it through Theta.

Gamma is biggest at-the-money near expiry. φ(d1)\varphi(d_1) peaks at d1=0d_1 = 0 (i.e. roughly S=KS = K), and the denominator στ\sigma\sqrt{\tau} shrinks as time runs out. That is why ATM options become wildly sensitive in the last week — and why hedging them gets expensive.

Theta — The Bleeding of Time

Time is the only variable in VV that moves on its own without anyone trading. Differentiate with respect to calendar time tt:

Θcall=Ct=Sφ(d1)σ2τ    rKerτN(d2).\displaystyle \Theta_{\text{call}} = \frac{\partial C}{\partial t} = -\,\frac{S\,\varphi(d_1)\,\sigma}{2\sqrt{\tau}} \;-\; r K e^{-r\tau}\,N(d_2).

For a long call this is always negative. Two stories in one formula:

  • The volatility-decay term Sφ(d1)σ2τ-\tfrac{S \varphi(d_1) \sigma}{2\sqrt{\tau}} : every day, you lose a tiny piece of the optionality just because there is less time for the stock to move. This term is exactly the gamma rent flowing the other direction — mathematically it equals 12σ2S2Γ-\tfrac{1}{2}\sigma^2 S^2 \Gamma, which you may recognise as a term in the Black-Scholes PDE.
  • The financing term rKerτN(d2)-r K e^{-r\tau} N(d_2) : the present value of the strike that would be paid at exercise grows as expiry approaches; that growth costs the call holder money.
The fundamental trade-off in options. Long Gamma ⇒ positive Γ ⇒ negative Θ. You buy curvature; you pay rent on it. Selling options reverses both signs — you collect rent, you owe curvature.

Vega — Sensitivity to Volatility

Differentiating with respect to σ\sigma is again a textbook chain-rule exercise that collapses to:

ν=Vσ=Sφ(d1)τ.\displaystyle \nu = \frac{\partial V}{\partial \sigma} = S\,\varphi(d_1)\,\sqrt{\tau}.

Three things to notice immediately:

  1. Same φ(d1)\varphi(d_1) bell-curve factor as Gamma. So Vega is biggest at-the-money — there is the most to gain from extra volatility there.
  2. Scales like τ\sqrt{\tau}, the opposite of Gamma. Long-dated options are vega-rich; short-dated ones are gamma-rich. That is a fundamental tension between the two ends of the volatility curve.
  3. Same value for calls and puts (just like Gamma). Both have the same dependence on σ because they only differ by a deterministic put-call parity piece.
Strictly speaking vega is not a Greek letter — it is a finance-industry name. The Greek-letter version is sometimes written κ\kappa. Everybody still says "vega."

Interactive: All Four Greeks at Once

Below is a five-panel dashboard. The top panel is the option price itself; the bottom four panels are its partial derivatives with respect to S,S,t,σS, S, t, \sigma respectively. Move the sliders and watch how each Greek is literally the slope, curvature, or partial of the one above.

At S = 100.00 → price 4.615, Δ 0.569, Γ 0.0393, Θ -0.029/day, ν 0.196/1%σ
Spot S100.00
Strike K100.00
Time T (yr)0.25
Vol σ0.20
Rate r5.0%

The yellow dot marks the current spot. Dashed vertical line is the strike K. Notice how each Greek is just the slope (Δ), curvature (Γ), or partial of the one above it — calculus on the Black-Scholes surface.

Things to try:
  • Push T toward zero. Watch Gamma blow up at-the-money — the famous "expiry pin."
  • Slide σ from 5% to 80%. Vega is mostly invariant in shape but larger options become enormously sensitive.
  • Switch from Call to Put. Delta drops by exactly 1 everywhere — put-call parity in graph form.
  • Look at the price panel. Its slope at the yellow dot equals the value shown in the Delta panel. Its curvature equals the Gamma panel value. Calculus, on a screen.

Putting It Together: P&L as a Taylor Expansion

A trader holding an option overnight sees the stock move by dSdS, time advance by dtdt, and implied volatility shift by dσd\sigma. The change in the option's value, to second order, is a multivariate Taylor expansion:

dV    ΔdS  +  12Γ(dS)2  +  Θdt  +  νdσ.\displaystyle dV \;\approx\; \Delta\, dS \;+\; \tfrac{1}{2}\Gamma\, (dS)^2 \;+\; \Theta\, dt \;+\; \nu\, d\sigma.

Each term is one of the Greeks doing exactly what it was named for:

TermMeaningSign for long call
Δ dSDirectional P&L from the stock moving± (same sign as dS)
½ Γ (dS)²Convexity bonus — you always gain when the stock moves either way+
Θ dtDaily time decay
ν dσVolatility-revaluation P&L+ if dσ > 0

Now look at the magic. If you delta-hedge by shorting Δ\Delta shares, the first term vanishes. What is left is:

dVhedged    12Γ(dS)2  +  Θdt  +  νdσ.\displaystyle dV_{\text{hedged}} \;\approx\; \tfrac{1}{2}\Gamma (dS)^2 \;+\; \Theta\, dt \;+\; \nu\, d\sigma.

Two of those — Γ\Gamma and Θ\Theta — must balance over time, or there is arbitrage. That balance, written precisely, is the Black-Scholes PDE: Θ+12σ2S2Γ+rSΔrV=0\Theta + \tfrac{1}{2}\sigma^2 S^2 \Gamma + r S \Delta - r V = 0. Every term you have built in this section appears in that single line.


Visual: Delta and Gamma as Approximations

The most beautiful single picture in this section. Pick an expansion point S0S_0. The green dashed line is the linear (Delta-only) approximation of the option price. The amber dotted curve is the quadratic (Delta + Gamma) approximation. The blue curve is the true price.

Expansion point S₀100.00
Shock dS0.00

The green dashed line is the tangent at S₀ — that's the Delta-only prediction. The amber dotted line bends upward to match the curvature — that's Δ + ½Γ. As dS grows, the gap between green and blue grows too, and that gap is what Gamma fills in.

Drag the shock dSdS slider. For small dSdS the three dots almost coincide — Delta is enough. Push it further and the green dot drifts below the truth because the linear approximation misses the curvature. The amber dot stays close because the quadratic term captures Gamma.

This is the exact reason traders care about Gamma. A Delta-only hedge is correct only at one instant. The moment the stock moves, the hedge becomes stale, and the size of the staleness is proportional to Γ(dS)2\Gamma (dS)^2.

Worked Example (Try It By Hand)

Same scenario you will see in the Python output below — work through it with a calculator first so the formulas feel concrete.

Step-by-step calculation for an ATM 3-month call

Inputs: S=100,  K=100,  τ=0.25,  r=0.05,  σ=0.20S = 100,\; K = 100,\; \tau = 0.25,\; r = 0.05,\; \sigma = 0.20.

Step 1: Compute d₁ and d₂.

στ=0.200.5=0.10\sigma\sqrt{\tau} = 0.20 \cdot 0.5 = 0.10d1=ln1+(0.05+0.02)0.250.10=0+0.01750.10=0.175d_1 = \frac{\ln 1 + (0.05 + 0.02)\cdot 0.25}{0.10} = \frac{0 + 0.0175}{0.10} = 0.175d2=d10.10=0.075d_2 = d_1 - 0.10 = 0.075

Step 2: Look up N(d₁), N(d₂), φ(d₁).

N(0.175)0.5695,N(0.075)0.5299N(0.175) \approx 0.5695,\quad N(0.075) \approx 0.5299φ(0.175)=12πe0.01530.3928\varphi(0.175) = \tfrac{1}{\sqrt{2\pi}} e^{-0.0153} \approx 0.3928

Step 3: Discount factor. erτ=e0.01250.9876e^{-r\tau} = e^{-0.0125} \approx 0.9876.

Step 4: Plug into the price.

C=1000.56951000.98760.529956.9552.34=4.61C = 100 \cdot 0.5695 - 100 \cdot 0.9876 \cdot 0.5299 \approx 56.95 - 52.34 = 4.61

Step 5: Now each Greek.

  • Δ=N(d1)=0.5695\Delta = N(d_1) = 0.5695
  • Γ=φ(d1)Sστ=0.39281000.200.5=0.0393\Gamma = \dfrac{\varphi(d_1)}{S\sigma\sqrt{\tau}} = \dfrac{0.3928}{100 \cdot 0.20 \cdot 0.5} = 0.0393
  • Volatility part of Θ: Sφ(d1)σ2τ=1000.39280.2020.5=7.856-\dfrac{S\varphi(d_1)\sigma}{2\sqrt{\tau}} = -\dfrac{100 \cdot 0.3928 \cdot 0.20}{2 \cdot 0.5} = -7.856.
  • Financing part of Θ: rKerτN(d2)=0.051000.98760.5299=2.616-r K e^{-r\tau} N(d_2) = -0.05 \cdot 100 \cdot 0.9876 \cdot 0.5299 = -2.616.
  • Total Θ=7.8562.616=10.47\Theta = -7.856 - 2.616 = -10.47 per year, or about 10.47/3650.0287-10.47 / 365 \approx -0.0287 per day.
  • ν=Sφ(d1)τ=1000.39280.5=19.64\nu = S\varphi(d_1)\sqrt{\tau} = 100 \cdot 0.3928 \cdot 0.5 = 19.64 per unit σ, i.e. about $0.196 per 1-percentage-point change in σ.
Sanity check. If you bought this call for $4.61 and the stock immediately jumps to $101, you expect a gain of about Δ+12Γ=0.57+0.50.0390.589\Delta + \tfrac{1}{2}\Gamma = 0.57 + 0.5 \cdot 0.039 \approx 0.589. The Python output (and the visualizer above) confirm this within rounding.

Computing the Greeks in Plain Python

First the "intuition" version: write each closed-form Greek out as it appears in the textbook. No surprises — just enter the formulas and read the result.

Closed-form Black-Scholes Greeks
🐍bs_greeks.py
1NumPy import

We need vectorized math (log, sqrt, exp) so the same function works on a single point or an array of stock prices.

EXAMPLE
np.log(100/100) → 0.0
2SciPy normal distribution

norm.cdf gives N(x), the area to the left under the standard normal curve. norm.pdf gives φ(x), the height of the bell at x. Black-Scholes is built entirely out of these two.

EXAMPLE
norm.cdf(0) → 0.5,  norm.pdf(0) → 0.3989
4Function signature

Five market inputs and one flag. These five are exactly the variables on which V depends — and they are exactly what every Greek differentiates.

14Compute d₁

d₁ measures how far the log-moneyness ln(S/K), adjusted by drift, is in units of √T·σ standard deviations. It is the single most reused quantity in the whole file: Δ, Γ, Θ, ν all touch it.

EXAMPLE
S=K=100, r=.05, σ=.2, T=.25 → d₁ = (0 + 0.07·0.25)/(0.2·0.5) = 0.175
15Compute d₂

d₂ = d₁ − σ√T. It is d₁ shifted by exactly one standard deviation of returns. N(d₂) is the risk-neutral probability of ending in-the-money.

EXAMPLE
d₂ = 0.175 − 0.2·0.5 = 0.075
18Alias N for the CDF

Short name so the formula below reads almost identically to the textbook. N(d₁) and N(d₂) appear in every Black-Scholes line we write.

19Alias phi for the PDF

φ(d₁) is the bell-curve height at d₁. It is the factor that makes Gamma, Vega, and the time-decay piece of Theta vanish far from the strike.

EXAMPLE
φ(0.175) ≈ 0.393
22Branch: call option

If the trader bought a call, we use the call formula. The price is the discounted expected payoff E[max(S_T − K, 0)] in the risk-neutral measure.

23Call price

C = S·N(d₁) − K·e^{−rT}·N(d₂). Read left-to-right: 'expected stock value if exercised' minus 'expected discounted strike paid'. Both expectations are weighted by N(d₁) and N(d₂).

EXAMPLE
Atm 3-month call → ≈ 4.61
24Call Delta

Δ_call = N(d₁). It is always in [0, 1] because N is a CDF. Interpretation: probability-weighted exposure to the stock — own 0.57 shares per call when N(d₁)=0.57.

EXAMPLE
Deep ITM call → N(d₁) → 1.  Deep OTM → 0.
25Call Theta (per year)

Two parts. The first −Sφ(d₁)σ/(2√T) is the 'volatility time-decay' — uncertainty erodes as we approach expiry. The second −rKe^{−rT}N(d₂) is the financing cost of the strike. Both are negative for long calls, so Theta is negative — calls bleed value daily.

EXAMPLE
Atm 3-month call → Θ ≈ −15 per year ≈ −$0.041 per day.
28Branch: put option

Mirror image. Uses N(−d₁) and N(−d₂) by the symmetry of the normal distribution.

29Put price

P = K·e^{−rT}·N(−d₂) − S·N(−d₁). By put-call parity, P = C − S + K·e^{−rT}, so a single formula determines both once you know either price.

30Put Delta

Δ_put = N(d₁) − 1, always in [−1, 0]. A put gains value as the stock falls, so its sensitivity to S is negative.

EXAMPLE
Δ_put = 0.57 − 1 = −0.43
31Put Theta

Same volatility-decay piece as the call, but the financing piece flips sign because the put-holder gains from delaying receipt of K. Long puts can occasionally have positive Theta when r is high and the option is deep in-the-money.

35Gamma (same for call & put)

Γ = φ(d₁) / (S·σ·√T). The intuition: Gamma is the bell-curve mass arriving at d₁, divided by the local 'price scale' Sσ√T. Maximum at-the-money near expiry, tiny everywhere else.

EXAMPLE
Atm 3-month: Γ ≈ 0.0394
36Vega (same for call & put)

ν = S·φ(d₁)·√T. Same factor φ(d₁) that drives Gamma, but scaled by √T instead of 1/(Sσ√T). So Vega is large for long-dated at-the-money options — exactly where 'volatility uncertainty' has the most room to translate into price.

EXAMPLE
Atm 3-month: ν ≈ 19.7 per unit of σ ≈ 0.197 per 1% σ.
38Return dict

We return Theta scaled to per-day and Vega to per-1% sigma — that is how the trading desk quotes them. The raw partial derivatives are per-year and per-unit-σ, which match the calculus but are inconvenient at human scale.

49Run the toy example

S=100, K=100, T=0.25 years, r=5%, σ=20%. This is the same scenario we will hand-trace in the worked example below.

50Pretty print

Aligned key:value output makes it easy to compare against the by-hand numbers without scanning. Expect price ≈ 4.6150 and Δ ≈ 0.5695.

30 lines without explanation
1import numpy as np
2from scipy.stats import norm
3
4def black_scholes_greeks(S, K, T, r, sigma, option_type="call"):
5    """Price and all Greeks for a European option.
6
7    S      : current stock price
8    K      : strike price
9    T      : time to expiry (years)
10    r      : risk-free rate (annualized, continuous)
11    sigma  : volatility (annualized)
12    option_type : "call" or "put"
13    """
14    # 1. The two building blocks d1, d2.
15    d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
16    d2 = d1 - sigma * np.sqrt(T)
17
18    # 2. Standard-normal CDF N(x) and PDF phi(x).
19    N   = norm.cdf
20    phi = norm.pdf
21
22    # 3. Price and Delta depend on call vs put.
23    if option_type == "call":
24        price = S * N(d1) - K * np.exp(-r * T) * N(d2)
25        delta = N(d1)
26        theta = (-S * phi(d1) * sigma / (2 * np.sqrt(T))
27                 - r * K * np.exp(-r * T) * N(d2))
28    else:
29        price = K * np.exp(-r * T) * N(-d2) - S * N(-d1)
30        delta = N(d1) - 1
31        theta = (-S * phi(d1) * sigma / (2 * np.sqrt(T))
32                 + r * K * np.exp(-r * T) * N(-d2))
33
34    # 4. Gamma and Vega are identical for calls and puts.
35    gamma = phi(d1) / (S * sigma * np.sqrt(T))
36    vega  = S * phi(d1) * np.sqrt(T)
37
38    return {
39        "price": price,
40        "delta": delta,
41        "gamma": gamma,
42        "theta_per_year": theta,
43        "theta_per_day":  theta / 365.0,
44        "vega_per_1pct":  vega / 100.0,
45    }
46
47# Toy run.
48out = black_scholes_greeks(S=100, K=100, T=0.25, r=0.05, sigma=0.20, option_type="call")
49for k, v in out.items():
50    print(f"{k:<16} = {v:.6f}")

Running this on our worked-example inputs prints:

price            = 4.614997
delta            = 0.569460
gamma            = 0.039261
theta_per_year   = -10.472929
theta_per_day    = -0.028693
vega_per_1pct    = 0.196419

Compare these numbers against the hand-computed ones above — they match to four decimals. The small differences are just rounding in the by-hand normal-table lookups.


Greeks Via PyTorch Autograd

Closed-form derivatives are great when they exist. For complicated exotic options they often don't — and even when they do, the manual chain-rule bookkeeping is error-prone. Autograd does the work for free, and it generalizes immediately to any payoff you can write down in torch ops.

The trick is to mark every market variable we want a Greek for as a leaf tensor with requires_grad=True\texttt{requires\_grad=True}, then ask torch.autograd.grad\texttt{torch.autograd.grad} for the partial derivatives. Gamma is just the derivative of Delta — one more line.

Black-Scholes Greeks via autograd
🐍bs_greeks_torch.py
1Import torch

We need torch (not just numpy) because we want autograd to compute the Greeks for us. The price function is written entirely in torch ops so it stays differentiable.

3Differentiable price function

Exactly the textbook Black-Scholes formula, but every operation goes through torch — log, sqrt, exp, multiply, subtract. That builds a computation graph from inputs to price.

5Compute d₁ with torch ops

Same algebra as the numpy version, but each operation registers as a node in the autograd graph. d₁ knows it depends on S, T, sigma so gradients can flow back later.

6Compute d₂

d₂ = d₁ − σ√T. Note d₂ depends on d₁ (which depends on S, T, σ) AND on T, σ directly — autograd handles both paths.

7Normal CDF as a torch function

torch.distributions.Normal(0,1).cdf evaluates N(x) and is differentiable: dN/dx = φ(x). That fact is the entire reason this approach works — Greeks emerge automatically.

8Build the call price

Price = S·N(d₁) − K·e^{−rT}·N(d₂). Pure torch ops, so the graph that backpropagation can traverse is complete.

12Mark S as a leaf with grad

requires_grad=True tells autograd 'I will want ∂(something)/∂S later'. Without this, ∂price/∂S returns None.

EXAMPLE
torch.autograd.grad(price, S) → Delta
13Mark sigma as a leaf with grad

Same idea — we want ∂price/∂σ = Vega.

14Mark T as a leaf with grad

We want ∂price/∂T. By convention Theta = ∂V/∂t = −∂V/∂T because t flows forward and T = expiry−t flows backward — that is why we flip the sign on line 21.

15K is a constant

No requires_grad — we are not differentiating with respect to the strike. The price still depends on K, but autograd will not bother building gradient edges for it.

18Forward pass

Evaluates the price and simultaneously records every operation. After this line, autograd has the full graph ready.

20Delta via autograd

torch.autograd.grad(price, S, create_graph=True) returns ∂price/∂S. create_graph=True keeps the graph alive so we can differentiate this output again (we will, to get Gamma).

EXAMPLE
Returns tensor(0.5695) — matches N(d₁) by hand.
21Vega via autograd

∂price/∂σ. No further differentiation will be done on this scalar, so create_graph=True is only strictly needed if you also want Vanna, Vomma, etc.

22Theta via autograd

Theta is defined with respect to calendar time t, but the formula is parameterized by time-to-expiry T. dT/dt = −1, so Θ = ∂V/∂t = −∂V/∂T. That is the only reason for the minus sign.

25Gamma as a second derivative

Γ = ∂²V/∂S² = ∂Δ/∂S. Because we asked autograd to keep delta's graph alive (create_graph=True on line 20), we can now differentiate delta itself. One line — no manual chain rule, no φ(d₁) bookkeeping.

EXAMPLE
Returns tensor(0.0394) — matches the closed-form Gamma.
27Print results

Compare these against the plain-Python output. They agree to 6 decimals because both implementations evaluate exactly the same formulas — autograd just spares us from typing the derivatives.

16 lines without explanation
1import torch
2
3def black_scholes_call_torch(S, K, T, r, sigma):
4    """Black-Scholes call price using torch ops so we can differentiate it."""
5    d1 = (torch.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * torch.sqrt(T))
6    d2 = d1 - sigma * torch.sqrt(T)
7    Ncdf = torch.distributions.Normal(0.0, 1.0).cdf
8    price = S * Ncdf(d1) - K * torch.exp(-r * T) * Ncdf(d2)
9    return price
10
11# Treat every market variable we want a Greek for as a leaf with grad.
12S     = torch.tensor(100.0, requires_grad=True)
13sigma = torch.tensor(0.20,  requires_grad=True)
14T     = torch.tensor(0.25,  requires_grad=True)
15K     = torch.tensor(100.0)
16r     = torch.tensor(0.05)
17
18price = black_scholes_call_torch(S, K, T, r, sigma)
19
20# First derivatives — Delta, Vega, Theta (Theta is negative dV/dT).
21delta = torch.autograd.grad(price, S,     create_graph=True)[0]
22vega  = torch.autograd.grad(price, sigma, create_graph=True)[0]
23theta = -torch.autograd.grad(price, T,    create_graph=True)[0]
24
25# Gamma is the derivative of Delta with respect to S.
26gamma = torch.autograd.grad(delta, S)[0]
27
28print("price :", price.item())
29print("delta :", delta.item())
30print("gamma :", gamma.item())
31print("vega  :", vega.item())
32print("theta :", theta.item())

Expected output:

price : 4.6149974...
delta : 0.5694603...
gamma : 0.0392612...
vega  : 19.641888...
theta : -10.472929...

Identical to the closed-form numbers. You wrote the price formula once; autograd produced every Greek by walking the same computation graph backwards. This is the same machinery that backpropagates losses through neural networks — applied to a Black-Scholes price instead.

For an exotic payoff such as an Asian or barrier option there is often no closed-form Greek at all. You evaluate the price by Monte Carlo, ask autograd for V/S\partial V / \partial S, and the same code that just printed Delta keeps working. This is the modern way derivatives desks compute Greeks at scale.

Application: Delta Hedging

Suppose a market-maker sells one ATM call for C=4.61C = 4.61. They now have exposure Δ=0.57-\Delta = -0.57 to the stock — if SS rises, they lose money. To neutralize this risk they immediately buy 0.570.57 shares.

After hedging, the portfolio value is Π=C+ΔS\Pi = -C + \Delta S. Its sensitivity to the stock is, by construction:

ΠS=CS+Δ=Δ+Δ=0.\displaystyle \frac{\partial \Pi}{\partial S} = -\frac{\partial C}{\partial S} + \Delta = -\Delta + \Delta = 0.

First-order risk gone. But what is left? Apply the Taylor expansion from earlier:

dΠ    12Γ(dS)2    Θdt\displaystyle d\Pi \;\approx\; -\tfrac{1}{2}\Gamma (dS)^2 \;-\; \Theta\, dt

The short-call position has negative Gamma (so the first term is negative — the trader loses if the stock moves a lot in either direction) and positive Theta (so the second term contributes positively as time passes — the trader collects rent).

The market-maker's bet: over a day, the stock moves less than what the implied volatility predicts. They collect Theta and pay only a small amount of Gamma. Repeated thousands of times with proper risk management, this is the business of being an options market-maker.

And rebalancing the hedge — buying or selling small numbers of shares as Δ\Delta drifts — is the practical reason traders watch Gamma all day. Big Gamma ⇒ Delta changes fast ⇒ rebalance often.


Summary

Every Greek in this section is a partial derivative of the Black-Scholes price. Once you see them as ordinary calculus objects, all of options trading becomes a story about the geometry of one surface.

GreekFormulaSign of long callWhen is it large?
ΔN(d₁)+ (0 to 1)Deep ITM
Γφ(d₁) / (S σ √τ)+ATM, short τ
Θ− S φ(d₁) σ / (2√τ) − r K e^{−rτ} N(d₂)ATM, short τ
νS φ(d₁) √τ+ATM, long τ

Take-aways:

  1. Delta is the slope; it tells you the equivalent stock position and the first-order hedge.
  2. Gamma is the curvature; it is always positive for a long option and creates the "free P&L when the stock moves" that everybody pays Theta for.
  3. Theta is the cost of holding optionality — mathematically 12σ2S2Γ-\tfrac{1}{2}\sigma^2 S^2 \Gamma appears inside Theta, which is how the Black-Scholes PDE locks them together.
  4. Vega tells you how today's price reacts to a shift in the volatility forecast — long options are long Vega, short options are short Vega.
  5. A second-order Taylor expansion in (S,t,σ)(S, t, \sigma) decomposes every day's option P&L into a sum of Greek contributions. That decomposition is what every options trader stares at every morning.
  6. Computationally, autograd renders all the closed-form algebra optional: write the price, ask for derivatives, get every Greek for free.
Looking ahead. In the next section we invert the process: instead of taking σ\sigma as given and computing prices, we take prices from the market and back out the implied volatility. That single number — and the funny smile it traces out — is the market's opinion on every assumption in Black-Scholes at once.
Loading comments...