3
$\begingroup$

I am trying to run a delta-gamma hedge for a Black-Scholes model in Python.The Euler disceretizatioin of the paths is the simplest possible. I wrote the code below but the PnL looks undesirable and wrong.

I have 2 Options: The one that I am going short and an additional option with a longer maturity (1.5) for the hedge.

#install pandas
import math
import numpy as np
import scipy as sp
import numpy.random as npr  
import scipy.stats as scs
import matplotlib.pyplot as plt
import numpy.random as npr
import seaborn
seaborn.set_style("ticks")

%matplotlib inline

np.set_printoptions(suppress=True)

# sets the plotting style

#--------------------------

#functions 
def callprice(S,K,T,sigma,r):
    d1=(sp.log(S/K) + (r + 0.5 * sigma**2)*T) / (sigma * sp.sqrt(T))
    d2=(sp.log(S/K) + (r - 0.5 * sigma**2)*T) / (sigma * sp.sqrt(T))
    return S*scs.norm.cdf(d1) - math.exp(-r *T) * K * scs.norm.cdf(d2)

def deltafunc(S, K, T, sigma, r):
    d1=(sp.log(S/K) + (r + 0.5 * sigma**2)*T) / (sigma * sp.sqrt(T))
    return scs.norm.cdf(d1) 

def gamma(S, K, T, sigma, r):
    d1=(sp.log(S/K) + (r + 0.5 * sigma**2)*T) / (sigma * sp.sqrt(T))
    return scs.norm.pdf(d1) / (S * sigma * sp.sqrt(T))


S0 = 100
k  = 100 
K2 = 100 
T1 = 1   # time to maturity
T2 = 1.1 # time to maturity
sigma = 0.2 # vola
n = 10000 # number of simulations
m = 252  # number of realisations of stock
r = 0.05 # interest rate
dt = T1/m

s = np.zeros([n,m+1])
w = npr.standard_normal([n,m])
ttm1 = T1- np.arange(1, m+1, 1)/m
ttm2 = T2- np.arange(1, m+1, 1)/m
s[:,0] = S0

#simple Euler discretization of GBM

for i in range(1,m+1):
    s[:,i] = s[:,i-1]*((1 + r*dt) + sigma / np.sqrt(252) * w[:,i-1])

#Computation of greeks

bscall  = np.zeros([n,m+1])
deltabs = np.zeros([n,m+1])
gamma1  = np.zeros([n,m+1])
gamma2  = np.zeros([n,m+1])
delta2 = np.zeros([n,m+1])
ttm     = np.arange(1, m+1, 1)/m
mu = r


bscall[:,0]     = callprice(S0, k, T1, sigma, mu)
deltabs[:,0]    = deltafunc(S0, k, T1, sigma, mu)

#delta gamma
gamma1[:,0] = gamma(s[:,0], k, T1, sigma, mu)
gamma2[:,0] = gamma(s[:,0], k, T2, sigma, mu)
delta2[:,0] = deltafunc(s[:,0], k, T2, sigma, mu)

for i in range(1,m+1):
    bscall[:,i]  = callprice(s[:,i], k, T1-ttm[i-1], sigma, mu)
    deltabs[:,i] = deltafunc(s[:,i], k, T1-ttm[i-1], sigma, mu)
    gamma1[:,i]  = gamma(s[:,i], k, T1-ttm[i-1], sigma, mu)
    gamma2[:,i] = gamma(s[:,i], k, T2-ttm[i-1], sigma, mu)
    delta2[:,i] = deltafunc(s[:,i], k, T2-ttm[i-1], sigma, mu)

#coef between gammas 
h2 = gamma1/gamma2

#delta rebalance
strategy = deltabs - delta2*h2

#initialization
st               = s[:,0]
amount           = callprice(s[:,0], k, T1, sigma, mu)
delta            = deltabs[:,0] - delta2[:,0]*gamma1[:,0]/gamma2[:,0]
gammacoef        = gamma1[:,0]/gamma2[:,0]
Pnl              = amount - delta*st - gamma1[:,0]/gamma2[:,0]*callprice(s[:,0], k, T2, sigma, mu)
interest         = np.exp(r * dt)

for i in range(1, m):
    Pnl          = interest * Pnl
    newdelta     = deltabs[:,i] - delta2[:,i]*gamma1[:,i]/gamma2[:,i]
    newgammacoef = gamma1[:,i]/gamma2[:,i]
    Pnl          = Pnl - ((newdelta-delta)*s[:,i] + (newgammacoef-gammacoef)*callprice(s[:,i], k, T2-ttm[i-1], sigma, r))
    delta        = newdelta
    gammacoef    = newgammacoef

Pnl              = Pnl * interest

PnL_final        = Pnl + strategy[:,-2] * s[:,-1] + gamma1[:,-2]/gamma2[:,-2]*callprice(s[:,-1], k, T2-ttm[-1], sigma, r)/interest - np.max(s[:,-1]-k,0) 
PnL_final2       = [x/callprice(s[0,0], k, T1, sigma, mu) for x in PnL_final]


print(PnL_final)

plt.hist(PnL_final)
$\endgroup$
  • $\begingroup$ your np.max(s[:,-1]-k,0) might be incorrect, try something like np.maximum(s[:,-1] - k, np.zeros(n)) $\endgroup$ – starovoitovs Aug 25 '19 at 12:46
  • $\begingroup$ Your euler discretization is wrong. Where did you take it from? $\endgroup$ – will Feb 7 at 22:59
0
$\begingroup$

I think your problem is here: $\textbf{T1-ttm[i-1]}$ (or T2). Rather it should be just $\textbf{ttm[i-1]}$.

In your code time to maturity increases with time, it obviously should be the other way around.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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