Black-Scholes Formula: European Option Pricing & Greeks

Michael BrenndoerferNovember 28, 202551 min read

Learn the Black-Scholes formula for European options with Python implementation. Covers derivation, the Greeks, put-call parity, and dividend adjustments.

Reading Level

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Black-Scholes Formula and European Option Pricing

In the previous chapter, we derived the Black-Scholes-Merton partial differential equation (PDE), which describes how the price of a derivative must evolve to prevent arbitrage opportunities. That PDE, while elegant, doesn't immediately tell us what an option is worth. To actually price an option, we need to solve the PDE subject to the appropriate boundary conditions.

This chapter presents the solution: the famous Black-Scholes formula for European options. Published by Fischer Black and Myron Scholes in 1973, with crucial contributions from Robert Merton, this formula transformed finance by providing the first closed-form solution for option prices. Before Black-Scholes, options traded with wide bid-ask spreads because traders couldn't agree on fair value. After Black-Scholes, the options market exploded in both volume and sophistication.

The formula expresses an option's price in terms of five observable or estimable quantities: the current stock price, the strike price, time to expiration, the risk-free interest rate, and the volatility of the underlying asset. The expected return of the stock does not appear in the formula. As we learned when studying risk-neutral valuation, we can price derivatives by pretending all assets grow at the risk-free rate, a consequence of the no-arbitrage principle.

We'll work through the solution to the Black-Scholes PDE, interpret each component of the resulting formula, implement it in Python, and verify that it satisfies fundamental relationships like put-call parity. We'll close with an introduction to the Greeks, the sensitivity measures that quantify how option prices respond to changes in the underlying parameters.

Solving the Black-Scholes PDE

Recall from the previous chapter that the Black-Scholes PDE for a derivative V(S,t)V(S,t) on a non-dividend-paying stock is:

Vt+12σ2S22VS2+rSVSrV=0\frac{\partial V}{\partial t} + \frac{1}{2}\sigma^2 S^2 \frac{\partial^2 V}{\partial S^2} + rS\frac{\partial V}{\partial S} - rV = 0

where:

  • VV: price of the derivative
  • tt: time
  • SS: price of the underlying asset
  • σ\sigma: volatility of the underlying asset
  • rr: risk-free interest rate

This equation captures a fundamental requirement: the price of any derivative must evolve in time so no riskless arbitrage profit can be extracted. Each term in the equation plays a specific role. The first term represents how the option price changes with the passage of time alone. The second term, involving the second derivative with respect to the stock price, captures the effect of the stock's random fluctuations, which is precisely why the volatility parameter appears squared and multiplied by S2S^2. The third term accounts for the drift in the option price due to the expected growth of the stock under risk-neutral dynamics. Finally, the last term ensures that the total return on any derivative equals the risk-free rate in a hedged portfolio.

To find the price of a European call option, we must solve this PDE subject to the boundary condition at expiration:

C(S,T)=max(SK,0)C(S,T) = \max(S - K, 0)

where:

  • C(S,T)C(S,T): value of the call option at expiration
  • SS: stock price at expiration
  • KK: strike price
  • TT: expiration time

This boundary condition states something intuitive: at the moment of expiration, an option is worth exactly its intrinsic value. If the stock price exceeds the strike, the call holder can buy the stock at KK and immediately sell it at SS, pocketing the difference. If the stock price falls below the strike, the call expires worthless. The mathematical challenge lies in determining what the option should be worth at any time before expiration, given that it will satisfy this terminal condition.

Transformation to the Heat Equation

The Black-Scholes PDE is a second-order linear parabolic PDE. While it looks complicated, it can be transformed into the heat equation, one of the most studied equations in mathematical physics. This transformation involves several changes of variables. Instead of solving the Black-Scholes PDE directly, we convert it into the well-studied heat equation. The heat equation describes how temperature diffuses through a material, and its solutions are extremely well understood.

First, we introduce dimensionless variables. Let τ=Tt\tau = T - t represent time to expiration, so τ\tau increases as we move backward from expiration. This reversal of time direction is natural because we know the option's value at expiration and want to work backward to find its present value. Define x=ln(S/K)x = \ln(S/K) to work with log-prices. This logarithmic transformation converts the multiplicative nature of stock price movements into an additive one, which simplifies the mathematics considerably. A stock that can move between $50 and $200 has log-price that ranges from ln(50/K)\ln(50/K) to ln(200/K)\ln(200/K), a much more symmetric range to work with. Finally, let u(x,τ)u(x,\tau) be a transformed version of the option price:

V(S,t)=Kerτv(x,τ)V(S,t) = K \cdot e^{-r\tau} \cdot v(x,\tau)

where:

  • V(S,t)V(S,t): original option price
  • KK: strike price
  • rr: risk-free rate
  • τ\tau: time to expiration
  • v(x,τ)v(x,\tau): transformed option price
  • xx: log-price variable

The factor erτe^{-r\tau} accounts for the time value of money, essentially expressing the transformed price in forward terms. The factor KK scales the problem so that the transformed variable vv is dimensionless, depending only on relative moneyness rather than absolute dollar amounts.

Applying these substitutions and simplifying using the chain rule transforms the Black-Scholes PDE into:

vτ=σ222vx2+(rσ22)vx\frac{\partial v}{\partial \tau} = \frac{\sigma^2}{2}\frac{\partial^2 v}{\partial x^2} + \left(r - \frac{\sigma^2}{2}\right)\frac{\partial v}{\partial x}

where:

  • vv: transformed option price
  • τ\tau: time to expiration
  • xx: log-price variable
  • σ\sigma: volatility
  • rr: risk-free rate

This equation is already simpler than the original because the coefficients are now constants rather than functions of SS. However, it still contains a first derivative term, which represents a drift in the log-price. To eliminate this drift and arrive at the standard heat equation, we perform one more transformation.

A further substitution of the form v(x,τ)=eαx+βτu(x,τ)v(x, \tau) = e^{\alpha x + \beta \tau}u(x, \tau) eliminates the first derivative term. By choosing the constants α\alpha and β\beta appropriately, specifically values that depend on the ratio of the risk-free rate to the volatility squared, we can make the first-order term vanish. This yields the standard heat equation:

uτ=σ222ux2\frac{\partial u}{\partial \tau} = \frac{\sigma^2}{2}\frac{\partial^2 u}{\partial x^2}

where:

  • uu: variable related to option price (after removing drift)
  • τ\tau: time to expiration
  • xx: spatial variable (log-price)
  • σ\sigma: volatility parameter

The heat equation has a well-known solution via the Green's function, also called the fundamental solution or heat kernel. The physical interpretation is illuminating: if you place a concentrated source of heat at a single point and watch how it spreads through a material, the temperature at any point and time is given by a Gaussian distribution centered at the original source. The solution involves convolving the initial condition with this Gaussian kernel, essentially averaging over all possible paths the "heat" (or in our case, the probability mass) could have traveled.

The General Solution

Working backward through the transformations, reversing each change of variables in sequence, the solution for a European call option emerges as:

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

where:

  • C(S,t)C(S,t): call option price
  • SS: current stock price
  • N()N(\cdot): cumulative standard normal distribution function
  • d1,d2d_1, d_2: standardized moneyness terms
  • KK: strike price
  • rr: risk-free interest rate
  • TtT-t: time to expiration

This formula expresses the option price as the difference between two terms, each involving the cumulative normal distribution function N()N(\cdot). The function N(x)N(x) gives the probability that a standard normal random variable is less than xx, and it appears here because the underlying stock price follows a lognormal distribution under geometric Brownian motion.

The terms d1d_1 and d2d_2 are defined as:

d1=ln(S/K)+(r+σ22)(Tt)σTtd_1 = \frac{\ln(S/K) + (r + \frac{\sigma^2}{2})(T-t)}{\sigma\sqrt{T-t}}

where:

  • SS: current stock price
  • KK: strike price
  • rr: risk-free rate
  • σ\sigma: volatility
  • TtT-t: time to expiration

The numerator of d1d_1 contains two parts. The first, ln(S/K)\ln(S/K), measures the current moneyness of the option in logarithmic terms. A positive value indicates the option is in-the-money, while a negative value indicates it is out-of-the-money. The second part, (r+σ2/2)(Tt)(r + \sigma^2/2)(T-t), represents the expected drift of the log-price over the remaining life of the option. The denominator, σTt\sigma\sqrt{T-t}, normalizes this quantity by the standard deviation of the log-price at expiration, converting it into a standardized z-score.

The second standardized term is:

d2=d1σTt=ln(S/K)+(rσ22)(Tt)σTtd_2 = d_1 - \sigma\sqrt{T-t} = \frac{\ln(S/K) + (r - \frac{\sigma^2}{2})(T-t)}{\sigma\sqrt{T-t}}

where:

  • d1d_1: first standardized term
  • σ\sigma: volatility
  • TtT-t: time to expiration
  • SS: current stock price
  • KK: strike price
  • rr: risk-free rate

Notice that d2d_2 differs from d1d_1 only in the sign of the σ2/2\sigma^2/2 term in the numerator. This seemingly small difference has a profound interpretation that we will explore shortly. The relationship d2=d1σTtd_2 = d_1 - \sigma\sqrt{T-t} shows that the two quantities differ by exactly one standard deviation of the log-return.

For a European put option, we can either solve the PDE with the put boundary condition P(S,T)=max(KS,0)P(S,T) = \max(K-S, 0), or use put-call parity. The result is:

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

where:

  • P(S,t)P(S,t): put option price
  • KK: strike price
  • rr: risk-free rate
  • TtT-t: time to expiration
  • SS: current stock price
  • N()N(\cdot): cumulative standard normal distribution function
  • d1,d2d_1, d_2: standardized moneyness terms

The put formula has a parallel structure to the call formula but with the terms reversed and the signs of the arguments to N()N(\cdot) flipped. This symmetry reflects the complementary nature of calls and puts: a call benefits when the stock rises above the strike, while a put benefits when the stock falls below the strike. The relationship between the two formulas is made precise by put-call parity.

These are the celebrated Black-Scholes formulas. Let's examine what each term means.

Anatomy of the Black-Scholes Formula

The call option formula C=SN(d1)KerτN(d2)C = SN(d_1) - Ke^{-r\tau}N(d_2) (where τ=Tt\tau = T-t) has a clear interpretation when viewed through the lens of risk-neutral valuation. To understand the formula, we must connect it to risk-neutral pricing, where a derivative's price is its discounted expected payoff:

C=erτEQ[max(STK,0)]C = e^{-r\tau} \mathbb{E}^{\mathbb{Q}}[\max(S_T - K, 0)]

where:

  • CC: call option price
  • rr: risk-free rate
  • τ\tau: time to expiration
  • EQ\mathbb{E}^{\mathbb{Q}}: expectation under the risk-neutral measure Q\mathbb{Q}
  • STS_T: stock price at expiration
  • KK: strike price

This expectation says that we imagine a world where all investors are indifferent to risk, so the stock grows at the risk-free rate on average. In this risk-neutral world, we calculate the average payoff of the option and then discount it back to today. This procedure gives the correct arbitrage-free price even though the real world is not risk-neutral.

This expectation can be decomposed into two pieces:

C=erτEQ[ST1ST>K]erτKPQ(ST>K)C = e^{-r\tau} \mathbb{E}^{\mathbb{Q}}[S_T \cdot \mathbf{1}_{S_T > K}] - e^{-r\tau} K \cdot \mathbb{P}^{\mathbb{Q}}(S_T > K)

where:

  • CC: call option price
  • rr: risk-free rate
  • τ\tau: time to expiration
  • STS_T: stock price at expiration
  • KK: strike price
  • 1ST>K\mathbf{1}_{S_T > K}: indicator function (1 if ST>KS_T > K, 0 otherwise)
  • PQ\mathbb{P}^{\mathbb{Q}}: probability under the risk-neutral measure

This decomposition separates the option's payoff into its two components: receiving the stock and paying the strike. The indicator function 1ST>K\mathbf{1}_{S_T > K} equals 1 when the option finishes in-the-money and 0 otherwise. The first term captures the expected value of receiving the stock in those scenarios where exercise occurs. The second term captures the expected cost of paying the strike price, again only in scenarios where exercise occurs.

The second term is straightforward: KerτN(d2)K e^{-r\tau} N(d_2) is the present value of paying the strike, weighted by the risk-neutral probability N(d2)N(d_2) that the option finishes in-the-money. This term has a clean economic interpretation. You can think of it as the cost of a contingent payment: you will pay KK at expiration, but only if ST>KS_T > K. The probability of this event under risk-neutral dynamics is N(d2)N(d_2), and we discount the expected payment back to today at the risk-free rate.

The first term requires more care. SN(d1)S \cdot N(d_1) represents the present value of receiving the stock conditional on exercise. The factor N(d1)N(d_1) isn't quite a probability in the usual sense. It is the expected stock price conditional on exercise, normalized appropriately. To be precise, when you compute the expected value of the stock price over only those outcomes where ST>KS_T > K, you get a number that depends not just on the probability of exercise but also on how high the stock price tends to be in those favorable scenarios. Stocks that are likely to exercise tend to be worth more when they do exercise, which creates a positive correlation that inflates the expected receipt above what simple probability would suggest.

Technically, N(d1)N(d_1) is the probability that ST>KS_T > K under a different probability measure, sometimes called the stock measure or share measure. This alternative measure reweights outcomes according to the stock price, giving more weight to high-stock-price scenarios. Under this measure, the probability of exercise is higher than N(d2)N(d_2) because we are overweighting exactly those outcomes where exercise occurs. The difference between N(d1)N(d_1) and N(d2)N(d_2) captures this reweighting effect.

Out[3]:
Visualization
The risk-neutral probability $N(d_2)$ and the share-measure probability $N(d_1)$ as functions of moneyness. Both probabilities increase with moneyness, but $N(d_1)$ is always higher, reflecting the correlation between high stock prices and exercise events.
The risk-neutral probability $N(d_2)$ and the share-measure probability $N(d_1)$ as functions of moneyness. Both probabilities increase with moneyness, but $N(d_1)$ is always higher, reflecting the correlation between high stock prices and exercise events.

The Role of Each Parameter

The five inputs to the Black-Scholes formula each affect option prices in intuitive ways. Understanding these relationships builds intuition for how options behave and why traders care about each parameter.

  • Stock price (SS): Higher stock prices increase call values and decrease put values. This is the most direct relationship: a call gives you the right to buy at KK, so the higher SS is relative to KK, the more valuable that right. If the stock is already trading at $120 and your strike is $100, the option has $20 of intrinsic value plus whatever time value remains. Mathematically, the stock price enters the formula directly in the first term and indirectly through d1d_1 and d2d_2.

  • Strike price (KK): Higher strikes decrease call values and increase put values. A call with a higher strike requires the stock to rise further to be profitable. Consider two calls, one with strike $100 and another with strike $110. The first call is easier to profit from because the stock needs only to exceed $100, not $110. The strike enters the formula in the second term and in the logarithm within d1d_1 and d2d_2.

  • Time to expiration (τ=Tt\tau = T-t): More time generally increases option values. This "time value" reflects the increased opportunity for favorable price movements. A six-month option has more time for the stock to make a large move than a one-month option. The relationship enters through τ\sqrt{\tau} in the formula, meaning time value doesn't grow linearly. This square root dependence is crucial: the first month of a six-month option is less valuable than the first month of a one-month option. Options lose value at an accelerating rate as expiration approaches, a phenomenon called time decay.

  • Risk-free rate (rr): Higher rates increase call values and decrease put values. The intuition is that buying a call is like a leveraged position in the stock. You get stock exposure while keeping your capital earning interest elsewhere. Higher rates make this implicit financing benefit more valuable. Additionally, higher rates reduce the present value of the strike payment, making it cheaper in today's dollars to acquire the stock at expiration.

  • Volatility (σ\sigma): Higher volatility increases both call and put values. This is perhaps the most important insight of the model. Because an option's downside is limited (you can only lose the premium), higher volatility creates more upside potential without proportionally increasing downside risk. Consider a call option when the stock is at $100 and the strike is $100. If volatility is very low, the stock will likely stay near $100 and the option will be worth little. If volatility is high, the stock might reach $120 or $80 with meaningful probability. The $120 outcome pays $20, while the $80 outcome pays nothing. Higher volatility increases the chance of reaching $120 without increasing the cost of the $80 outcome which is already zero.

Volatility as the Key Unknown

Four of the five Black-Scholes inputs are directly observable: you can look up the stock price, strike price, time to expiration, and risk-free rate. Only volatility must be estimated. This makes volatility the central challenge in option pricing, a topic we'll explore in depth when we study implied volatility and the volatility smile.

Understanding d1d_1 and d2d_2

The quantities d1d_1 and d2d_2 are standardized measures of "moneyness," expressing how far in- or out-of-the-money the option is, adjusted for time and volatility. These quantities serve as the arguments to the cumulative normal distribution function, converting the lognormal distribution of stock prices into a tractable form.

Consider d2d_2 first:

d2=ln(S/K)+(rσ22)τστd_2 = \frac{\ln(S/K) + (r - \frac{\sigma^2}{2})\tau}{\sigma\sqrt{\tau}}

where:

  • SS: stock price
  • KK: strike price
  • rr: risk-free rate
  • σ\sigma: volatility
  • τ\tau: time to expiration

To understand d2d_2, we need to recall how the stock price evolves under geometric Brownian motion. The numerator ln(S/K)+(rσ22)τ\ln(S/K) + (r - \frac{\sigma^2}{2})\tau is the expected log-return of the stock under the risk-neutral measure, relative to the strike. The term rσ2/2r - \sigma^2/2 appears rather than just rr because of the difference between arithmetic and geometric means. When a variable follows geometric Brownian motion with drift μ\mu, its expected logarithm grows at rate μσ2/2\mu - \sigma^2/2, not μ\mu. This correction factor, sometimes called the Itô correction or convexity adjustment, arises from the nonlinear relationship between a variable and its logarithm.

Recall that under geometric Brownian motion with drift rr, the expected log-price is:

E[lnST]=lnS+(rσ22)τ\mathbb{E}[\ln S_T] = \ln S + (r - \frac{\sigma^2}{2})\tau

where:

  • E[lnST]\mathbb{E}[\ln S_T]: expected log stock price at time TT
  • lnS\ln S: log of current stock price
  • rr: risk-free rate
  • σ\sigma: volatility
  • τ\tau: time to expiration

So the numerator equals E[lnST]lnK=E[ln(ST/K)]\mathbb{E}[\ln S_T] - \ln K = \mathbb{E}[\ln(S_T/K)]. This is the expected value of the log of the ratio of the terminal stock price to the strike. When this is positive, the stock is expected to end up above the strike on average. The denominator στ\sigma\sqrt{\tau} is the standard deviation of this log-return. The volatility of the log-price after time τ\tau is στ\sigma\sqrt{\tau}, reflecting the diffusion of prices over time. Thus d2d_2 measures how many standard deviations the expected log-price exceeds the log-strike, which is exactly the input you'd need to find P(ST>K)\mathbb{P}(S_T > K) using the normal distribution.

The quantity d1d_1 is similar but with a +σ22+\frac{\sigma^2}{2} term instead of σ22-\frac{\sigma^2}{2}. This difference of στ\sigma\sqrt{\tau} accounts for the convexity adjustment when computing expected values of lognormal variables. When we compute not just the probability of exercise but the expected stock price conditional on exercise, we need to account for the asymmetry of the lognormal distribution. High stock prices are further above the mean than low stock prices are below it, and this asymmetry inflates the expected value conditional on exceeding a threshold.

The technical explanation involves a change of measure: N(d1)N(d_1) is a probability under a different measure where the stock, rather than the money market account, is the numeraire. In this alternative measure, the stock price process has a higher drift, compensating for the fact that we're measuring things in stock units rather than dollar units. The result is that probabilities under the stock measure are systematically higher than under the risk-neutral measure for in-the-money events.

Put-Call Parity Revisited

As we learned when studying option basics, put-call parity is a fundamental relationship linking European call and put prices:

CP=SKerτC - P = S - Ke^{-r\tau}

where:

  • CC: call option price
  • PP: put option price
  • SS: stock price
  • KK: strike price
  • rr: risk-free rate
  • τ\tau: time to expiration

This relationship must hold regardless of any model assumptions; it is a pure arbitrage argument. If it were violated, you could construct a riskless profit by simultaneously buying the cheap side and selling the expensive side. The relationship says that a portfolio of a long call and a short put with the same strike and expiration replicates the payoff of owning the stock while owing the present value of the strike price.

Let's verify that the Black-Scholes formulas satisfy put-call parity. This verification serves two purposes: it confirms that our formulas are internally consistent, and it demonstrates the elegant symmetry properties of the normal distribution.

Starting with the Black-Scholes call and put formulas:

C=SN(d1)KerτN(d2)P=KerτN(d2)SN(d1)\begin{aligned} C &= S N(d_1) - K e^{-r\tau} N(d_2) \\ P &= K e^{-r\tau} N(-d_2) - S N(-d_1) \end{aligned}

where:

  • C,PC, P: call and put option prices
  • SS: stock price
  • KK: strike price
  • rr: risk-free rate
  • τ\tau: time to expiration
  • N()N(\cdot): cumulative standard normal distribution
  • d1,d2d_1, d_2: moneyness terms

We compute the difference CPC - P to verify the relationship. The key mathematical fact we will use is the symmetry of the standard normal distribution: N(x)+N(x)=1N(x) + N(-x) = 1 for any value of xx. This follows from the fact that the normal distribution is symmetric around zero, so the probability of being less than xx plus the probability of being greater than xx (which equals the probability of being less than x-x) must sum to one.

CP=[SN(d1)KerτN(d2)][KerτN(d2)SN(d1)](substitute formulas)=S[N(d1)+N(d1)]Kerτ[N(d2)+N(d2)](group terms)=S1Kerτ1(symmetry: N(x)+N(x)=1)=SKerτ(simplify)\begin{aligned} C - P &= [S N(d_1) - K e^{-r\tau} N(d_2)] - [K e^{-r\tau} N(-d_2) - S N(-d_1)] && \text{(substitute formulas)} \\ &= S [N(d_1) + N(-d_1)] - K e^{-r\tau} [N(d_2) + N(-d_2)] && \text{(group terms)} \\ &= S \cdot 1 - K e^{-r\tau} \cdot 1 && \text{(symmetry: } N(x) + N(-x) = 1\text{)} \\ &= S - K e^{-r\tau} && \text{(simplify)} \end{aligned}

where:

  • CC: call price
  • PP: put price
  • SS: stock price
  • KK: strike price
  • rr: risk-free rate
  • τ\tau: time to expiration

The Black-Scholes formulas are internally consistent and satisfy the no-arbitrage constraint of put-call parity. This verification is more than a mathematical exercise. It confirms that the formulas respect the fundamental arbitrage relationships that must hold in any well-functioning market. Any pricing model, no matter how sophisticated, must satisfy put-call parity. If a proposed option pricing formula violated this relationship, we would know immediately that it contains an error.

Out[4]:
Visualization
Comparison of the difference between call and put prices (blue) and the forward value $S - Ke^{-rT}$ (red dashed). The perfect overlap confirms that the Black-Scholes formulas satisfy the no-arbitrage put-call parity relationship.
Comparison of the difference between call and put prices (blue) and the forward value $S - Ke^{-rT}$ (red dashed). The perfect overlap confirms that the Black-Scholes formulas satisfy the no-arbitrage put-call parity relationship.

Implementing the Black-Scholes Formula

Let's implement the Black-Scholes formula in Python and explore its behavior. We'll build up from simple functions to a complete implementation.

In[5]:
Code
import numpy as np
from scipy.stats import norm


def black_scholes_call(S, K, T, r, sigma):
    """
    Calculate Black-Scholes price for a European call option.

    Parameters:
        S: Current stock price
        K: Strike price
        T: Time to expiration (in years)
        r: Risk-free interest rate (annualized)
        sigma: Volatility (annualized)

    Returns:
        Call option price
    """
    if T <= 0:
        return max(S - K, 0)  # At expiration, return intrinsic value

    d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)

    call_price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
    return call_price


def black_scholes_put(S, K, T, r, sigma):
    """
    Calculate Black-Scholes price for a European put option.
    """
    if T <= 0:
        return max(K - S, 0)

    d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)

    put_price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
    return put_price

Now let's calculate option prices for a specific example:

In[6]:
Code
# Example parameters
S = 100  # Current stock price: $100
K = 105  # Strike price: $105
T = 0.5  # Time to expiration: 6 months
r = 0.05  # Risk-free rate: 5%
sigma = 0.20  # Volatility: 20%

call_price = black_scholes_call(S, K, T, r, sigma)
put_price = black_scholes_put(S, K, T, r, sigma)
Out[7]:
Console
Black-Scholes Option Pricing Example
========================================
Stock Price (S):     $100.00
Strike Price (K):    $105.00
Time to Expiry (T):  0.50 years (6 months)
Risk-free Rate (r):  5.0%
Volatility (σ):      20.0%
----------------------------------------
Call Option Price:   $4.5817
Put Option Price:    $6.9892

The call option on this slightly out-of-the-money stock has a lower value than the put, which holds intrinsic value. Let's verify put-call parity holds:

In[8]:
Code
# Verify put-call parity: C - P = S - K*exp(-rT)
lhs = call_price - put_price
rhs = S - K * np.exp(-r * T)
parity_difference = abs(lhs - rhs)
Out[9]:
Console
Put-Call Parity Verification
========================================
C - P = -2.4075
S - K*exp(-rT) = -2.4075
Difference: 0.00e+00
Put-call parity holds

The difference of effectively zero confirms that our implementation satisfies the fundamental no-arbitrage relationship required by put-call parity.

Examining the Intermediate Calculations

Understanding the intermediate values d1d_1 and d2d_2 helps build intuition for how the formula works:

In[10]:
Code
def compute_d1_d2(S, K, T, r, sigma):
    """Compute d1 and d2 with detailed breakdown."""
    log_moneyness = np.log(S / K)
    drift_term = (r + 0.5 * sigma**2) * T
    diffusion = sigma * np.sqrt(T)

    d1 = (log_moneyness + drift_term) / diffusion
    d2 = d1 - diffusion

    return d1, d2, log_moneyness, drift_term, diffusion


d1, d2, log_moneyness, drift_term, diffusion = compute_d1_d2(S, K, T, r, sigma)
Out[11]:
Console
Breakdown of d1 and d2 Calculations
=============================================
ln(S/K) = ln(100/105) = -0.0488
Drift term (r + σ²/2)T = 0.0350
Diffusion σ√T = 0.1414
---------------------------------------------
d1 = (ln(S/K) + drift) / diffusion = -0.0975
d2 = d1 - σ√T = -0.2389
---------------------------------------------
N(d1) = 0.4612 (probability under share measure)
N(d2) = 0.4056 (risk-neutral probability ITM)

The negative d2d_2 value tells us there's less than a 50% risk-neutral probability that this option finishes in-the-money. The value of N(d2)N(d_2) calculated above represents the precise probability of the stock price exceeding the strike at expiration under the risk-neutral measure.

Key Parameters

The key parameters for the Black-Scholes implementation are:

  • SS: Current stock price. Higher prices increase call values and decrease put values.
  • KK: Strike price. The reference price for the option's payoff.
  • TT: Time to expiration in years. Longer times generally increase option values.
  • rr: Risk-free interest rate (annualized). Higher rates favor calls over puts.
  • σ\sigma: Volatility (annualized). Determines the range of potential future stock prices; higher volatility increases value for both calls and puts.

Option Price Sensitivity to Inputs

Let's visualize how option prices change with respect to each input parameter. This builds intuition for the Greeks, which we'll introduce formally later in this chapter.

In[12]:
Code
# Calculate price sensitivity to spot price
spot_range = np.linspace(70, 130, 100)
calls_by_spot = [black_scholes_call(s, K, T, r, sigma) for s in spot_range]
puts_by_spot = [black_scholes_put(s, K, T, r, sigma) for s in spot_range]
In[13]:
Code
fig, ax = plt.subplots(figsize=(6.0, 4.0))
ax.plot(spot_range, calls_by_spot, "b-", linewidth=2, label="Call")
ax.plot(spot_range, puts_by_spot, "r-", linewidth=2, label="Put")
ax.axvline(x=K, color="gray", linestyle="--", alpha=0.5, label=f"Strike = ${K}")
ax.axhline(y=0, color="black", linewidth=0.5)
ax.set_xlabel("Stock Price ($)")
ax.set_ylabel("Option Price ($)")
ax.set_title("Option Price vs. Underlying Stock Price")
ax.legend()
ax.grid(True, alpha=0.3)
ax.set_xlim(70, 130)
plt.show()
Out[13]:
Visualization
Line chart showing call price increasing and put price decreasing as stock price rises from 70 to 130.
Call and put option prices as a function of the underlying stock price. The call value increases with stock price while the put value decreases. Both curves show characteristic convexity near the strike price.

The curves show the characteristic "hockey stick" shape approaching expiration, but smoothed by time value. Notice how both options have positive value even when out-of-the-money. This is the time value component.

In[14]:
Code
# Calculate price sensitivity to volatility
vol_range = np.linspace(0.05, 0.60, 100)
calls_by_vol = [black_scholes_call(S, K, T, r, v) for v in vol_range]
puts_by_vol = [black_scholes_put(S, K, T, r, v) for v in vol_range]
In[15]:
Code
fig, ax = plt.subplots(figsize=(6.0, 4.0))
ax.plot(vol_range * 100, calls_by_vol, "b-", linewidth=2, label="Call")
ax.plot(vol_range * 100, puts_by_vol, "r-", linewidth=2, label="Put")
ax.axvline(
    x=sigma * 100,
    color="gray",
    linestyle="--",
    alpha=0.5,
    label=rf"Current $\sigma$ = {sigma:.0%}",
)
ax.set_xlabel("Volatility (%)")
ax.set_ylabel("Option Price ($)")
ax.set_title("Option Price vs. Volatility")
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()
Out[15]:
Visualization
Line chart showing both call and put prices increasing as volatility rises from 5% to 60%.
Call and put option prices versus volatility. Prices increase monotonically with volatility, illustrating that higher uncertainty increases the value of optionality. This monotonic relationship allows implied volatility to be uniquely determined from market prices.

The monotonic relationship between option prices and volatility is crucial. Since all other inputs are directly observable, if you know an option's market price, you can "invert" the Black-Scholes formula to find the volatility that would produce that price. This implied volatility becomes a key market observable, which we'll study in a later chapter.

In[16]:
Code
# Calculate price sensitivity to time
time_range = np.linspace(0.01, 1.0, 100)
calls_by_time = [black_scholes_call(S, K, t, r, sigma) for t in time_range]
puts_by_time = [black_scholes_put(S, K, t, r, sigma) for t in time_range]
In[17]:
Code
fig, ax = plt.subplots(figsize=(6.0, 4.0))
ax.plot(time_range * 12, calls_by_time, "b-", linewidth=2, label="Call")
ax.plot(time_range * 12, puts_by_time, "r-", linewidth=2, label="Put")
ax.axvline(
    x=T * 12,
    color="gray",
    linestyle="--",
    alpha=0.5,
    label=f"Current T = {T * 12:.0f} months",
)
ax.set_xlabel("Time to Expiration (months)")
ax.set_ylabel("Option Price ($)")
ax.set_title("Option Price vs. Time to Expiration")
ax.legend()
ax.grid(True, alpha=0.3)
ax.invert_xaxis()  # Time decreases as we approach expiration
plt.show()
Out[17]:
Visualization
Line chart showing call and put prices declining from 1 year to 0 years to expiration.
Call and put option prices versus time to expiration. As expiration approaches (moving left to right), option values decline toward their intrinsic values, illustrating the accelerating impact of time decay.

As time passes, option prices decay toward their intrinsic values. This time decay (quantified by the Greek letter theta) is a critical consideration for option traders, particularly those holding long positions.

Out[18]:
Visualization
Option price surface showing how call prices vary with both stock price and time to expiration. The surface demonstrates that time value is highest for at-the-money options and diminishes as expiration approaches.
Option price surface showing how call prices vary with both stock price and time to expiration. The surface demonstrates that time value is highest for at-the-money options and diminishes as expiration approaches.

Introduction to the Greeks

The Greeks are partial derivatives of the option price with respect to various inputs. They quantify how sensitive an option's price is to small changes in market conditions. Understanding the Greeks is essential for risk management and hedging. Each Greek measures a different dimension of risk, and together they provide a complete picture of an option position's exposure to market movements.

The Greeks derive their importance from the dynamic nature of hedging. As we learned when studying the derivation of the Black-Scholes PDE, perfect replication of an option requires continuous adjustment of a hedge portfolio. The Greeks tell us exactly how to perform these adjustments and quantify the risks that arise when hedging is imperfect or infrequent.

The Greeks

The Greeks are named after Greek letters and measure the sensitivity of option prices to changes in underlying parameters. The five primary Greeks are Delta, Gamma, Theta, Vega (not actually Greek), and Rho.

Delta: Sensitivity to Stock Price

Delta (Δ\Delta) measures how much the option price changes when the stock price moves by $1. This is the most fundamental Greek because it directly connects the option's value to movements in the underlying asset. Delta answers the practical question: if the stock moves, how much does your option position change in value?

Δcall=CS=N(d1)\Delta_{\text{call}} = \frac{\partial C}{\partial S} = N(d_1)

where:

  • Δcall\Delta_{\text{call}}: delta of the call option
  • CC: call option price
  • SS: stock price
  • N(d1)N(d_1): cumulative normal distribution value at d1d_1

The result that call delta equals N(d1)N(d_1) comes directly from differentiating the Black-Scholes formula. The derivative of the first term SN(d1)S \cdot N(d_1) with respect to SS is not simply N(d1)N(d_1) because d1d_1 itself depends on SS. However, when we carefully apply the chain rule, the additional terms cancel out, leaving just N(d1)N(d_1). This cancellation is not coincidental; it reflects a deep property of the Black-Scholes formula related to the self-financing nature of the replicating portfolio.

Δput=PS=N(d1)1=N(d1)\begin{aligned} \Delta_{\text{put}} &= \frac{\partial P}{\partial S} \\ &= N(d_1) - 1 \\ &= -N(-d_1) \end{aligned}

where:

  • Δput\Delta_{\text{put}}: delta of the put option
  • PP: put option price
  • SS: stock price
  • N(d1)N(d_1): cumulative normal distribution value at d1d_1
  • N(d1)N(-d_1): cumulative normal distribution value at d1-d_1

Call deltas range from 0 to 1, while put deltas range from -1 to 0. An at-the-money call has a delta near 0.5, meaning it moves about $0.50 for every $1 move in the stock. A deep in-the-money call has delta close to 1, moving nearly dollar-for-dollar with the stock. A deep out-of-the-money call has delta close to 0, barely responding to stock movements because the option is unlikely to ever be exercised.

Delta also has an interpretation as a hedge ratio: to hedge a short call position, you should hold Δ\Delta shares of stock. If you sell a call with delta 0.5, you need to buy 0.5 shares to neutralize your exposure to small stock price movements. This hedge ratio must be continuously updated as the stock price moves and as time passes, which is why delta hedging is dynamic rather than static.

Gamma: Sensitivity of Delta to Stock Price

Gamma (Γ\Gamma) measures how quickly delta changes as the stock moves by $1. This second-order sensitivity is crucial because it tells us how stable our delta hedge will be. High gamma means that even small moves in the stock price will significantly change the delta, requiring frequent rebalancing of the hedge.

Γ=2VS2=N(d1)SσTt\Gamma = \frac{\partial^2 V}{\partial S^2} = \frac{N'(d_1)}{S \sigma \sqrt{T-t}}

where:

  • Γ\Gamma: gamma of the option
  • VV: option price (call or put)
  • SS: stock price
  • N(d1)N'(d_1): standard normal probability density at d1d_1
  • σ\sigma: volatility
  • TtT-t: time to expiration

Note that N(x)=12πex2/2N'(x) = \frac{1}{\sqrt{2\pi}}e^{-x^2/2} is the standard normal probability density function. The appearance of the PDF rather than the CDF in gamma reflects the fact that gamma measures the rate of change of a probability. When the stock price moves, the probability of exercise changes, and gamma quantifies how rapidly this change occurs.

Gamma is the same for calls and puts with the same strike and expiration. This equality follows from put-call parity: since CP=SKerτC - P = S - Ke^{-r\tau}, and the right-hand side is linear in SS, the second derivative with respect to SS must be identical for calls and puts.

High gamma means the option's delta is unstable, requiring frequent rebalancing of hedges. At-the-money options near expiration have the highest gamma because small price movements can flip the option from out-of-the-money to in-the-money or vice versa, causing dramatic changes in delta. Gamma is a double-edged sword: long gamma positions benefit from realized volatility through the convexity of their payoff, but they also face the cost and complexity of frequent rebalancing.

Theta: Sensitivity to Time

Theta (Θ\Theta) measures how much the option price decreases as time passes, holding all else constant. This is the only Greek that does not measure sensitivity to a market variable; instead, it captures the inexorable erosion of time value as expiration approaches. Time is the one factor that moves in only one direction, making theta fundamentally different from other risks.

Θcall=Ct=SN(d1)σ2TtrKer(Tt)N(d2)\Theta_{\text{call}} = \frac{\partial C}{\partial t} = -\frac{S N'(d_1) \sigma}{2\sqrt{T-t}} - rKe^{-r(T-t)}N(d_2)

where:

  • Θcall\Theta_{\text{call}}: theta of the call option
  • SS: stock price
  • N(d1)N'(d_1): standard normal PDF at d1d_1
  • σ\sigma: volatility
  • TtT-t: time to expiration
  • rr: risk-free rate
  • KK: strike price
  • N(d2)N(d_2): cumulative normal CDF at d2d_2

The formula consists of two components, each with a distinct economic interpretation:

  • SN(d1)σ2Tt-\frac{S N'(d_1) \sigma}{2\sqrt{T-t}}: Represents the erosion of value due to the resolution of uncertainty (volatility decay). As time passes, there is less time for favorable price movements to occur. This term is always negative, reflecting the fact that options lose optionality value over time.
  • rKer(Tt)N(d2)- rKe^{-r(T-t)}N(d_2): Represents the loss of the interest-free leverage benefit as expiration approaches. A call option allows you to defer payment of the strike price until expiration. As expiration nears, this deferral benefit shrinks. For puts, this term has the opposite sign because puts involve receiving the strike rather than paying it.

Theta is typically negative for long option positions. Options lose value as time passes. This is the "cost" of holding optionality. The magnitude of theta increases as expiration approaches, especially for at-the-money options. This acceleration of time decay near expiration is sometimes called "time decay speeding up" and is a critical concern for option holders.

The relationship between theta and gamma is fundamental. The Black-Scholes PDE can be rearranged to show that, for a delta-hedged position, theta plus a term proportional to gamma must sum to the risk-free rate times the option value. This theta-gamma tradeoff means that positions with high positive gamma (which benefit from volatility) must pay high negative theta (losing value over time), and vice versa.

Vega: Sensitivity to Volatility

Vega (ν\nu or V\mathcal{V}) measures how much the option price changes when volatility moves by one percentage point. Despite being called "vega," this Greek is not named after an actual Greek letter, but the convention is so established that the name persists. Vega is arguably the most important Greek for option traders because volatility is the only unobservable input to the Black-Scholes formula and the one where traders have the most disagreement.

ν=Vσ=STtN(d1)\nu = \frac{\partial V}{\partial \sigma} = S \sqrt{T-t} \cdot N'(d_1)

where:

  • ν\nu: vega of the option
  • VV: option price
  • SS: stock price
  • TtT-t: time to expiration
  • N(d1)N'(d_1): standard normal PDF at d1d_1

Vega is the same for calls and puts and is always positive; higher volatility benefits option holders. This makes economic sense: volatility expands the range of possible future stock prices, and since options have limited downside (you can never lose more than the premium) but unlimited upside, more dispersion in outcomes is always favorable.

Vega is largest for at-the-money options and for options with longer time to expiration. At-the-money options are most sensitive to volatility because they are on the knife's edge between expiring worthless and expiring with value. Small changes in volatility significantly affect the probability of crossing the strike. Longer-dated options have more vega because there is more time for volatility to manifest as actual price movements.

When traders speak of "trading volatility," they typically mean taking positions that profit from changes in implied volatility. A trader who buys options has positive vega exposure and profits if volatility rises. A trader who sells options has negative vega exposure and profits if volatility falls.

Rho: Sensitivity to Interest Rate

Rho (ρ\rho) measures how much the option price changes when the risk-free rate moves. Interest rate sensitivity is typically smaller than sensitivity to other parameters, but it can become significant for long-dated options or in environments where rates are changing rapidly.

ρcall=Cr=K(Tt)er(Tt)N(d2)\rho_{\text{call}} = \frac{\partial C}{\partial r} = K(T-t)e^{-r(T-t)}N(d_2)

where:

  • ρcall\rho_{\text{call}}: rho of the call option
  • KK: strike price
  • TtT-t: time to expiration
  • rr: risk-free rate
  • N(d2)N(d_2): cumulative normal CDF at d2d_2

Call rho is positive because higher interest rates reduce the present value of the strike payment while leaving the current stock price unchanged. A call holder benefits from this because they pay the strike in the future, and higher rates make that future payment cheaper in today's dollars.

ρput=Pr=K(Tt)er(Tt)N(d2)\rho_{\text{put}} = \frac{\partial P}{\partial r} = -K(T-t)e^{-r(T-t)}N(-d_2)

where:

  • ρput\rho_{\text{put}}: rho of the put option
  • PP: put option price
  • KK: strike price
  • TtT-t: time to expiration
  • rr: risk-free rate
  • N(d2)N(-d_2): cumulative normal CDF at d2-d_2

Put rho is negative because put holders receive the strike price upon exercise. Higher interest rates make this future receipt less valuable in present terms. The magnitude of rho is proportional to time to expiration: the longer the option's life, the more time there is for interest rate effects to accumulate.

Rho is typically the least important Greek for equity options, since interest rate changes are usually small relative to stock price and volatility moves. However, for interest rate derivatives or long-dated equity options (LEAPS), rho can be a significant risk factor.

Computing the Greeks

Let's implement and calculate the Greeks for our example option:

In[19]:
Code
def black_scholes_greeks(S, K, T, r, sigma, option_type="call"):
    """
    Calculate Black-Scholes price and Greeks for a European option.

    Returns dictionary with price and all Greeks.
    """
    if T <= 0:
        # At expiration, return limit values
        if option_type == "call":
            price = max(S - K, 0)
            delta = 1.0 if S > K else 0.0
        else:
            price = max(K - S, 0)
            delta = -1.0 if S < K else 0.0
        return {
            "price": price,
            "delta": delta,
            "gamma": 0,
            "theta": 0,
            "vega": 0,
            "rho": 0,
        }

    sqrt_T = np.sqrt(T)
    d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt_T)
    d2 = d1 - sigma * sqrt_T

    # Standard normal PDF at d1
    n_d1 = norm.pdf(d1)

    # Common terms
    discount = np.exp(-r * T)

    if option_type == "call":
        price = S * norm.cdf(d1) - K * discount * norm.cdf(d2)
        delta = norm.cdf(d1)
        theta = -S * n_d1 * sigma / (2 * sqrt_T) - r * K * discount * norm.cdf(
            d2
        )
        rho = K * T * discount * norm.cdf(d2)
    else:
        price = K * discount * norm.cdf(-d2) - S * norm.cdf(-d1)
        delta = norm.cdf(d1) - 1  # Equivalent to -N(-d1)
        theta = -S * n_d1 * sigma / (2 * sqrt_T) + r * K * discount * norm.cdf(
            -d2
        )
        rho = -K * T * discount * norm.cdf(-d2)

    # Gamma and Vega are the same for calls and puts
    gamma = n_d1 / (S * sigma * sqrt_T)
    vega = S * sqrt_T * n_d1

    # Convert theta to daily and vega to per 1% vol change
    theta_daily = theta / 365
    vega_percent = vega / 100

    return {
        "price": price,
        "delta": delta,
        "gamma": gamma,
        "theta": theta,
        "theta_daily": theta_daily,
        "vega": vega,
        "vega_pct": vega_percent,
        "rho": rho,
    }


call_greeks = black_scholes_greeks(S, K, T, r, sigma, "call")
put_greeks = black_scholes_greeks(S, K, T, r, sigma, "put")
Out[20]:
Console
Greeks for European Options
=======================================================
Greek        Call                 Put                 
-------------------------------------------------------
Price        $4.5817              $6.9892             
Delta        0.4612               -0.5388             
Gamma        0.0281               0.0281              
Theta (ann)  -7.6919              -2.5715             
Theta (day)  -0.0211              -0.0070             
Vega (/1%)   0.2808               0.2808              
Rho          20.7672              -30.4366            

Let's interpret these values:

Out[21]:
Console

Interpretation of the Greeks:
-------------------------------------------------------
• If the stock rises $1, the call gains $0.46
  and the put loses $0.54
• Each day that passes, the call loses $0.0211
• If volatility rises 1%, the call gains $0.2808
• Gamma of 0.0281 means delta changes ~0.03
  for each $1 move in the stock

Visualizing Delta Across Strikes

In[22]:
Code
# Calculate delta across strikes
strike_range = np.linspace(70, 130, 100)
call_deltas = []
put_deltas = []

for k in strike_range:
    cg = black_scholes_greeks(S, k, T, r, sigma, "call")
    pg = black_scholes_greeks(S, k, T, r, sigma, "put")
    call_deltas.append(cg["delta"])
    put_deltas.append(pg["delta"])
In[23]:
Code
fig, ax = plt.subplots(figsize=(6.0, 4.0))
ax.plot(strike_range, call_deltas, "b-", linewidth=2, label="Call Delta")
ax.plot(strike_range, put_deltas, "r-", linewidth=2, label="Put Delta")
ax.axhline(y=0, color="black", linewidth=0.5)
ax.axhline(y=0.5, color="gray", linestyle=":", alpha=0.5)
ax.axhline(y=-0.5, color="gray", linestyle=":", alpha=0.5)
ax.axvline(x=S, color="green", linestyle="--", alpha=0.5, label=f"Spot = ${S}")
ax.set_xlabel("Strike Price ($)")
ax.set_ylabel("Delta")
ax.set_title("Option Delta vs. Strike Price")
ax.legend()
ax.grid(True, alpha=0.3)
ax.set_ylim(-1.1, 1.1)
plt.show()
Out[23]:
Visualization
Line chart showing call delta decreasing from 1 to 0 and put delta from 0 to -1 as strike increases.
Call and put delta as a function of strike price. Deep in-the-money calls have delta near 1, while deep out-of-the-money calls have delta near 0. Put delta follows a parallel pattern shifted by -1.

The plot illustrates how delta varies across different strike prices. For deep in-the-money calls (low strikes), delta approaches 1, indicating the option moves tick-for-tick with the stock. For deep out-of-the-money calls (high strikes), delta approaches 0. This curvature is captured by Gamma.

Out[24]:
Visualization
Gamma across strike prices for options with different times to expiration. Near-expiration options exhibit dramatically higher gamma near the strike, reflecting the knife-edge nature of exercise decisions as expiration approaches.
Gamma across strike prices for options with different times to expiration. Near-expiration options exhibit dramatically higher gamma near the strike, reflecting the knife-edge nature of exercise decisions as expiration approaches.
Out[25]:
Visualization
Gamma sensitivity across stock price and time to expiration. The concentration of high gamma values (dark red) for at-the-money options near expiration creates the 'gamma mountain,' indicating regions of highest hedging instability.
Gamma sensitivity across stock price and time to expiration. The concentration of high gamma values (dark red) for at-the-money options near expiration creates the 'gamma mountain,' indicating regions of highest hedging instability.
Out[26]:
Visualization
Theta (daily time decay) for at-the-money options as expiration approaches. The decay accelerates dramatically in the final weeks, illustrating why short-dated options are often described as 'melting ice cubes.
Theta (daily time decay) for at-the-money options as expiration approaches. The decay accelerates dramatically in the final weeks, illustrating why short-dated options are often described as 'melting ice cubes.

The next chapter provides comprehensive coverage of the Greeks, including their use in hedging strategies, portfolio risk management, and the dynamics of delta-hedged positions.

Extending to Dividend-Paying Stocks

The basic Black-Scholes formula assumes the stock pays no dividends. For stocks that pay a continuous dividend yield qq, we can modify the formula by replacing SS with SeqτSe^{-q\tau}. The intuition behind this adjustment is that dividend payments reduce the effective growth rate of the stock price. An investor who holds the stock receives dividends, but an investor who holds a call option does not. The option holder misses out on this cash flow, making the option less valuable.

The modified call pricing formula becomes:

C=SeqτN(d1)KerτN(d2)C = Se^{-q\tau}N(d_1) - Ke^{-r\tau}N(d_2)

where:

  • CC: call option price
  • SS: stock price
  • qq: continuous dividend yield
  • τ\tau: time to expiration
  • N()N(\cdot): cumulative standard normal CDF
  • KK: strike price
  • rr: risk-free rate

The factor eqτe^{-q\tau} discounts the stock price by the cumulative dividend yield over the option's life. Economically, this represents the fact that the stock will be worth less (by the amount of dividends paid out) at expiration than it would be without dividends. The call option, which only benefits from the terminal stock price, must account for this reduction.

The parameters d1d_1 and d2d_2 are modified as follows:

d1=ln(S/K)+(rq+σ22)τστd_1 = \frac{\ln(S/K) + (r - q + \frac{\sigma^2}{2})\tau}{\sigma\sqrt{\tau}}

where:

  • SS: stock price
  • KK: strike price
  • rr: risk-free rate
  • qq: dividend yield
  • σ\sigma: volatility
  • τ\tau: time to expiration

The key change is that rqr - q replaces rr in the drift term. The effective growth rate of the stock under the risk-neutral measure is now the risk-free rate minus the dividend yield. This makes sense: dividends represent cash flowing out of the stock, reducing its expected appreciation rate.

d2=d1στd_2 = d_1 - \sigma\sqrt{\tau}

where:

  • d1d_1: standardized moneyness term
  • σ\sigma: volatility
  • τ\tau: time to expiration

The relationship between d1d_1 and d2d_2 remains unchanged; they still differ by exactly στ\sigma\sqrt{\tau}.

The dividend yield reduces the call value and increases the put value. Intuitively, dividends represent cash flows that benefit stockholders but not call option holders (who don't receive dividends until they exercise). Put holders, conversely, benefit from dividends because dividends reduce the stock price, making it more likely that the put will finish in-the-money.

In[27]:
Code
def black_scholes_dividend(S, K, T, r, sigma, q, option_type="call"):
    """
    Black-Scholes with continuous dividend yield q.
    """
    if T <= 0:
        if option_type == "call":
            return max(S - K, 0)
        else:
            return max(K - S, 0)

    sqrt_T = np.sqrt(T)
    d1 = (np.log(S / K) + (r - q + 0.5 * sigma**2) * T) / (sigma * sqrt_T)
    d2 = d1 - sigma * sqrt_T

    if option_type == "call":
        price = S * np.exp(-q * T) * norm.cdf(d1) - K * np.exp(
            -r * T
        ) * norm.cdf(d2)
    else:
        price = K * np.exp(-r * T) * norm.cdf(-d2) - S * np.exp(
            -q * T
        ) * norm.cdf(-d1)

    return price


# Compare prices with and without dividend
q = 0.02  # 2% dividend yield
call_no_div = black_scholes_call(S, K, T, r, sigma)
call_with_div = black_scholes_dividend(S, K, T, r, sigma, q, "call")
put_no_div = black_scholes_put(S, K, T, r, sigma)
put_with_div = black_scholes_dividend(S, K, T, r, sigma, q, "put")
Out[28]:
Console
Effect of Dividend Yield on Option Prices
==================================================
Dividend yield: 2.0%
--------------------------------------------------
Option          No Dividend     With Dividend  
Call            $4.5817         $4.1367        
Put             $6.9892         $7.5393        
--------------------------------------------------
Call reduction due to dividend: $0.4450
Put increase due to dividend: $0.5501

The output shows that the dividend yield reduces the call price and increases the put price. This occurs because the dividend drops the expected stock price at expiration, making the call less likely to finish in-the-money and the put more likely.

Out[29]:
Visualization
Effect of dividend yield on option prices across different strikes. Calls decrease in value with dividends (dashed blue vs solid blue) while puts increase (dashed red vs solid red). The effect is most pronounced for in-the-money calls.
Effect of dividend yield on option prices across different strikes. Calls decrease in value with dividends (dashed blue vs solid blue) while puts increase (dashed red vs solid red). The effect is most pronounced for in-the-money calls.

Key Parameters

The key parameters for the Black-Scholes model with dividends are:

  • SS: Current stock price.
  • KK: Strike price.
  • TT: Time to expiration.
  • rr: Risk-free interest rate.
  • σ\sigma: Volatility.
  • qq: Continuous dividend yield. Represents cash flows paid to shareholders that option holders do not receive. Higher dividends decrease call values and increase put values.

Limitations of the Black-Scholes Model

While the Black-Scholes formula revolutionized option pricing and remains foundational, its assumptions limit its applicability in real markets.

The assumption of constant volatility is perhaps the most significant limitation. Empirical studies consistently show that volatility varies over time and exhibits clustering, with volatile periods tending to follow volatile periods. Moreover, when we examine implied volatilities from traded options, we find they vary systematically with strike price (the volatility smile) and with time to expiration (the term structure of volatility). These patterns directly contradict the constant volatility assumption and require more sophisticated models to explain.

The assumption of geometric Brownian motion implies that log-returns are normally distributed. However, as we discussed when studying stylized facts of financial returns, real asset returns exhibit heavy tails (more extreme moves than a normal distribution predicts) and negative skewness (large negative returns are more common than large positive returns). This means Black-Scholes systematically underprices options that pay off in extreme scenarios, particularly out-of-the-money puts that protect against market crashes.

The model assumes continuous trading with no transaction costs, allowing perfect delta hedging. In practice, transaction costs make continuous rebalancing impossible, and the discrete nature of trading introduces hedging errors. The model also assumes the ability to borrow and short-sell without restrictions at the risk-free rate, which may not hold for all market participants.

Finally, Black-Scholes prices European options only. American options, which can be exercised before expiration, require different techniques. Exotic options with path-dependent payoffs or multiple underlying assets also need more general pricing methods, which we'll cover in subsequent chapters on binomial trees and Monte Carlo simulation.

Despite these limitations, Black-Scholes remains the benchmark model. Market participants quote implied volatilities (the volatility that makes Black-Scholes match market prices) rather than dollar prices, using Black-Scholes as a translation device. Understanding Black-Scholes deeply is essential before moving to more complex models.

Summary

The Black-Scholes formula for European option pricing is:

C=SN(d1)KerτN(d2)C = SN(d_1) - Ke^{-r\tau}N(d_2)

where:

  • CC: call option price
  • SS: stock price
  • N()N(\cdot): cumulative standard normal CDF
  • d1,d2d_1, d_2: standardized moneyness terms
  • KK: strike price
  • rr: risk-free interest rate
  • τ\tau: time to expiration
P=KerτN(d2)SN(d1)P = Ke^{-r\tau}N(-d_2) - SN(-d_1)

where:

  • PP: put option price
  • KK: strike price
  • rr: risk-free interest rate
  • τ\tau: time to expiration
  • N()N(\cdot): cumulative standard normal CDF
  • d1,d2d_1, d_2: standardized moneyness terms
  • SS: stock price

Key insights:

  • Solution from the PDE: The Black-Scholes formula arises from solving the Black-Scholes PDE (derived in the previous chapter) subject to the option's terminal payoff condition. The solution involves transforming the PDE to the heat equation and applying the risk-neutral valuation principle.

  • Probabilistic interpretation: N(d2)N(d_2) is the risk-neutral probability that the option expires in-the-money, while N(d1)N(d_1) relates to the expected stock price conditional on exercise under a different measure.

  • Five inputs, one unknown: The formula takes five parameters: stock price, strike, time to expiration, interest rate, and volatility. Only volatility must be estimated, making it the central challenge in option pricing.

  • Monotonic relationships: Call prices increase with stock price, volatility, and interest rate, and decrease with strike price. Put prices exhibit the opposite relationships for stock price and rate. Both option types increase with volatility and time.

  • The Greeks: Delta, Gamma, Theta, Vega, and Rho quantify sensitivity to the five inputs. These partial derivatives are essential for hedging and risk management, which we'll explore comprehensively in the next chapter.

  • Model limitations: Constant volatility, normally distributed returns, continuous trading, and European exercise only are assumptions that don't perfectly match reality. Understanding these limitations guides when to use more sophisticated models.

The Black-Scholes formula, despite its simplifying assumptions, provides the foundation for all of options theory. The concepts of delta hedging, implied volatility, and risk-neutral pricing that emerge from this framework underpin modern derivatives markets.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about the Black-Scholes formula and European option pricing.

Loading component...

Reference

BIBTEXAcademic
@misc{blackscholesformulaeuropeanoptionpricinggreeks, author = {Michael Brenndoerfer}, title = {Black-Scholes Formula: European Option Pricing & Greeks}, year = {2025}, url = {https://mbrenndoerfer.com/writing/black-scholes-formula-european-option-pricing-greeks}, organization = {mbrenndoerfer.com}, note = {Accessed: 2025-01-01} }
APAAcademic
Michael Brenndoerfer (2025). Black-Scholes Formula: European Option Pricing & Greeks. Retrieved from https://mbrenndoerfer.com/writing/black-scholes-formula-european-option-pricing-greeks
MLAAcademic
Michael Brenndoerfer. "Black-Scholes Formula: European Option Pricing & Greeks." 2026. Web. today. <https://mbrenndoerfer.com/writing/black-scholes-formula-european-option-pricing-greeks>.
CHICAGOAcademic
Michael Brenndoerfer. "Black-Scholes Formula: European Option Pricing & Greeks." Accessed today. https://mbrenndoerfer.com/writing/black-scholes-formula-european-option-pricing-greeks.
HARVARDAcademic
Michael Brenndoerfer (2025) 'Black-Scholes Formula: European Option Pricing & Greeks'. Available at: https://mbrenndoerfer.com/writing/black-scholes-formula-european-option-pricing-greeks (Accessed: today).
SimpleBasic
Michael Brenndoerfer (2025). Black-Scholes Formula: European Option Pricing & Greeks. https://mbrenndoerfer.com/writing/black-scholes-formula-european-option-pricing-greeks