Introduction
Option Greeks measure the exposure of option price or option delta to movement of different factors such as the underlying price, time and volatility. In this tutorial we will discuss various Greeks, their meanings and their implications on the pricing and how to use them to hedge risks.
Delta
Delta, , is the rate of change of the option price with respect to the price of the underlying asset. It measures the first-order sensitivity of the price to a movement in stock price S. The option delta is 0.4 means that if the underlying moves by for example 1%, then the value of the option will move by 0.4 × 1%. For European options on an asset that provides a yield at rate q:
def delta(self):
d1 = self.d1()
if self.type == "c":
return exp(-self.q * self.T) * self.n(d1)
elif self.type == "p":
return exp(-self.q * self.T) * (self.n(d1)-1)
Stock price, days remaining to expiration and implied volatility will impact the Delta.
- Stock Price: Call option has a positive Delta range from 0 to 1. The Delta is positively correlated to underlying stock price change. While put option has a negative Delta ranges from -1 to 0, its Delta is negatively correlated with the underlying stock price change. At-the-money call options usually have a Delta near 0.50. At-the-money put options have a Delta near -.50.
- Implied Volatility: Low implied volatility stocks will tend to have higher Delta for the in-the-money options and lower Delta for out-of-the-money options.
- Days remaining to expiration: As expiration nears, in-the-money call Deltas increase toward 1, at-the-money call Deltas remain at around 0.5 and out-of-the-money call Deltas fall to 0 provided other inputs remain constant.
As a general rule, in-the-money options will move more than out-of-the-money options, and short-term options will react more than longer-term options to the same price change in the stock.
In order to demonstrate how those Greeks values change with the time to expiration and the underlying price, we choose 60 * 23 call options contracts with the stock price ranging from 10 to 70, time to expiration ranging from 0 to 1 year. The strikes of all the contracts are 40, the interest rates are 0.1, the volatilities are all 0.5. We construct the contracts data as a 23 * 60 matrix.
s = np.array([range(10,70,1) for i in range(23)])
I = np.ones((shape(s)))
time = arange(1,12.5,0.5)/12
T = np.array([ele for ele in time for i in range(shape(s)[1])]).reshape(shape(s))
contracts = []
for i in range(shape(s)[0]):
for j in range(shape(s)[1]):
contracts.append(BsmModel('c',s[i,j],40*I[i,j],0.1*I[i,j], T[i,j],0.5*I[i,j]))
delta = np.array([x.delta() for x in contracts]).reshape(shape(s))
gamma = np.array([x.gamma() for x in contracts]).reshape(shape(s))
vega = np.array([x.vega() for x in contracts]).reshape(shape(s))
theta = np.array([x.theta() for x in contracts]).reshape(shape(s))
rho = np.array([x.rho() for x in contracts]).reshape(shape(s))
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib import animation
z = delta
fig = plt.figure(figsize=(20,11))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(40,290)
ax.plot_wireframe(s, T, z, rstride=1, cstride=1)
ax.plot_surface(s, T, z, facecolors=cm.jet(delta),linewidth=0.001, rstride=1, cstride=1, alpha = 0.75)
ax.set_zlim3d(0, z.max())
ax.set_xlabel('stock price')
ax.set_ylabel('Time to Expiration')
ax.set_zlabel('delta')
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(z)
cbar = plt.colorbar(m)
The color of the graph above represents delta value.
Gamma
Gamma, , is the rate of change of the portfolio's delta with respect to the underlying asset's price. It represents the second-order sensitivity of the option to a movement in the underlying asset’s price.
Long options, either calls or puts, always yield positive Gamma. Gamma is higher for options that are at-the-money and closer to expiration because the Delta of the near term options move toward either 0 or 1 is imminent. Deeper-in-the-money or farther-out-of-the-money options have lower Gamma as their Deltas already approached 0 or 1 (or 0 or -1 for puts) and will not change as quickly with movement in the underlying. For European options:
def gamma(self):
d1 = self.d1()
dn1 = self.dn(d1)
return dn1 * exp(-self.q * self.T) / (self.s * self.sigma * sqrt(self.T))
z = gamma
fig = plt.figure(figsize=(20,11))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(12,320)
ax.plot_wireframe(s, T, z, rstride=1, cstride=1)
ax.plot_surface(s, T, z, facecolors=cm.jet(delta),linewidth=0.001, rstride=1, cstride=1, alpha = 0.75)
ax.set_zlim3d(0, z.max())
ax.set_xlabel('stock price')
ax.set_ylabel('Time to Expiration')
ax.set_zlabel('gamma')
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(delta)
cbar = plt.colorbar(m)
The color of the graph above represents delta value.
Vega
The Vega, , is the rate of change in the value of the option with respect to the volatility of the underlying asset.
Vega is always positive for long positions and is the same value for both puts and calls. Hence the option price always increases as the volatility increases. Vega for the European options:
def vega(self):
d1 = self.d1()
dn1 = self.dn(d1)
return self.s * sqrt(self.T) * dn1 * exp(-self.q * self.T)
z = vega
norm = matplotlib.colors.Normalize()
fig = plt.figure(figsize=(20,11))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(20,45)
ax.plot_wireframe(s, T, z, rstride=1, cstride=1)
ax.plot_surface(s, T, z, facecolors=cm.jet(norm(z)),linewidth=0.001, rstride=1, cstride=1, alpha = 0.9)
ax.set_zlim3d(z.min(), z.max())
ax.set_xlabel('stock price')
ax.set_ylabel('Time to Expiration')
ax.set_zlabel('vega')
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(z)
cbar = plt.colorbar(m)
The color of the graph above represents Vega.
Theta
Theta, , is the rate of change of the value of the option with respect to the passage of time. It is also referred to as the time decay of the portfolio.
The theta of holding long position of a call or a put option is usually negative. An option that loses 0.1% per day is said to have a Theta of −0.1%. For example, if we buy an OTM call option, the value of this call option decreases as time passes since the option has less time to expiry. If time passes with the price of the underlying asset and its volatility remaining the same, the passing of time will lower the value of the option. Theta for European Options
def theta(self):
d1 = self.d1()
d2 = d1 - self.sigma * sqrt(self.T)
dn1 = self.dn(d1)
if self.type == "c":
return -self.s * dn1 * self.sigma * exp(-self.q*self.T) / (2 * sqrt(self.T)) \
+ self.q * self.s * self.n(d1) * exp(-self.q*self.T) \
- self.r * self.k * exp(-self.r*self.T) * self.n(d2)
if self.type == "p":
return -self.s * dn1 * self.sigma * exp(-self.q * self.T) / (2 * sqrt(self.T)) \
- self.q * self.s * self.n(-d1) * exp(-self.q * self.T) \
+ self.r * self.k * exp(-self.r * self.T) * self.n(-d2)
z = theta
# facecolors aren't normalizing as might be expected
# we need to normalize it to avoid all dark color for value under 0
norm = matplotlib.colors.Normalize()
fig = plt.figure(figsize=(20,11))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(35,300)
ax.plot_wireframe(s, T, z, rstride=1, cstride=1)
ax.plot_surface(s, T, z, facecolors=cm.jet(norm(z)),linewidth=0.001, rstride=1, cstride=1, alpha = 0.9)
ax.set_zlim3d(z.min(), z.max())
ax.set_xlabel('stock price')
ax.set_ylabel('Time to Expiration')
ax.set_zlabel('rho')
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(z)
cbar = plt.colorbar(m)
Rho
Rho, , is the rate of change of the value of a derivative with respect to the interest rate. It is usually small and not a big issue in practice unless the option is deep in-the-money and has a long horizon. The interest rate would matter because we need to discount a larger cash flow over a longer horizon. Rho for the European options:
def rho(self):
d2 = self.d2()
if self.type == "c":
return self.k * self.T * (exp(-self.r*self.T)) * self.n(d2)
if self.type == "p":
return -self.k * self.T * (exp(-self.r*self.T)) * self.n(-d2)
z = rho
norm = matplotlib.colors.Normalize()
fig = plt.figure(figsize=(20,11))
ax = fig.add_subplot(111, projection='3d')
ax.view_init()
ax.plot_wireframe(s, T, z, rstride=1, cstride=1)
ax.plot_surface(s, T, z, facecolors=cm.jet(norm(z)),linewidth=0.001, rstride=1, cstride=1, alpha = 0.9)
ax.set_zlim3d(z.min(), z.max())
ax.set_xlabel('stock price')
ax.set_ylabel('Time to Expiration')
ax.set_zlabel('vega')
m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(z)
cbar = plt.colorbar(m)
Delta, Gamma and Vega Hedging
The delta of the underlying asset is always 1, the trader can hedge his positions by buying or selling the number of shares of the underlying asset indicated by the total delta. However, underlying asset positions have Gamma 0 because their Delta is always 1 (long) or -1 (short) and will not change. In addition, Vega of the underlying asset is also zero because the underlying asset's payoff doesn't vary depending on how its price moves (payoff is not contingent). Therefore, its price is not affected by price volatility.
In order to adjust Gamma and Vega, it is necessary to take a position in an option or other derivatives. However, if only one other derivative is added, either the Gamma risk or the Vega risk will be canceled out, but not both at the same time. Here we need to use 2 derivatives to make the portfolio delta, gamma, and vega neutral all at once. Note, Vega and Gamma for a portfolio is the sum of the vegas and Gammas of its constituents.
Summary
In this chapter we discussed various Greeks, their meanings and their implications on the pricing and hedging of derivatives. We also presented some useful formulas for calculating the Greeks value of European options and generated the plots to show how they changed with strikes and time to expirations. The Greeks letter is the sensitivity measure of options price to the market variables. Next chapter we will discuss another major risk measures: volatility.