Black-Scholes Formula: European Option Pricing & Greeks
Covers the Black-Scholes formula for European options with Python implementation. Topics include derivation, the Greeks, put-call parity.
Quantitative FinanceAll chapters Black-Scholes Formula and European Option PricingFull chapter · Sections in this chapter1 / 11 ↓
Reading tools Definitions & inline links
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.
Article links
Make inline references clickable
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 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 an alternative derivation and extensions published by Robert Merton that same year, this formula transformed finance by providing a closed-form European option price grounded in dynamic replication and no-arbitrage reasoning. The formula gave market participants a systematic way to connect option prices with the cost of dynamically hedging their payoffs. Cboe reports growth from 5.6 million contracts in 1974 to roughly 1.3 billion across its exchanges in 2014, including futures. The 1997 Nobel committee credited the pricing methodology with advances in valuation and risk management.
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, this non-dividend-paying stock has expected growth rate under the pricing measure. More generally, the martingale condition applies to appropriately discounted total gains, including dividends, rather than to every ex-dividend asset price.
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 on a non-dividend-paying stock is:
where:
- : price of the derivative
- : time
- : price of the underlying asset
- : volatility of the underlying asset
- : 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 . The third term accounts for the drift in the option price due to the expected growth of the stock under risk-neutral dynamics. The last term discounts the derivative value at rate . Together, the PDE terms make the self-financing delta-hedged position with value earn the risk-free rate; the unhedged derivative need not have that expected return under the physical measure.
To find the price of a European call option, we must solve this PDE subject to the boundary condition at expiration:
where:
- : value of the call option at expiration
- : stock price at expiration
- : strike price
- : 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 and immediately sell it at , 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.
We seek the financially admissible solution, with and at most linear growth as increases. These restrictions exclude nonfinancial solutions on the unbounded stock-price domain.
Transformation to the Heat Equation
Assume , constant and constant . Introduce remaining time , measured in years when the rate and volatility use annual units. As increases, we move backward from the known expiry payoff. Set , the dimensionless log-moneyness. Multiplying by a factor adds the logarithm of that factor to . For example, when K=\100$50$200-\ln 2+\ln 2$.
Normalize and discount the option value by writing
Here is dimensionless; still has units of time. The chain rule gives
Substituting these derivatives into the pricing PDE and cancelling leaves a constant-coefficient equation:
Write and . To remove both the drift term and the zero-order term that the next substitution creates, set
The constant is dimensionless, while has inverse-time units. Direct differentiation gives . Our choices make both extra coefficients zero, so
This is the heat equation with diffusivity . The terminal call payoff becomes its initial condition at :
The notation clips negative values to zero. Thus this initial function is zero for . For , the whole-line heat kernel is the Gaussian density
It weights transformed payoff values at log-price endpoints . The kernel integrates to one; is a transformed payoff, not a probability density. Convolving the two gives
To evaluate this integral, let and define . Completing the square in its exponent gives
Here is the standard normal cumulative distribution function. Hence . Multiplying by the two scaling factors recovers . Because and , the first term simplifies to and the second to , where
The next section states the resulting prices and interprets these standardized terms.
The General Solution
Working backward through the transformations, reversing each change of variables in sequence, the solution for a European call option emerges as:
where:
- : call option price
- : current stock price
- : cumulative standard normal distribution function
- : standardized moneyness terms
- : strike price
- : risk-free interest rate
- : time to expiration
This formula expresses the option price as the difference between two terms, each involving the cumulative normal distribution function . The function gives the probability that a standard normal random variable is less than , and it appears here because the underlying stock price follows a lognormal distribution under geometric Brownian motion.
The terms and are defined as:
where:
- : current stock price
- : strike price
- : risk-free rate
- : volatility
- : time to expiration
The numerator of contains two parts. The first, , 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, , equals the risk-neutral expected log-price drift plus the variance adjustment . It shifts to ; it is not the expected log-price drift itself. The denominator, , 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:
where:
- : first standardized term
- : volatility
- : time to expiration
- : current stock price
- : strike price
- : risk-free rate
Notice that differs from only in the sign of the term in the numerator. This sign change determines the probabilistic interpretation developed below. The relationship 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 , or use put-call parity. The result is:
where:
- : put option price
- : strike price
- : risk-free rate
- : time to expiration
- : current stock price
- : cumulative standard normal distribution function
- : 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 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 (where ) 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:
where:
- : call option price
- : risk-free rate
- : time to expiration
- : expectation under the risk-neutral measure
- : stock price at expiration
- : 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:
where:
- : call option price
- : risk-free rate
- : time to expiration
- : stock price at expiration
- : strike price
- : indicator function (1 if , 0 otherwise)
- : 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 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: is the present value of paying the strike, weighted by the risk-neutral probability 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 at expiration, but only if . The probability of this event under risk-neutral dynamics is , and we discount the expected payment back to today at the risk-free rate.
The first term requires more care. is the discounted expected stock receipt restricted to exercise outcomes: . This is an unconditional expectation with an indicator, not an expectation conditional on exercise. If , then when the exercise probability is positive. High-stock-price outcomes receive more weight in the expected stock receipt than in the exercise probability. The next paragraph gives its precise share-measure interpretation.
Technically, is the probability that 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 because we are overweighting exactly those outcomes where exercise occurs. The difference between and captures this reweighting effect.
VisualizationOut [3]Expand

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 (): 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 , so the higher is relative to , 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 and .
-
Strike price (): Higher strikes decrease call values and increase put values when the other inputs are fixed. A call has a positive expiry payoff only when the stock finishes above its strike. For example, calls struck at \100$110d_1d_2$.
-
Time to expiration (): More remaining time often raises an option's value, but the effect depends on the option type and inputs. A European put can fall in value as remaining maturity increases, even when interest rates are positive. Near expiration, at-the-money options can experience especially rapid time decay. Theta captures this local calendar-time effect with other inputs fixed.
-
Risk-free rate (): 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 useful. 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 (): Higher volatility increases both call and put values with the other inputs fixed. Under the model's pricing measure, changing volatility leaves the terminal stock-price mean unchanged and changes the dispersion of outcomes. The convex vanilla payoffs benefit from that extra dispersion: a call struck at \100$20$120$80\max(S-Ke^{-r\tau},0)$, so its value still depends on carry and remaining maturity.
The stock price is observed, while the strike and expiration are contract terms. An appropriate pricing rate or discount curve must be selected from market data and matched to the currency, maturity and compounding convention. Volatility remains a central modeling challenge: future realized volatility must be forecast, while implied volatility can be calibrated from an admissible market premium. We'll return to implied volatility and the volatility smile in a later chapter.
Understanding and
The quantities and 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 first:
where:
- : stock price
- : strike price
- : risk-free rate
- : volatility
- : time to expiration
To understand , we need to recall how the stock price evolves under geometric Brownian motion. The numerator is the expected log-return of the stock under the risk-neutral measure, relative to the strike. The term appears rather than just because of the difference between arithmetic and geometric means. When a variable follows geometric Brownian motion with drift , its expected logarithm grows at rate , not . 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 , the expected log-price is:
where:
- : expected log stock price at time
- : log of current stock price
- : risk-free rate
- : volatility
- : time to expiration
So the numerator equals . 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 is the standard deviation of this log-return. The volatility of the log-price after time is , which reflects the diffusion of prices over time. Thus measures how many standard deviations the expected log-price exceeds the log-strike, which is exactly the input you'd need to find using the normal distribution.
The quantity exceeds by . Completing the square in the lognormal density shows that . This is the stock receipt weighted across all outcomes, with zero contribution when exercise does not occur. To obtain the expectation conditional on exercise, divide by when that probability is positive.
The technical explanation involves a change of measure: for this non-dividend stock, is the probability of the call event under the stock-numeraire or share measure. The density change weights outcomes by the terminal stock price, increasing the probability of this upper-tail event. It decreases the probability of the complementary lower-tail event ; the comparison is not the same for put exercise.
Put-Call Parity Revisited
As we learned when studying option basics, put-call parity is a fundamental relationship linking European call and put prices:
where:
- : call option price
- : put option price
- : stock price
- : strike price
- : risk-free rate
- : time to expiration
This equality does not require the Black-Scholes stock-price distribution. It follows from matching European calls and puts on a non-dividend stock under the stated frictionless trading and financing assumptions. The long-call, short-put portfolio pays . Buying a share and borrowing today, with repaid at expiration, has the same payoff. No arbitrage therefore equates their current values.
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:
where:
- : call and put option prices
- : stock price
- : strike price
- : risk-free rate
- : time to expiration
- : cumulative standard normal distribution
- : moneyness terms
We compute the difference to verify the relationship. The key mathematical fact we will use is the symmetry of the standard normal distribution: for any value of . This follows from the fact that the normal distribution is symmetric around zero, so the probability of being less than plus the probability of being greater than (which equals the probability of being less than ) must sum to one.
where:
- : call price
- : put price
- : stock price
- : strike price
- : risk-free rate
- : 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.
VisualizationOut [4]Expand

Implementing the Black-Scholes Formula
Let's implement the Black-Scholes formula in Python and explore its behavior. These educational functions use scalar inputs with and positive remaining time for the pre-expiry formulas, with a separate expiry-payoff branch. They assume finite, numerically usable inputs and are not general-range pricing routines. The validator explicitly rejects zero volatility, which would require a separate deterministic-limit formula. Negative remaining maturity is rejected; zero remaining maturity returns the expiry payoff.
PythonIn [5]Expand
import numpy as np
from scipy.stats import norm
def validate_bs_inputs(S, K, T, r, sigma, option_type="call", q=0.0):
"""Validate this chapter's finite scalar educational pricing domain.
S, K and sigma must be positive; remaining maturity T may be zero.
Rates r and continuous yield q may have either sign.
Zero volatility is excluded, rather than evaluated through a singular formula.
Numeric inputs must be representable as finite Python floats.
"""
from numbers import Real
values = (S, K, T, r, sigma, q)
if not all(isinstance(value, Real) for value in values):
raise ValueError("Pricing inputs must be finite real scalars")
try:
S, K, T, r, sigma, q = map(float, values)
except (OverflowError, TypeError, ValueError) as error:
raise ValueError("Pricing inputs must be finite real scalars") from error
if not all(np.isfinite(value) for value in (S, K, T, r, sigma, q)):
raise ValueError("Pricing inputs must be finite real scalars")
if S <= 0 or K <= 0 or sigma <= 0 or T < 0:
raise ValueError("S, K and sigma must be positive; T must be nonnegative")
if not isinstance(option_type, str) or option_type not in ("call", "put"):
raise ValueError("option_type must be 'call' or 'put'")
return S, K, T, r, sigma, q
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
Inputs are finite real scalars with S,K,sigma>0 and T>=0; T=0
returns the expiry payoff. The implementation assumes numerically usable
intermediates and does not support arbitrary numerical ranges.
"""
S, K, T, r, sigma, _ = validate_bs_inputs(S, K, T, r, sigma)
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 a scalar European put price for finite inputs with S,K,sigma>0.
T is nonnegative remaining maturity; T=0 returns the expiry payoff.
This educational implementation assumes numerically usable intermediates.
"""
S, K, T, r, sigma, _ = validate_bs_inputs(S, K, T, r, sigma, "put")
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_priceNow let's calculate option prices for a specific example:
PythonIn [6]Expand
# 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)ConsoleOut [7]Expand
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:
PythonIn [8]Expand
# 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)ConsoleOut [9]Expand
Put-Call Parity Verification ======================================== C - P = -2.4075 S - K*exp(-rT) = -2.4075 Difference: 0.00e+00 Put-call parity holds
At these example inputs, the implementation agrees with put-call parity to floating-point precision.
Examining the Intermediate Calculations
Understanding the intermediate values and helps build intuition for how the formula works:
PythonIn [10]Expand
def compute_d1_d2(S, K, T, r, sigma):
"""Compute d1/d2 for finite scalar S,K,T,sigma>0 and finite r."""
S, K, T, r, sigma, _ = validate_bs_inputs(S, K, T, r, sigma)
if T == 0:
raise ValueError("d1 and d2 require positive remaining maturity")
log_moneyness = np.log(S / K)
d1_shift = (r + 0.5 * sigma**2) * T
diffusion = sigma * np.sqrt(T)
d1 = (log_moneyness + d1_shift) / diffusion
d2 = d1 - diffusion
return d1, d2, log_moneyness, d1_shift, diffusion
d1, d2, log_moneyness, d1_shift, diffusion = compute_d1_d2(S, K, T, r, sigma)ConsoleOut [11]Expand
Breakdown of d1 and d2 Calculations ============================================= ln(S/K) = ln(100/105) = -0.0488 d1 numerator shift (r + σ²/2)T = 0.0350 Diffusion σ√T = 0.1414 --------------------------------------------- d1 = (ln(S/K) + shift) / 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 value tells us there's less than a 50% risk-neutral probability that this option finishes in-the-money. The value of 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:
- : Current stock price. Higher prices increase call values and decrease put values.
- : Strike price. The reference price for the option's payoff.
- : Time to expiration in years. Longer times generally increase option values.
- : Risk-free interest rate (annualized). Higher rates favor calls over puts.
- : Volatility (annualized). Controls the dispersion of terminal stock prices; with the other inputs fixed, higher volatility increases both call and put values.
Option Price Sensitivity to Inputs
Let's visualize how option prices change with stock price, volatility and remaining maturity, holding the other inputs fixed. These examples build intuition for the Greeks introduced later in this chapter.
PythonIn [12]Expand
# 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]VisualizationOut [13]Expand

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.
PythonIn [14]Expand
# 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]VisualizationOut [15]Expand

With and the rate fixed, the call price approaches as volatility tends to zero and approaches as volatility increases without bound. Thus a price strictly between those limits has one finite positive implied volatility. For a put, the corresponding open interval is between and . At a boundary, outside these intervals, or at expiry, a finite positive implied volatility is not guaranteed. The rate must also be selected using an appropriate discount curve and convention.
PythonIn [16]Expand
# 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]VisualizationOut [17]Expand

In this example, the call falls as expiration approaches, while the put rises slightly near expiration. Both prices converge to their intrinsic payoffs as remaining maturity tends to zero, but not necessarily monotonically. Theta measures the local calendar-time change with other inputs held fixed.
VisualizationOut [18]Expand

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 model price is to small changes in those inputs. Understanding the Greeks is essential for risk management and hedging. Each Greek measures a different dimension of local, model-based sensitivity; this set does not capture every risk, including model misspecification or liquidity risk.
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 within that model requires continuous adjustment of a hedge portfolio. Delta gives the model's stock hedge ratio, while the other Greeks help assess how that hedge and the option value respond as inputs change. These sensitivities do not eliminate errors from discrete rebalancing or departures from the model's assumptions.
The Greeks are usually 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 (whose name is not a Greek letter), and Rho.
Delta: Sensitivity to Stock Price
Delta () measures the local rate of change of the option price with respect to the stock price, holding the other inputs fixed. Multiplying delta by a stock-price change gives a first-order estimate of the option-price change, not an exact repricing for a finite $1 move. Delta answers the practical question: if the stock moves a little, how much does your option position change in value?
where:
- : delta of the call option
- : call option price
- : stock price
- : cumulative normal distribution value at
The result that call delta equals comes directly from differentiating the Black-Scholes formula. The derivative of the first term with respect to is not simply because itself depends on . However, when we carefully apply the chain rule, the additional terms cancel out, leaving just . 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.
where:
- : delta of the put option
- : put option price
- : stock price
- : cumulative normal distribution value at
- : cumulative normal distribution value at
Call deltas range from 0 to 1, while put deltas range from -1 to 0 in this non-dividend model. A spot-at-the-money call often has delta near 0.5 for short remaining maturity and modest carry, but its exact delta is . Delta gives a first-order estimate for a small stock move. A deep in-the-money call approaches delta 1, while a deep out-of-the-money call approaches delta 0.
Delta also has an interpretation as a hedge ratio: to hedge a short call position, you should hold 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 () measures the local rate of change of delta with respect to the stock price, holding the other inputs fixed. Multiplying gamma by a small stock-price change approximates the change in delta. This second-order sensitivity helps assess how stable the delta hedge will be. High gamma means that even small moves in the stock price can significantly change the delta, requiring frequent rebalancing of the hedge.
where:
- : gamma of the option
- : option price (call or put)
- : stock price
- : standard normal probability density at
- : volatility
- : time to expiration
The function is the standard normal probability density. Gamma measures the stock-price derivative of call delta , which is the call exercise probability under the share measure. It is not the derivative of the risk-neutral exercise probability .
Gamma is the same for calls and puts with the same strike and expiration. This equality follows from put-call parity: since , and the right-hand side is linear in , the second derivative with respect to must be identical for calls and puts.
High gamma means delta changes rapidly with the stock price, requiring frequent hedge rebalancing. As expiration approaches, gamma becomes concentrated near the money, but its exact maximum depends on the variable being changed. At fixed , gamma peaks across strikes at . At fixed , its peak across stock prices is . Long gamma gives positive local price curvature; total profit also depends on time decay, financing and the trading strategy.
Theta: Sensitivity to Time
Theta () measures the local rate of change of the option price as calendar time advances, holding the expiration date and the other inputs fixed. Since remaining maturity is , this is the negative of the derivative with respect to remaining maturity. Theta can have either sign: a negative value indicates time decay, while a positive value indicates a local increase in price as time passes. With time measured in years, the formula below gives theta per year.
where:
- : theta of the call option
- : stock price
- : standard normal PDF at
- : volatility
- : time to expiration
- : risk-free rate
- : strike price
- : cumulative normal CDF at
The formula consists of two components, each with a distinct economic interpretation:
- : Represents the erosion of value due to the resolution of uncertainty (time decay at fixed volatility). As time passes, there is less time for favorable price movements to occur. This term is always negative, which reflects the fact that options lose optionality value over time.
- : Represents the financing contribution from deferring the strike payment. For positive rates, the call's deferral benefit shrinks as expiration approaches. This contribution vanishes at zero rates and reverses sign at negative rates. In put theta, the financing term has the opposite sign because puts involve receiving rather than paying the strike.
Theta is often negative for long option positions, but time decay is not universal. A sufficiently deep in-the-money European put can have positive theta when interest rates are positive, because receiving the strike sooner can outweigh the loss of optionality. Near expiration, at-the-money options can have especially large negative theta, making time decay a practical concern for their holders.
The Black-Scholes PDE links theta and gamma through , where is the option value. The right-hand side accounts for financing the delta-hedged position. Positive gamma therefore does not, by itself, force theta to be negative; the option value, delta, stock price, and interest rate also enter the relationship.
Vega: Sensitivity to Volatility
Vega ( or ) is the local derivative of option value with respect to volatility expressed as a decimal. 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 useful when a position expresses a view on volatility. Future realized volatility must be estimated, while implied volatility can be inferred from an option's quoted market price when that price lies within the model's admissible range.
where:
- : vega of the option
- : option price
- : stock price
- : time to expiration
- : standard normal PDF at
A change in decimal volatility of , such as to , is one percentage point. Traders commonly quote vega as the raw derivative divided by . Multiplying that quotation by a one-percentage-point change gives a first-order price estimate, not an exact finite-change gain.
Vega is the same for calls and puts and is positive in the stated pre-expiry domain: , and . Thus a small volatility increase raises both vanilla option prices with the other inputs fixed.
Vega is often concentrated near the money, but the location of its maximum depends on which inputs are held fixed. At fixed stock price, remaining maturity, interest rate and volatility, it peaks across strikes at , or , not necessarily at . Increasing maturity raises the factor but also changes , so vega need not increase over every maturity interval.
Trading volatility can involve exposure to changes in implied volatility or to differences between realized and implied volatility. The examples here isolate vega exposure, with the other inputs held fixed. For the non-dividend-paying European call and put here, with , positive volatility and time remaining before expiry, a long option has positive vega; holding the other inputs fixed, a rise in implied volatility raises its model value. A short option has the opposite exposure. Total profit also depends on stock moves, time decay, financing and other changes.
Rho: Sensitivity to Interest Rate
Rho () is the local derivative of option price with respect to the interest rate expressed as a decimal. Its contribution to risk depends on the size of the rate change and the contract's maturity. Comparisons with other Greeks require specified input changes because the derivatives use different units.
where:
- : rho of the call option
- : strike price
- : time to expiration
- : risk-free rate
- : cumulative normal CDF at
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.
where:
- : rho of the put option
- : put option price
- : strike price
- : time to expiration
- : risk-free rate
- : cumulative normal CDF at
Put rho is negative because the put holder receives the strike at exercise, and a higher rate reduces its present value. Rho contains a remaining-maturity factor, but discounting and also depend on maturity. Its magnitude need not grow proportionally or increase over every maturity interval.
Interest-rate sensitivity reflects the cost of carrying a hedged option position. Longer-dated equity options can be more sensitive to rate changes than near-term options, although the exact maturity dependence is not universal. Assess the exposure using a specified rate change and the position's rho.
Computing the Greeks
Let's implement and calculate the Greeks for our example option:
PythonIn [19]Expand
from numbers import Real
def black_scholes_greeks(S, K, T, r, sigma, option_type="call"):
"""
Calculate price and Greeks for a European option before expiration.
S, K, T (remaining maturity in years) and sigma must be positive real
finite scalars; r must be real and finite. All numeric inputs must be
representable as finite Python floats. option_type is the scalar string
'call' or 'put'.
Returns annual and daily calendar-time theta, raw vega and vega per
percentage point. Expired payoffs belong to the separate pricing functions.
This educational float implementation rejects unusable or nonfinite
intermediates/results with a numerical range ValueError; it is not an
arbitrary-range pricer. Benign underflow to zero is allowed.
"""
if not all(isinstance(value, Real) for value in (S, K, T, r, sigma)):
raise ValueError("S, K, T, r and sigma must be real finite scalars")
try:
S, K, T, r, sigma = map(float, (S, K, T, r, sigma))
except (OverflowError, TypeError, ValueError) as error:
raise ValueError("S, K, T, r and sigma must be real finite scalars") from error
if not all(np.isfinite(value) for value in (S, K, T, r, sigma)):
raise ValueError("S, K, T, r and sigma must be real finite scalars")
if S <= 0 or K <= 0 or T <= 0 or sigma <= 0:
raise ValueError(
"S, K, T and sigma must be strictly positive before expiration"
)
if not isinstance(option_type, str) or option_type not in ("call", "put"):
raise ValueError("option_type must be 'call' or 'put'")
try:
with np.errstate(over="raise", divide="raise", invalid="raise", under="ignore"):
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 not all(np.isfinite(value) for value in (d1, d2, discount)):
raise ValueError(
"Inputs exceed the numerical range of this implementation"
)
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_denominator = S * sigma * sqrt_T
if not np.isfinite(gamma_denominator) or gamma_denominator <= 0:
raise ValueError(
"Inputs exceed the numerical range of this implementation"
)
gamma = n_d1 / gamma_denominator
vega = S * sqrt_T * n_d1
# Convert theta to daily and vega to per one percentage point of volatility
theta_daily = theta / 365
vega_percent = vega / 100
greeks = {
"price": price,
"delta": delta,
"gamma": gamma,
"theta": theta,
"theta_daily": theta_daily,
"vega": vega,
"vega_pct": vega_percent,
"rho": rho,
}
if not all(np.isfinite(value) for value in greeks.values()):
raise ValueError(
"Inputs exceed the numerical range of this implementation"
)
except (OverflowError, FloatingPointError, ZeroDivisionError) as error:
raise ValueError(
"Inputs exceed the numerical range of this implementation"
) from error
return greeks
call_greeks = black_scholes_greeks(S, K, T, r, sigma, "call")
put_greeks = black_scholes_greeks(S, K, T, r, sigma, "put")ConsoleOut [20]Expand
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 (/1pp) 0.2808 0.2808 Rho 20.7672 -30.4366
Let's interpret these values:
ConsoleOut [21]Expand
First-order estimates from the Greeks (other inputs held fixed): ------------------------------------------------------- • If the stock rises $1, the call gains approximately $0.46 and the put loses approximately $0.54 • Over one day, the call loses approximately $0.0211 • If volatility rises one percentage point (20% to 21%), the call gains approximately $0.2808 • Gamma of 0.0281 means delta changes ~0.03 for each $1 move in the stock
Visualizing Delta Across Strikes
PythonIn [22]Expand
# 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"])VisualizationOut [23]Expand

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 plot varies strike while keeping the stock price fixed. Gamma instead measures how delta changes with the stock price, holding strike and the other inputs fixed.
VisualizationOut [24]Expand

VisualizationOut [25]Expand

VisualizationOut [26]Expand

The next chapter covers the Greeks in detail, 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 , we can modify the formula by replacing with . 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:
where:
- : call option price
- : stock price
- : continuous dividend yield
- : time to expiration
- : cumulative standard normal CDF
- : strike price
- : risk-free rate
The factor is the continuous-yield carry adjustment. Under the pricing measure, the ex-dividend stock price grows on average at rate , while the stock's dividend-reinvested total gains have expected return . This is a multiplicative adjustment, not a subtraction of the nominal dollars of dividends paid over the option's life.
The parameters and are modified as follows:
where:
- : stock price
- : strike price
- : risk-free rate
- : dividend yield
- : volatility
- : time to expiration
The key change is that replaces 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.
where:
- : standardized moneyness term
- : volatility
- : time to expiration
The relationship between and remains unchanged; they still differ by exactly .
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.
PythonIn [27]Expand
def black_scholes_dividend(S, K, T, r, sigma, q, option_type="call"):
"""
Scalar European pricing with continuous dividend yield q.
Requires finite real inputs with S,K,sigma>0 and T>=0; r and q may
have either sign. option_type must be call or put. T=0 gives the
expiry payoff. Zero volatility is explicitly excluded. This educational
implementation assumes numerically usable intermediates.
"""
S, K, T, r, sigma, q = validate_bs_inputs(S, K, T, r, sigma, option_type, 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")ConsoleOut [28]Expand
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.
VisualizationOut [29]Expand

Key Parameters
The key parameters for the Black-Scholes model with dividends are:
- : Current stock price.
- : Strike price.
- : Time to expiration.
- : Risk-free interest rate.
- : Volatility.
- : 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.
Constant volatility is a restrictive modelling assumption. Empirical studies consistently show that volatility varies over time and exhibits clustering, with volatile periods tending to follow volatile periods. Implied volatilities from traded options also 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. Observed log-return distributions often have heavier tails than a normal distribution. Many equity-index return samples also show negative skewness, although the sign and size of asymmetry depend on the asset, time horizon and sample. For a distribution with a finite third moment and nonzero variance, negative skewness means that the standardized third central moment is negative; it does not impose a universal ordering of positive and negative tail probabilities. These empirical features warn against relying on a constant-volatility lognormal model as a description of observed returns. They do not, by themselves, establish that a particular option is underpriced: that comparison depends on the volatility input, calibration and observed market premium.
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.
The displayed vanilla formulas price European exercise and do not generally include American early-exercise value. American contracts require an optimal-stopping method within the pricing framework. A non-dividend American call at nonnegative rates is a special case where early exercise gives no advantage and the European call formula applies. Path-dependent payoffs and multiple underlying assets also require methods suited to those contracts.
Despite these limitations, Black-Scholes is a useful benchmark for option pricing. Market participants often express or compare option values in implied-volatility terms. Depending on the market, options may be quoted in premium or volatility units; a pricing model suited to the contract translates between them. Understanding Black-Scholes deeply is essential before moving to more complex models.
Summary
The Black-Scholes formula for European option pricing is:
where:
- : call option price
- : stock price
- : cumulative standard normal CDF
- : standardized moneyness terms
- : strike price
- : risk-free interest rate
- : time to expiration
where:
- : put option price
- : strike price
- : risk-free interest rate
- : time to expiration
- : cumulative standard normal CDF
- : standardized moneyness terms
- : 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: For the European call, is its risk-neutral exercise probability and is its exercise probability under the share measure. The term is the discounted expected stock receipt restricted to exercise outcomes.
-
Five inputs: The formula takes stock price, strike, remaining maturity, interest rate and volatility. Volatility must be forecast or inferred from a compatible market premium, and the pricing rate must be selected using suitable market conventions.
-
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; the remaining-time effect is not universal for European puts.
-
The Greeks: Delta and Gamma describe stock-price sensitivity and curvature; Theta measures calendar-time sensitivity, Vega volatility sensitivity, and Rho interest-rate sensitivity. This list contains no strike derivative. The next chapter applies these measures to hedging and risk management.
-
Model limitations: Constant volatility, normally distributed log-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 provides a foundation for studying option valuation and hedging under a tractable model. Delta hedging, implied volatility and risk-neutral pricing are tools we can carry into the models and methods that follow.
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.
Black-Scholes Formula and European Option Pricing
Join the discussionAsk a question or share what you learned.
Keep exploring
Reference
Citation details
Cite or share this article.


Comments
Add to the conversation
A question, a correction, or an example from your own work.
No comments yet. Be the first to share your thoughts!