Skip to content

Estimating Option Delta and Gamma With Bump-and-Reprice

Original question

How do I calculate the delta and gamma of an option using finite differences and compare them with analytical values?
Reprice the option at S−hS-h, SS, and S+hS+h. Delta is the difference between the two bumped prices divided by 2h2h. Gamma is the sum of the bumped prices less twice the centre price, divided by h2h^2. On a six-month call with S=100S=100, K=105K=105, r=4%r=4\%, and σ=25%\sigma=25\%, a 11-dollar bump yields delta about 0.4702950.470295 and gamma about 0.0224990.022499.

See which Taylor terms the bumps cancel

Expanding V(S+h)V(S+h) and V(S−h)V(S-h) in Taylor series and subtracting cancels the even terms. Adding the expansions and subtracting 2V(S)2V(S) cancels the odd terms. For a sufficiently smooth price,

Δ^h=V(S+h)−V(S−h)2h,Γ^h=V(S+h)−2V(S)+V(S−h)h2.\widehat{\Delta}_h=\frac{V(S+h)-V(S-h)}{2h},\qquad \widehat{\Gamma}_h=\frac{V(S+h)-2V(S)+V(S-h)}{h^2}.
Both have O(h2)O(h^2) truncation error in this setting. For a Black–Scholes call with no dividends, Δ=N(d1)\Delta=N(d_1) and Γ=ϕ(d1)/(Sστ)\Gamma=\phi(d_1)/(S\sigma\sqrt{\tau}). When bumping spot, keep maturity, strike, rate and volatility fixed to measure the same model derivatives. If a hedging model specifies that implied volatility changes with spot, state and test that convention separately.
Delta divides the difference between two revaluations by 2h2h, which is the distance between the bumped spots. Gamma divides the change in the two slopes by hh again, so its denominator is h2h^2. Reprice all three points with the same strike, maturity, rate and volatility for a partial derivative with respect to spot. If you use a Monte Carlo pricer, common random numbers help remove noise that would otherwise be magnified by these divisions. Compare several bump sizes before interpreting a single error.

Change the bump and compare with the analytic Greeks

The analytic delta and gamma are 0.4703170.470317 and 0.02250510.0225051. With h=1h=1, prices at 9999, 100100, and 101101 are about 5.3208915.320891, 5.7799365.779936, and 6.2614816.261481. With h=5h=5, the delta and gamma estimates are 0.4697910.469791 and 0.02236020.0223602. The smaller bump comes closer here because analytic repricing has little noise at the dollar scale. With Monte Carlo repricing, reuse the same shocks at all three spots and estimate the uncertainty of the per-path price differences.

Central differences with a bump sweep

from math import exp, log, sqrt from scipy.stats import norm strike, maturity, rate, vol = 105, 0.5, 0.04, 0.25 spot = 100 def call_price(s): d1 = (log(s / strike) + (rate + vol**2 / 2) * maturity) / (vol * sqrt(maturity)) return s * norm.cdf(d1) - strike * exp(-rate * maturity) * norm.cdf( d1 - vol * sqrt(maturity) ) center = call_price(spot) for h in (5, 1, 0.1, 0.01): below, above = call_price(spot - h), call_price(spot + h) delta = (above - below) / (2 * h) gamma = (above - 2 * center + below) / h**2 print(h, delta, gamma)
Explore the price curve in the options pricer to see where its slope and curvature are changing.

Interactive example

Move volatility and expiry in Black–Scholes

This European call uses strike 100, a continuously compounded risk-free rate of 5% and zero dividends. The benchmark spot is 100.

Price at spot 100 is 10.45 · delta 0.637
Call prices across spot prices compared with the expiry payoff01020307085100115130Spot priceValue
  • Call price today
  • Expiry payoff

References and next steps