2
$\begingroup$

I am interested about greeks with Black-Scholes. In this case, I have the python formula to compute the greek called "Vanna", that is: $\frac{\partial^2 P}{\partial \sigma \partial S}$ the sensitivity of option value P with respect to a joint movement in underlying and volatility.

Now, let's consider the following example, with S = [100,120] a list of 50 equispaced points and $\sigma$ = [0.05,0.7] another list of 50 equispaced points, in the code below I am able to generate the plot of this greek, with respect each element of S and $\sigma$, i.e. with respect the first element of S and first element of $\sigma$ list, after that with respect to the second element of both list, till the last element of both list.

My question is: How can I take all the possible combinations, between these 2 lists? Maybe it can be done with a 3-dimensional plot? How can I do this in Python?

import numpy as np
import matplotlib.pyplot as plt
underlying = np.linspace(100,120,50)
K = 100
T = 1
r = 0
sigma = np.linspace(0.05,0.7,50)
def Vanna_(S, K, T, r, sigma):
    lista = []
    d1 = (np.log(S / K) + (r + 1/2 * sigma ** 2) * T) / (sigma * np.sqrt(T))
    d2 = d1-vol*T**(1/2)
    return (1 / np.sqrt(2 * np.pi) * S  * np.exp(-d1 ** 2 * 1/2) * np.sqrt(T))/S * (1- d1/(sigma*np.sqrt(T)))
plt.plot(Vanna_(underlying, K, T, r, sigma))
$\endgroup$

2 Answers 2

6
$\begingroup$

Something like this?

from mpl_toolkits import mplot3d
from itertools import product

S = np.linspace(100,120)
vols = np.linspace(0.05,0.7)
combs = list(product(S, vols))

values = [Vanna_(underlying, K, T, r, sigma) for underlying, sigma in combs]
x, y = np.hsplit(np.array(combs), 2)

fig = plt.figure()
ax = plt.axes(projection="3d")
ax.scatter3D(x, y, values, c=values);

enter image description here

$\endgroup$
6
$\begingroup$

Here is another solution using Plotly.

First of all let me correct a typo in your code

def Vanna_(S, K, T, r, sigma):
    lista = []
    d1 = (np.log(S / K) + (r + 1/2 * sigma ** 2) * T) / (sigma * np.sqrt(T))
    d2 = d1-sigma*T**(1/2)
    return (1 / np.sqrt(2 * np.pi) * S  * np.exp(-d1 ** 2 * 1/2) * np.sqrt(T))/S * (1- d1/(sigma*np.sqrt(T)))

Then let me use pandas to format the result

import numpy as np
import pandas

K = 100
T = 1
r = 0

underlying_1d = np.linspace(100,120,25)
sigma_1d     = np.linspace(0.05,0.3,50)

underlying, sigma = np.meshgrid(underlying_1d, sigma_1d)

Vanna_df = pandas.DataFrame(
    Vanna_(underlying, K, T, r, sigma),
    columns=underlying_1d,
    index=sigma_1d
    )
Vanna_df.index.name  = 'volatility'
Vanna_df.columns.name = 'Strike'
Vanna_df.iloc[:10,:10]

Now a contourplot

import plotly.graph_objects as go

fig = go.Figure(data =
    go.Contour(
        z=Vanna_df.values,
        x=underlying_1d,
        y=sigma_1d
    ))
fig.update_layout(title='Vanna', autosize=False, 
                  xaxis_title='volatility', yaxis_title='strike',
                  width=700, height=500)
fig.show()

contour plot

and your surface plot

import plotly.graph_objects as go

fig = go.Figure(data =
    go.Surface(
        z=Vanna_df.values,
        x=underlying_1d,
        y=sigma_1d
    ))
fig.update_traces(contours_z=dict(show=True, usecolormap=True,
                                  highlightcolor="limegreen", project_z=True))

fig.update_layout(title='Vanna', autosize=False,
                  width=700, height=500)
fig.show()

surface

(Note: it is not my habit to post code on quant.stackexchange but I am training myself to use Plotly nowadays...)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.