Options Greeks are a set of quantities representing an option’s price sensitivity to its underlying parameters. Each of them measures a different dimension of the risk in an option position.
They fall out elegantly from derivatives of the Black-Scholes options pricing formula.
This tutorial will go through the Options Greeks, and how to derive them from derivatives of the Black-Scholes option pricing formula for call and put options.
Then we will go through how to create functions to calculate the Options Greeks in Python, C++, and R with code examples.
Table of contents
What is the Black-Scholes Options Pricing Formula
The Black-Scholes or Black-Scholes-Merton model is a financial mathematical equation for pricing options contracts and other derivatives.
Using the Black-Scholes model, the price of a European call option is calculated using the formula:
$$C= S_{0}N(d_{1})~- Xe^{-r\tau}N(d_{2}) $$
and for the price of a European put option:
$$P= ~- Xe^{-r\tau}N(d_{2}) ~- S_{0}N(-d_{1})$$
With:
$$d_{1} = \frac{\text{ln}\frac{S_{0}}{X} + (r + \sigma^{2}/2)*\tau}{\sigma\sqrt{\tau}}, \qquad d_{2} = \frac{\text{ln}\frac{S_{0}}{X} + (r – \sigma^{2}/2)*\tau}{\sigma\sqrt{\tau}} = d_{1} – \sigma\sqrt{\tau}$$
Where:
- C = price of the call option
- S0 = price of the underlying stock
- X = option exercise price or strike price
- r = risk-free interest rate
- 𝛕 = time until expiration (maturity)
- 𝞂 = the volatility of the underlying asset.
N represents the cumulative distribution function for a normal (Gaussian) distribution, which we can understand as “the probability that a random variable is less or equal to its input for a normal distribution”.
We can think of the two terms in the sum as the current price in the stock weighted by the probability of exercising the option to buy the stock minus the discounted price of exercising the option weighted by the probability of exercising the option. In other words, what you will pay minus what you will receive (Introduction to the Black-Scholes formula, Khan Academy 2013).
The Option Greeks Explained
Option Greeks are a set of quantities representing an option’s price sensitivity to its underlying parameters. Each of them measures a different dimension of the risk in an option position.
Delta (Δ)
Delta measures the rate of change of option value with respect to changes in the underlying asset’s price
$$\Delta = \frac{\partial V}{\partial S_{0}} $$
Gamma (Γ)
Gamma measures the rate of change in Delta with respect to changes in the underlying price.
$$\Gamma = \frac{\partial \Delta}{\partial S_{0}} $$
Theta (ϴ)
Theta measures the sensitivity of the option value to the passage of time.
$$\Theta = -\frac{\partial V}{\partial \tau} $$
Vega (V)
Vega is the rate of change of the option price with respect to the underlying stock’s volatility.
$$\nu = \frac{\partial V}{\partial \sigma} $$
For further reading on how volatility is found, go to the article: How to Calculate Implied Volatility in Python.
Rho (ρ)
Rho is the rate of change of the option price with respect to the interest rate.
$$\rho = \frac{\partial V}{\partial r} $$
Where V denotes the option’s value, either C for the call option or P for the put option.
Options Greeks Expressions
Taking the Black-Scholes Formulae for call and put option pricing as follows:
$$ C= S_{0}N(d_{1}) ~- Xe^{-rt}N(d_{2}), \qquad P= -S_{0}N(-d_{1}) ~- Xe^{-rt}N(d_{2})$$
The expressions for the Options Greeks can be derived as follows:
Call option (C): $$ \Delta = \frac{\partial C}{\partial S_{0}} = N(d_{1})$$ $$ \Theta = -\frac{\partial C}{\partial \tau} = -rXe^{-r\tau}N(d_{2}) ~- \frac{\sigma}{2\sqrt{\tau}}S_{0}n(d_{1})$$ $$ \Gamma = \frac{\partial \Delta}{\partial S_{0}} = \frac{1}{S_{0}\sigma\sqrt{\tau}}n(d_{1})$$ $$ \nu = \frac{\partial C}{\partial \sigma} = \sqrt{\tau}S_{0}n(d_{1}) $$ $$ \rho = \frac{\partial C}{\partial r} = \tau Xe^{-r\tau}N(d_{2}) $$ Put option (C): $$ \Delta = \frac{\partial P}{\partial S_{0}} = N(d_{1}) ~- 1$$ $$ \Theta = ~-\frac{\partial P}{\partial \tau} = ~- \frac{\sigma}{2\sqrt{\tau}}S_{0}n(d_{1}) + rXe^{-r\tau}N(-d_{2}) $$ $$ \Gamma = \frac{\partial \Delta}{\partial S_{0}} = \frac{1}{S_{0}\sigma\sqrt{\tau}}n(d_{1})$$ $$ \nu = \frac{\partial P}{\partial \sigma} = \sqrt{\tau}S_{0}n(d_{1}) $$ $$ \rho = \frac{\partial P}{\partial r} = -\tau Xe^{-r\tau}N(-d_{2}) $$
Calculate Options Greeks using Black-Scholes Formula in Python
Let’s go through how to calculate the Options Greeks in Python. First, we will import the necessary mathematical and statistical functions from math
and scipy.stats
. Then, we will define functions for the d1 and d2 variables, and the call and put options pricing.
from math import log, sqrt, pi, exp from scipy.stats import norm # Function for d1 variable def d1(S,K,T,r,sigma): return(log(S/K)+(r+sigma**2/2.)*T)/(sigma*sqrt(T)) # Function for d2 variable def d2(S,K,T,r,sigma): return d1(S,K,T,r,sigma)-sigma*sqrt(T) # Function for Call option pricing using Black-Scholes def bs_call(S,K,T,r,sigma): return S*norm.cdf(d1(S,K,T,r,sigma))-K*exp(-r*T)*norm.cdf(d2(S,K,T,r,sigma)) # Function for Put option pricing using Black-Scholes def bs_put(S,K,T,r,sigma): return K*exp(-r*T)*norm.cdf(-1 * d2(S,K,T,r,sigma)) - S*norm.cdf(-1*d1(S,K,T,r,sigma))
Next, we will define the call Option Greeks using the expressions in the Options Greeks Expressions section.
# Function for Call Delta function def call_delta(S, K, T, r, sigma): return norm.cdf(d1(S,K,T,r,sigma)) # Function for Call Theta function def call_theta(S,K,T,r,sigma): theta_1 = -r*K*exp(-r*T)*norm.cdf(d2(S,K,T,r,sigma)) theta_2 = sigma*S*norm.pdf(d1(S,K,T,r,sigma))/(2*sqrt(T)) # Divide by 365 to get the change in option price per one calendar day, otherwise change would be per one year theta = (theta_1 - theta_2) / 365 return theta # Function for Call Gamma function def call_gamma(S, K, T, r, sigma): return norm.pdf(d1(S,K,T,r,sigma))/(S*sigma*sqrt(T)) # Function for Call Vega function def call_vega(S, K, T, r, sigma): return 0.01 * (sqrt(T)*S*norm.pdf(d1(S, K, T, r, sigma))) # Function for Call Rho function def call_rho(S, K, T, r, sigma): return 0.01 * (T*K*exp(-r*T)*norm.cdf(d2(S, K, T, r, sigma)))
Next, we will define the put Option Greeks using the expressions in the Options Greeks Expressions section.
# Function for Put Delta function def put_delta(S, K, T, r, sigma): return norm.cdf(d1(S,K,T,r,sigma)) - 1 # Function for Put Theta function def put_theta(S, K, T, r, sigma): theta_1 = -1*sigma*S*norm.pdf(d1(S,K,T,r,sigma))/(2*sqrt(T)) theta_2 = r*K*exp(-r*T)*norm.cdf(-1*d2(S,K,T,r,sigma)) # Divide by 365 to get the change in option price per one calendar day, otherwise change would be per one year theta = (theta_1 + theta_2) / 365 return theta # Function for Put Gamma function def put_gamma(S, K, T, r, sigma): return norm.pdf(d1(S,K,T,r,sigma))/(S*sigma*sqrt(T)) # Function for Put Vega function def put_vega(S, K, T, r, sigma): return 0.01 * (sqrt(T)*S*norm.pdf(d1(S, K, T, r, sigma))) # Function for Put Rho function def put_rho(S, K, T, r, sigma): return 0.01 * -1* (T*K*exp(-r*T)*norm.cdf(-1*d2(S, K, T, r, sigma)))
Now, we can define our main function, and set values for the price of the underlying stock, the strike price, the risk-free interest rate, volatility, and the time until expiration. We can then price the call and put options and calculate the Options Greeks.
if __name__ == '__main__': S = 110 K = 100 T = 1 r = 0.04 sigma = 0.2 call = bs_call(S, K, T, r, sigma) delta = call_delta(S,K,T,r,sigma) gamma = call_gamma(S,K,T,r,sigma) theta = call_theta(S,K,T,r,sigma) rho = call_rho(S,K,T,r,sigma) vega = call_vega(S,K,T,r,sigma) put = bs_put(S, K, T, r, sigma) put_delta = put_delta(S,K,T,r,sigma) put_gamma = put_gamma(S,K,T,r,sigma) put_theta = put_theta(S,K,T,r,sigma) put_rho = put_rho(S,K,T,r,sigma) put_vega = put_vega(S,K,T,r,sigma) print('Call option price:', round(call,2)) print('Call Delta: ', round(delta,3)) print('Call Gamma: ', round(gamma,3)) print('Call Theta: ', round(theta,3)) print('Call Rho: ', round(rho,3)) print('Call Vega: ', round(vega,3)) print('===================================') print('Put option price:', round(put,2)) print('Put Delta: ', round(put_delta,3)) print('Put Gamma: ', round(put_gamma,3)) print('Put Theta: ', round(put_theta,3)) print('Put Rho: ', round(put_rho,3)) print('Put Vega: ', round(put_vega,3))
Let’s run the code to see the result:
Call option price: 16.97 Call Delta: 0.781 Call Gamma: 0.013 Call Theta: -0.016 Call Rho: 0.69 Call Vega: 0.325 =================================== Put option price: 3.05 Put Delta: -0.219 Put Gamma: 0.013 Put Theta: -0.006 Put Rho: -0.271 Put Vega: 0.325
Calculate Options Greeks using Black-Scholes Formula in C++
Let’s go through how to calculate the Options Greeks in C++. First, we will define the Standard normal probability density function, cumulative distribution function, the d1,d2 variables, and the call and put option pricing formulae.
#include <iostream> #include <cmath> // Standard normal probability density function double norm_pdf(const double& x) { return (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x); } // Standard normal cumulative distribution function double normalCDF(double x) // Phi(-∞, x) aka N(x){ return std::erfc(-x/std::sqrt(2))/2; } // d1 variable double d_1(const double& S, const double& K, const double& r, const double& T, const double& sig){ return (log(S/K) + (r + pow(sig,2)/2)*T) / (sig*(pow(T,0.5))); } // d1 variable double d_2(const double& S, const double& K, const double& r, const double& T, const double& sig) { return (log(S/K) + (r - pow(sig,2)/2)*T) / (sig*(pow(T,0.5))); } // Function for Call option pricing using Black-Scholes double call_price(const double& S, const double& K, const double& r, const double& T, const double& sig) { return S * normalCDF((d_1(S, K, r, T, sig))) - K*exp(-r*T)* normalCDF(d_2(S,K, r, T, sig)); } // Function for Put option pricing using Black-Scholes double put_price(const double& S, const double& K, const double& r, const double& T, const double& sig) { return -S * normalCDF(-d_1(S, K, r, T, sig)) + K*exp(-r*T)* normalCDF(-d_2(S,K, r, T, sig)); }
Next, let’s define functions for the call and put Option Greeks using the expressions in the Options Greeks Expressions section.
// Function for Call Delta double call_delta(const double& S, const double& K, const double& r, const double& T, const double& sig) { return normalCDF(d_1(S,K,r,T,sig)); } // Function for Call Gamma double call_gamma(const double& S, const double& K, const double& r, const double& T, const double& sig) { return norm_pdf(d_1(S,K,r,T,sig))/(S*sig*pow(T,0.5)); } // Function for Call Theta double call_theta(const double& S, const double& K, const double& r, const double& T, const double& sig) { double theta_1 = -r*K*exp(-r*T)* normalCDF(d_2(S,K,r,T,sig)); double theta_2 = sig*S* norm_pdf(d_1(S,K,r,T,sig))/(2*pow(T,0.5)); // Divide by 365 to get the change in option price per one calendar day, otherwise change would be per one year double theta = (theta_1 - theta_2) / 365; return theta; } // Function for Call Rho double call_rho(const double& S, const double& K, const double& r, const double& T, const double& sig) { return 0.01 * (T * K * exp(-r * T)* normalCDF(d_2(S,K,r,T,sig))); } // Function for Call Vega double call_vega(const double& S, const double& K, const double& r, const double& T, const double& sig) { return 0.01 * (pow(T,0.5) * S * norm_pdf(d_1(S,K,r,T,sig))); }
// Function for Put Delta double put_delta(const double& S, const double& K, const double& r, const double& T, const double& sig) { return normalCDF(d_1(S,K,r,T,sig)) - 1; } // Function for Put Gamma double put_gamma(const double& S, const double& K, const double& r, const double& T, const double& sig) { return norm_pdf(d_1(S,K,r,T,sig))/(S*sig*pow(T,0.5)); } // Function for Put Theta double put_theta(const double& S, const double& K, const double& r, const double& T, const double& sig) { double theta_1 = -1*sig*S* norm_pdf(d_1(S,K,r,T,sig))/(2*pow(T,0.5)); double theta_2 = r*K*exp(-r*T)* normalCDF(-1*d_2(S,K,r,T,sig)); // Divide by 365 to get the change in option price per one calendar day, otherwise change would be per one year double theta = (theta_1 + theta_2) / 365; return theta; } // Function for Put Rho double put_rho(const double& S, const double& K, const double& r, const double& T, const double& sig) { return 0.01 * -1 *(T * K * exp(-r * T)* normalCDF(-1* d_2(S,K,r,T,sig))); } // Function for Put Vega double put_vega(const double& S, const double& K, const double& r, const double& T, const double& sig) { return 0.01 * (pow(T,0.5) * S * norm_pdf(d_1(S,K,r,T,sig))); }
Now, we can define our main function, and set values for the price of the underlying stock, the strike price, the risk-free interest rate, the volatility, and the time until expiration. We can then price the call and put options and calculate the Options Greeks.
int main() { // First we create the parameter list double S = 110.0; // Option price double K = 100.0; // Strike price double r = 0.04; // Risk-free rate (5%) double sig = 0.2; // Volatility of the underlying (20%) double T = 1.0; // One year until expiry // Then we calculate the call/put values // double call = call_price(S, K, r, T, sig); // double put = put_price(S, K, r, T, sig); // Then we calculate the call/put values double call = call_price(S, K, r, T, sig); double put = put_price(S, K, r, T, sig); double delta = call_delta(S, K, r, T, sig); double theta = call_theta(S, K, r, T, sig); double gamma = call_gamma(S, K, r, T, sig); double vega = call_vega(S, K, r, T, sig); double rho = call_rho(S, K, r, T, sig); double p_delta = put_delta(S, K, r, T, sig); double p_theta = put_theta(S, K, r, T, sig); double p_gamma = put_gamma(S, K, r, T, sig); double p_vega = put_vega(S, K, r, T, sig); double p_rho = put_rho(S, K, r, T, sig); // Output the parameters and prices std::cout << "Underlying: " << S << std::endl; std::cout << "Strike: " << K << std::endl; std::cout << "Risk-Free Rate: " << r << std::endl; std::cout << "Volatility: " << sig << std::endl; std::cout << "Maturity: " << T << std::endl; std::cout << "Call Price: " << call << std::endl; std::cout << "Put Price: " << put << std::endl; std::cout << "Call Delta: " << delta << std::endl; std::cout << "Call Gamma: " << gamma << std::endl; std::cout << "Call Theta: " << theta << std::endl; std::cout << "Call Rho: " << rho << std::endl; std::cout << "Call Vega: " << vega << std::endl; std::cout << "Put Delta: " << p_delta << std::endl; std::cout << "Put Gamma: " << p_gamma << std::endl; std::cout << "Put Theta: " << p_theta << std::endl; std::cout << "Put Rho: " << p_rho << std::endl; std::cout << "Put Vega: " << p_vega << std::endl; return 0; }
Let’s run the code to see the result:
Underlying: 110 Strike: 100 Risk-Free Rate: 0.04 Volatility: 0.2 Maturity: 1 Call Price: 16.9687 Put Price: 3.04762 Call Delta: 0.781288 Call Gamma: 0.0134135 Call Theta: -0.016452 Call Vega: 0.324606 Call Rho: 0.68973 Put Delta: -0.218712 Put Gamma: 0.0134135 Put Theta: -0.00592279 Put Vega: 0.324606 Put Rho: -0.271059
Calculate Options Greeks using Black-Scholes Formula in R
Let’s go through how to calculate the Options Greeks in R. First, we will define functions for the d1, d2 variables and the call and put option pricing.
# d1 variable d1 <- function(S, K, r, T, sig){ (log(S/K) + (r+sig^2/2)*T)/(sig*sqrt(T)) } # d2 variable d2 <- function(S, K, r, T, sig){ (log(S/K) + (r-sig^2/2)*T)/(sig*sqrt(T)) } # Function for Call option pricing using Black-Scholes call_price <- function(S, K, r, T, sig){ call <- S*pnorm(d1(S,K,r,T,sig)) - K*exp(-r*T)*pnorm(d2(S,K,r,T,sig)) return (call) } # Function for Put option pricing using Black-Scholes put_price <- function(S, K, r, T, sig){ put <- K*exp(-r*T)*pnorm(-d2(S,K,r,T,sig)) - S*pnorm(-d1(S,K,r,T,sig)) return (put) }
Let’s define the call and put Option Greeks using the expressions in the Options Greeks Expressions section.
# Function for Call Delta call_delta <- function(S,K,r,T,sig){ delta <- pnorm(d1(S,K,r,T,sig)) return(delta) } # Function for Call Gamma call_gamma <- function(S,K,r,T,sig){ gamma <- dnorm(d1(S,K,r,T,sig))/(S*sig*sqrt(T)) return(gamma) } # Function for Call Theta call_theta <- function(S,K,r,T,sig){ theta_1 = -1* r * K * exp(-r*T)*pnorm(d2(S,K,r,T,sig)) theta_2 = sig * S * dnorm(d1(S,K,r,T,sig))/(2*sqrt(T)) # Divide by 365 to get the change in option price per one calendar day, otherwise change would be per one year theta = (theta_1-theta_2)/365 return (theta) } # Function for Call Rho call_rho <- function(S,K,r,T,sig){ rho <- 0.01 * (T * K * exp(-r*T)*pnorm(d2(S,K,r,T,sig))) return(rho) } # Function for Call Vega call_vega <- function(S,K,r,T,sig){ vega <- 0.01 * (sqrt(T) * S * dnorm(d1(S,K,r,T,sig))) return(vega) }
# Function for Put Delta put_delta <- function(S,K,r,T,sig){ delta <- pnorm(d1(S,K,r,T,sig)) - 1 return(delta) } # Function for Put Gamma put_gamma <- function(S,K,r,T,sig){ gamma <- dnorm(d1(S,K,r,T,sig))/(S*sig*sqrt(T)) } # Function for Put Theta put_theta <- function(S,K,r,T,sig){ theta_1 = -1*sig * S * dnorm(d1(S,K,r,T,sig))/(2*sqrt(T)) theta_2 = r * K * exp(-r*T)*pnorm(-1* d2(S,K,r,T,sig)) theta = (theta_1+theta_2)/365 return (theta) } # Function for Put Rho put_rho <- function(S,K,r,T,sig){ rho <- 0.01 * -1* (T * K * exp(-r*T)*pnorm(-1*d2(S,K,r,T,sig))) } # Function for Put Vega put_vega <- function(S,K,r,T,sig){ vega <- 0.01 * (sqrt(T) * S * dnorm(d1(S,K,r,T,sig))) }
Next, we will call the defined functions to get the call and put options prices and the Options Greeks, then assign them to variables.
call <- call_price(110, 100, 0.04, 1, 0.2) put <- put_price(110, 100, 0.04, 1, 0.2) c_delta <- call_delta(110, 100, 0.04, 1, 0.2) c_gamma <- call_gamma(110, 100, 0.04, 1, 0.2) c_theta <- call_theta(110, 100, 0.04, 1, 0.2) c_rho <- call_rho(110, 100, 0.04, 1, 0.2) c_vega <- call_vega(110, 100, 0.04, 1, 0.2) p_delta <- put_delta(110, 100, 0.04, 1, 0.2) p_gamma <- put_gamma(110, 100, 0.04, 1, 0.2) p_theta <- put_theta(110, 100, 0.04, 1, 0.2) p_rho <- put_rho(110, 100, 0.04, 1, 0.2) p_vega <- put_vega(110, 100, 0.04, 1, 0.2)
Next, we will use the cat
function to print all of the values to the console:
cat("Call price=", call, "\nPut price=", put, "\nCall Delta=",c_delta, "\nCall Gamma=",c_gamma, "\nCall Theta=",c_theta, "\nCall Rho=",c_rho, "\nCall Vega=",c_vega, "\n\nPut Delta=",p_delta, "\nPut Gamma=",p_gamma, "\nPut Theta=",p_theta, "\nPut Rho=",p_rho, "\nPut Vega=",p_vega )
Let’s run the code to get the result:
Call price= 16.96868 Put price= 3.047622 Call Delta= 0.7812881 Call Gamma= 0.01341346 Call Theta= -0.01645199 Call Rho= 0.6897301 Call Vega= 0.3246057 Put Delta= -0.2187119 Put Gamma= 0.01341346 Put Theta= -0.005922795 Put Rho= -0.2710593 Put Vega= 0.3246057
Summary
Congratulations on reading to the end of this tutorial!
For further reading on the Black-Scholes Option Pricing model and how to use it in R, Python, and C++, go to the articles:
- Black-Scholes Option Pricing in R
- Black-Scholes Option Pricing in Python
- Black-Scholes Option Pricing in C++
You can use our free Black-Scholes option pricing calculator to estimate the fair value of a European call or put option.
You can use our free Implied Volatility calculator to estimate the Implied Volatility of a priced option.
Have fun and happy researching!
Suf is a senior advisor in data science with deep expertise in Natural Language Processing, Complex Networks, and Anomaly Detection. Formerly a postdoctoral research fellow, he applied advanced physics techniques to tackle real-world, data-heavy industry challenges. Before that, he was a particle physicist at the ATLAS Experiment of the Large Hadron Collider. Now, he’s focused on bringing more fun and curiosity to the world of science and research online.