Greeks by repricing
The sensitivities of an option's value to its inputs are its Greeks. Each is a derivative with respect to one input, all the others held fixed. Take the call of case studies 2.4.6 and 2.6.5: stock price , strike , years, rate and volatility , worth $6.3710.
- Delta is the slope of the price in . Case study 2.7.4 gave it as , in dollars of option per dollar of stock.
- Gamma is the second derivative in , (case study 2.7.4): the change in delta per dollar.
- Vega is the slope in , (case study 2.4.6). Desks quote it per vol point, a change of 0.01 in : 0.2777.
Here is the standard normal cumulative distribution, its density, and the one in case study 2.4.6's formula. A pricing system replaces each derivative by a finite difference of the price, as in lesson 2.8.1.
Rule: Bump-and-reprice
is the bump to the stock price, in dollars, and the bump to the volatility. Five prices give all three Greeks: today's, two with the stock bumped and two with the volatility bumped.
Case study 2.7.4 checked delta and gamma with a 1-cent bump. Desks usually bump the stock by 1% and the volatility by one vol point, :
| Greek | formula | bumped | error |
|---|---|---|---|
| delta | 0.570158 | 0.570054 | |
| gamma | 0.027772 | 0.027762 | |
| vega per vol point | 0.277721 | 0.277717 |
These are truncation errors (lesson 2.8.1), 0.02% of delta and 0.04% of gamma. That is far below the doubt in the inputs themselves: nobody knows the volatility to four digits.
Try it
call is case study 2.4.6's formula, with and first. formulas returns the three Greeks from their closed forms, vega per vol point.
The cell bumps the stock by $1, which is 1%, and the volatility by 0.01. The last column is each error as a share of the Greek.
How big a bump?
Lesson 2.8.1 split the error of a difference into two parts. Truncation grows with the bump; rounding grows as the bump shrinks, and for a second difference it grows like . Here is the call with bumps from 10% of the stock price down to of it:
| bump, share of | delta error | bumped gamma | gamma error | |
|---|---|---|---|---|
| 10% | 10 | 0.026812 | ||
| 1% | 1 | 0.027762 | ||
| 0.01% | 0.01 | 0.027772 | ||
| 0.027772 | ||||
| 0.035527 | ||||
| 0.74 |
Gamma is the sensitive one. Its best bump is near 1 cent, which is lesson 2.8.1's with the scale : 0.012. Delta's best bump, near , is smaller. Rounding barely touches delta: even with a bump of dollars it is off by only .
So why do desks bump by 1%, a hundred times the best step for this formula? First, a 1% move is one the market really makes, so the bumped numbers describe a plausible day. Case study 2.2.4 said the same of the 1 bp bump.
Second, most pricers are far noisier than this formula.
Try it
The loop prints each row of the table: the bump as a share of , the bumped delta's error, the bumped gamma and its error. The last column is gamma's error as a share of gamma.
A noisy pricer
Case study 2.6.5 also priced this call with quad over the whole line, corner and all, and got 6.37102797: about above the formula. That error changes a little whenever moves. In lesson 2.8.1's rounding ceiling, , it takes the place of .
The bumped gammas from that pricer show the effect. A 1% bump gives 0.027762 and a 10-cent bump 0.027766, both fine. A 1-cent bump gives 0.027315, 1.6% low, and a bump of a tenth of a cent gives .
The error of the bumped gamma for two pricers of the same call: the noisier pricer needs a bigger bump. With a day to expiry, a 1% bump is as wide as the peak of gamma itself and flattens it.
The noisier the pricer, the larger the best bump. Trees and simulations, met in later courses, are noisier still. So desks keep bumps near 1% and check that halving the bump barely changes the answer.
Try it
by_quad is case study 2.6.5's integral over the whole line. Each line prints a bump, the bumped gamma from that pricer and its error as a share of the formula's 0.027772.
Try it
The first lines compare a $1 bump with a 1% bump on a $5 stock with strike $5. Then the right and the wrong vega bump, the one-sided delta, and the delta of a 100-share contract.
Where bumping misbehaves
Close to expiry
Case study 2.7.4 found that close to expiry the price curve nears the payoff's corner at the strike. The bend crowds into a range of about : $14.14 for six months, $1.05 for a day. A 1% bump is $1, so a day out it is as wide as the bend.
| time to expiry | gamma | 1% bump | error | |
|---|---|---|---|---|
| 6 months | 14.14 | 0.0278 | 0.0278 | |
| 1 month | 5.77 | 0.0689 | 0.0688 | |
| 1 week | 2.77 | 0.1438 | 0.1422 | |
| 1 day | 1.05 | 0.3811 | 0.3545 |
A bump must be small next to the scale on which the price bends, which here is , not . With a day left, a 10-cent bump gives 0.3808. The figure shows the 1% bump flattening the whole peak of gamma, not just its top.
At expiry: a corner and a jump
At expiry the call is worth its payoff, , with a corner at the strike. The gamma formula divides by there. The bump still returns a number: , whatever is.
A digital call pays $1 if the stock ends above the strike and nothing otherwise. At expiry its value jumps at the strike, and its bumped delta there is .
| bump | call gamma at the strike | digital delta at the strike |
|---|---|---|
| 1 | 1 | 0.5 |
| 0.1 | 10 | 5 |
| 0.01 | 100 | 50 |
The bumped number measures the bump, not the option: this is lesson 2.8.1's corner inside the step. Desks therefore treat such payoffs with care, for instance booking a digital as a narrow call spread, which has a slope rather than a jump.
Try it
The loop prints, for each expiry, , the formula's gamma, the 1% bump and its error. Then the one-day call with a 10-cent bump.
The last loop is at expiry, where the prices are the payoffs.
A numerical present value
Case study 2.5.5 valued $10,000 a year of tolls for 10 years at a continuous 5%: $78,693.87 exactly. Its payment schedules are lesson 2.8.2's rules. Payments at year-starts and year-ends are the left and right sums, so their average, $78,710.26, is the trapezoid rule; mid-year payments, $78,685.67, are the midpoint sum.
Combined as , they give Simpson's rule with 20 half-year strips: $78,693.87, right to the cent. Simpson's rule needs only 2 strips, values at years 0, 5 and 10, to come within $1.70. With 4 strips it is 11 cents off.
The same few lines value a stream whose discounted rate has no antiderivative, where no closed form exists to check against.
Try it
simpson_rule is lesson 2.8.2's, applied to the discounted rate .
The first line rebuilds Simpson's rule from case study 2.5.5's three schedules. The loop prints Simpson's value and error with 2, 4 and 10 strips.
Greeks by bump-and-reprice
Write bump_greeks(price, S, sigma, rel_bump=0.01, vol_bump=0.01). Here price(S, sigma) is any function that returns an option's value. Return (delta, gamma, vega) by central differences, with:
- the stock bumped by
rel_bump, a relative bump; - the volatility bumped by
vol_bump, an absolute bump; - vega reported per vol point: the slope in divided by 100.
Raise ValueError if S, sigma, rel_bump or vol_bump is not positive, or if vol_bump is not below sigma, which would make zero or negative.
The tests use the six-month call, a $5 stock where a fixed $1 bump fails, and a price function whose Greeks you can work out by hand.
See the tests
import math
from scipy.stats import norm
def _call(S, sigma, K=100.0, T=0.5, r=0.03):
d1 = (math.log(S / K) + (r + sigma**2 / 2) * T) / (sigma * math.sqrt(T))
return S * norm.cdf(d1) - K * math.exp(-r * T) * norm.cdf(d1 - sigma * math.sqrt(T))
def _formulas(S, sigma, K=100.0, T=0.5, r=0.03):
d1 = (math.log(S / K) + (r + sigma**2 / 2) * T) / (sigma * math.sqrt(T))
return norm.cdf(d1), norm.pdf(d1) / (S * sigma * math.sqrt(T)), S * math.sqrt(T) * norm.pdf(d1) / 100
def test_six_month_call():
"""The six-month call with 1% and one-vol-point bumps: delta 0.570054, gamma 0.027762, vega 0.277717"""
delta, gamma, vega = bump_greeks(_call, 100.0, 0.2)
expect_close(delta, 0.570054062469417, what="delta", rel=1e-9)
expect_close(gamma, 0.027762255136636327, what="gamma", rel=1e-9)
expect_close(vega, 0.27771682820363, what="vega per vol point", rel=1e-9)
def test_close_to_formulas():
"""The bumped Greeks agree with the closed forms to within 0.1%"""
for got, exact, name in zip(bump_greeks(_call, 100.0, 0.2), _formulas(100.0, 0.2), ("delta", "gamma", "vega")):
expect_close(got, exact, what=name, rel=1e-3)
def test_by_hand():
"""For price S²σ at S = 3, σ = 0.5: delta 3, gamma 1 and vega 0.09 per vol point"""
delta, gamma, vega = bump_greeks(lambda S, sigma: S**2 * sigma, 3.0, 0.5)
expect_close(delta, 3.0, what="delta of S²σ", rel=1e-9)
expect_close(gamma, 1.0, what="gamma of S²σ", rel=1e-6)
expect_close(vega, 0.09, what="vega of S²σ per vol point", rel=1e-9)
def test_relative_bump():
"""The stock bump is relative: a $5 stock with strike $5 has gamma within 0.1% of 0.555443"""
price = lambda S, sigma: _call(S, sigma, K=5.0)
gamma = bump_greeks(price, 5.0, 0.2)[1]
expect_close(gamma, _formulas(5.0, 0.2, K=5.0)[1], what="gamma of the $5 option", rel=1e-3)
def test_smaller_bump():
"""A smaller relative bump, 0.0001, gives gamma within 10⁻⁸ of the formula"""
gamma = bump_greeks(_call, 100.0, 0.2, rel_bump=1e-4)[1]
expect_close(gamma, _formulas(100.0, 0.2)[1], what="gamma with rel_bump=1e-4", abs_tol=1e-8, rel=0)
def test_bad_stock_price():
"""A stock price of 0 raises ValueError"""
try:
bump_greeks(_call, 0.0, 0.2)
except ValueError:
return
raise AssertionError("expected ValueError for S = 0")
def test_vol_bump_too_big():
"""A volatility bump of 0.25 when σ = 0.2 raises ValueError"""
try:
bump_greeks(_call, 100.0, 0.2, vol_bump=0.25)
except ValueError:
return
raise AssertionError("expected ValueError: σ − 0.25 is negative")
Summary card
- Bump-and-reprice estimates Greeks by central differences of the price: , , vega .
- For the six-month call, 1% and one-vol-point bumps match the closed forms to 0.04% or better.
- Gamma is the most sensitive: its rounding error grows like . A noisy pricer raises that error and pushes the best bump up. Desks use about 1% and check that halving it barely changes the answer.
- Bump the stock in proportion to its price, and the volatility by vol points; know the units and the sign of a position.
- A bump must be small next to the scale on which the price bends, . At a corner or a jump, as at expiry, the bumped Greek measures only the bump.
- Simpson's rule values a continuous cash flow from a few points: case study 2.5.5's schedules combine to the exact $78,693.87.