Just as Black-Scholes (1973), we also are keen to take note of risk factors for the Black (1973) model. Greek values in options trading are quite important, as they permit us to take a mathematical viewpoint of our positions as well as gauge our varying risk exposures. The Greeks provide insights into the parameter sensitivities of the Black Model. Option Greeks measure the change in the option price (or other option characteristic for a change in an option input.
delta: the sensitivity of the option price to a change in the Futures price
gamma: the change in delta as the Futures price changes
vega: the sensitivity of the option price to volatility or sigma
theta: the sensitivity of the option price to time decay
rho: the sensitivity of the option price to interest rate changes
The Greeks are widely used in practice to assess the risk of an option position. In the second a half of the video below please follow implementation of Greeks formulae for the Black (1976) model
The Black (1976) model is the standard model used by traders to understand and communicate the risk of an option portfolio. Below, we implement using these measures using Excel VBA.
'probability density function
'The normal probability density, N'(x), is defined as pdf
Function pdf(x)
pdf = Exp(-x ^ 2 / 2) / (Sqr(2 * Application.Pi()))
End Function
'Black Model
Function BlackPut(F, K, T, r, Sigma)
BlackPut = Exp(-T * r) * _
(K * Application.NormSDist(-dTwo(F, K, T, r, Sigma)) _
- (F * Application.NormSDist(-done(F, K, T, r, Sigma))))
End Function
Function BlackCall(F, K, T, r, Sigma)
BlackCall = Exp(-T * r) * _
(F * Application.NormSDist(done(F, K, T, r, Sigma)) _
- (K * Application.NormSDist(dTwo(F, K, T, r, Sigma))))
End Function
Function done(F, K, T, r, Sigma)
done = (Log(F / K) + (0.5 * Sigma * Sigma) * T) / (Sigma * Sqr(T))
End Function
Function dTwo(F, K, T, r, Sigma)
dTwo = done(F, K, T, r, Sigma) - Sigma * Sqr(T)
End Function
'Delta
Function BlackCallDelta(F, K, T, r, Sigma)
BlackCallDelta = Exp(-r * T) _
* Application.NormSDist(done(F, K, T, r, Sigma))
End Function
Function BlackPutDelta(F, K, T, r, Sigma)
BlackPutDelta = Exp(-r * T) _
* (Application.NormSDist(done(F, K, T, r, Sigma)) - 1)
End Function
'Gamma
Function BlackCallGamma(F, K, T, r, Sigma)
BlackCallGamma = Exp(-r * T) * (pdf(done(F, K, T, r, Sigma)) / (F * Sigma * Sqr(T)))
End Function
Function BlackPutGamma(F, K, T, r, Sigma)
BlackPutGamma = Exp(-r * T) * (pdf(done(F, K, T, r, Sigma)) / (F * Sigma * Sqr(T)))
End Function
'Vega
Function BlackCallVega(F, K, T, r, Sigma)
BlackCallVega = F * Exp(-r * T) * Sqr(T) * pdf(done(F, K, T, r, Sigma))
End Function
Function BlackPutVega(F, K, T, r, Sigma)
BlackPutVega = F * Exp(-r * T) * Sqr(T) * pdf(done(F, K, T, r, Sigma))
End Function
'Theta
Function BlackCallTheta(F, K, T, r, Sigma)
BlackCallTheta = -(F * Exp(-T * r) * pdf(done(F, K, T, r, Sigma)) * Sigma) _
/ (2 * Sqr(T)) + r * F * Exp(-T * r) * Application.NormSDist(done(F, K, T, r, Sigma)) _
- r * K * Exp(-T * r) * Application.NormSDist(dTwo(F, K, T, r, Sigma))
End Function
Function BlackPutTheta(F, K, T, r, Sigma)
BlackPutTheta = -(F * pdf(done(F, K, T, r, Sigma)) _
* Sigma * Exp(-r * T)) / (2 * Sqr(T)) - r * F * Application.NormSDist(-done(F, K, T, r, Sigma)) _
* Exp(-r * T) + r * K * Exp(-r * T) * Application.NormSDist(-dTwo(F, K, T, r, Sigma))
End Function
'Rho
Function BlackCallRho(F, K, T, r, Sigma)
BlackCallRho = T * K * Exp(-T * r) * Application.NormSDist(dTwo(F, K, T, r, Sigma))
End Function
Function BlackPutRho(F, K, T, r, Sigma)
BlackPutRho = -K * T * Exp(-r * T) * Application.NormSDist(-dTwo(F, K, T, r, Sigma))
End Function
It is possible using the Visual Basic programming language to create your own dialog boxes. This can be quite practical because many within the Excel environment - you can create your own app. Excel is a standard work-horse within many organisation. You can create powerful user interfaces and lock down formulae in the VBA environment. It is relatively simple to create custom dialog boxes for your applications. Custom dialog boxes can be used to request specific information, get a user's options or preferences. Custom dialog boxes are created using the UserForms . Here we provide VBA code and video demonstrating how to create a user interface to estimate Black (1976) option Greeks.
Dim d1 As Double
Dim d2 As Double
Dim Nd1 As Double
Dim Nd2 As Double
d1 = (Log(F / K) + (v ^ 2) * T / 2) / (v ^ (T ^ 0.5))
d2 = d1 - v * (T ^ (0.5))
Nd1 = Application.NormSDist(d1)
Nd2 = Application.NormSDist(d2)
Black = Exp(-r * T) * (F * Nd1 - K * Nd2)
Delta = Exp(-r * T) * Nd1
CND = (1 / ((2 * Application.Pi()) ^ 0.5)) * Exp(-(d1 ^ 2) / 2)
Gamma = (CND * Exp(-r * T)) / (F * v * (T ^ 0.5))
Vega = F * Exp(-r * T) * (T ^ (0.5)) * CND
Theta = -(F * Exp(-r * T) * CND * v) / (2 * (T ^ 0.5)) + r * Exp(-r * T) * (F * Nd1 - K * Nd2)
Rho = T * K * Exp(-r * T) * Nd2
Dim NNd1 As Double
Dim NNd2 As Double
NNd1 = Application.NormSDist(-d1)
NNd2 = Application.NormSDist(-d2)
BlackP = Exp(-r * T) * (K * NNd2 - F * NNd1)
DeltaP = Exp(-r * T) * (Nd1 - 1)
GammaP = (CND * Exp(-r * T)) / (F * v * (T ^ 0.5))
VegaP = F * Exp(-r * T) * (T ^ (0.5)) * CND
ThetaP = -(F * Exp(-r * T) * CND * v) / (2 * (T ^ 0.5)) - r * Exp(-r * T) * (F * NNd1 - K * NNd2)
RhoP = -T * K * Exp(-r * T) * NNd2
In the code below, we apply Espen Haug's approach and set out a Generlized Black Scholes format that permits Black (1976) estimation. The Davis Edwards Github can be found here.
# This document demonstrates a Python implementation of some option models described in books written by Davis
# Edwards: "Energy Trading and Investing", "Risk Management in Trading", "Energy Investing Demystified".
# The gbs approach follows Espen Haug
# for backward compatability with Python 2.7
from __future__ import division
# import necessary libaries
import math
import numpy as np
from scipy.stats import norm
from scipy.stats import mvn
# The primary class for calculating Generalized Black Scholes option prices and deltas
# Inputs: option_type = "p" or "c", fs = price of underlying, x = strike, t = time to expiration, r = risk free rate
# b = cost of carry, v = implied volatility
# Outputs: value, delta, gamma, theta, vega, rho
def _gbs(option_type, fs, x, t, r, b, v):
# Create preliminary calculations
t__sqrt = math.sqrt(t)
d1 = (math.log(fs / x) + (b + (v * v) / 2) * t) / (v * t__sqrt)
d2 = d1 - v * t__sqrt
if option_type == "c":
# it's a call
# _debug(" Call Option")
value = fs * math.exp((b - r) * t) * norm.cdf(d1) - x * math.exp(-r * t) * norm.cdf(d2)
delta = math.exp((b - r) * t) * norm.cdf(d1)
gamma = math.exp((b - r) * t) * norm.pdf(d1) / (fs * v * t__sqrt)
theta = -(fs * v * math.exp((b - r) * t) * norm.pdf(d1)) / (2 * t__sqrt) - (b - r) * fs * math.exp(
(b - r) * t) * norm.cdf(d1) - r * x * math.exp(-r * t) * norm.cdf(d2)
vega = math.exp((b - r) * t) * fs * t__sqrt * norm.pdf(d1)
rho = x * t * math.exp(-r * t) * norm.cdf(d2)
else:
# it's a put
# _debug(" Put Option")
value = x * math.exp(-r * t) * norm.cdf(-d2) - (fs * math.exp((b - r) * t) * norm.cdf(-d1))
delta = -math.exp((b - r) * t) * norm.cdf(-d1)
gamma = math.exp((b - r) * t) * norm.pdf(d1) / (fs * v * t__sqrt)
theta = -(fs * v * math.exp((b - r) * t) * norm.pdf(d1)) / (2 * t__sqrt) + (b - r) * fs * math.exp(
(b - r) * t) * norm.cdf(-d1) + r * x * math.exp(-r * t) * norm.cdf(-d2)
vega = math.exp((b - r) * t) * fs * t__sqrt * norm.pdf(d1)
rho = -x * t * math.exp(-r * t) * norm.cdf(-d2)
return value, delta, gamma, theta, vega, rho
# This is the public interface for European Options
# Each call does a little bit of processing and then calls the calculations located in the _gbs module
# Inputs:
# option_type = "p" or "c"
# fs = price of underlying
# x = strike
# t = time to expiration
# v = implied volatility
# r = risk free rate
# q = dividend payment
# b = cost of carry
# Outputs:
# value = price of the option
# delta = first derivative of value with respect to price of underlying
# gamma = second derivative of value w.r.t price of underlying
# theta = first derivative of value w.r.t. time to expiration
# vega = first derivative of value w.r.t. implied volatility
# rho = first derivative of value w.r.t. risk free rates
# Merton Model: Stocks Index, stocks with a continuous dividend yields
def merton(option_type, fs, x, t, r, q, v):
b = r - q
return _gbs(option_type, fs, x, t, r, b, v)
def black_76(option_type, fs, x, t, r, v):
b = 0
return _gbs(option_type, fs, x, t, r, b, v)
black_76('c', fs=100, x=100, t=1, r=0.05, v=0.20)
# c = black_76('c', fs=100, x=100, t=1, r=0.05, v=0.20)
# print( c )