As is well known in finance, delta hedging is a means of hold or short the underlying in order to hedge the derivative you already shorted or held. Thus our total portfolio will be delta neutral, which mean no profit nor loss with small changes of underlying price.Further information can be see here delta hedging
The catch of delta hedging is that people can not hedging the position continuously according to the theory and in real life there are always transaction costs.So the final profit or loss will be close to zero.However, another risk is that the underlying price is near the money during the maturity, in such case,it will be hard to hedge since it changes so much in the end,the final loss would be large. Other methods like Gamma hedge are recommended.
Below is a monte carlo simulation of delta hedging. I simulation 5000 differents paths, each path have been divided into 1000 discrete point to mimic the continuous hedging.There will be error of course, but with in a reasonable range.(There are several for loops in my algo, makes it a little slow when creating 5000*1000 data points, further improvement should be considered , like apply(),sapply())
1.the function to return one geometric brownian motion path \(S_t=S_0e^{\mu dt+\sigma dB_t}\)
GBM.process<-function(spot,drift,sigma,num,tau){
dt<-tau/num;
bm<-rnorm(num,mean = 0,sd=1);
fac<-(drift-sigma^2/2)*dt;
path<-spot;
for(i in 2:num){
path<-c(path,path[i-1]*exp(fac+sigma*sqrt(dt)*bm[i-1]))
}
return(path)
}
test.path<-GBM.process(spot = 100,drift = 0.03,sigma = 0.3,num = 1000,tau = 1)
plot(test.path,type = "l")
option.price<-function(spot,strike,vol,rf,tau,CorP){
d1<-(log(spot/strike)+(rf+vol^2/2)*tau)/(vol*sqrt(tau));
d2<-d1-vol*sqrt(tau);
Nd1<-pnorm(d1,mean=0,sd=1);
Nd2<-pnorm(d2,mean=0,sd=1);
discount<-exp(-rf*tau);
fee<-spot*Nd1-strike*Nd2*discount;
if(CorP=="c")
return(fee)
else if(CorP=="p")
return(fee-spot+strike*discount)
else
return("CorP must be c or p,which is European call or put.")
}
option.price(spot = 100,strike = 100,vol = 0.3,rf = 0.05,tau = 1,CorP = "c")
## [1] 14.23125
3.delta from B-S formula
\(\delta=N(d_1)\)
delta<-function(spot,strike,vol,rf,tau,CorP){
d1<-(log(spot/strike)+(rf+vol^2/2)*tau)/(vol*sqrt(tau));
Nd1<-pnorm(d1,mean=0,sd=1);
greek<-Nd1;
if(CorP=="c")
return(greek)
else if(CorP=="p")
return(greek-1)
else
return("CorP must be c or p,which is European call or put.")
}
delta(spot = 100,strike = 100,vol = 0.3,rf = 0.05,tau = 1,CorP = "c")
## [1] 0.6242517
4.Simulation
#replicate(n,object) creates n columns of the object
premium<-option.price(spot = 100,strike = 100,vol = 0.3,rf = 0.05,tau = 1,CorP = "c")
simu.path<-replicate(5000, GBM.process(spot = 100,drift = 0.03,sigma = 0.3,num = 1000,tau = 1))#5000 price path, 1000 points each
simu.delta<-matrix(0,nrow = nrow(simu.path),ncol = ncol(simu.path))#every delta on every point
period <- nrow(simu.path)
for(i in 1:ncol(simu.path)){
for(k in 1:nrow(simu.path)){
simu.delta[k,i]<-delta(spot = simu.path[k,i],strike = 100,vol = 0.3,rf = 0.05,tau = 1-(k-1)/period,CorP = "c")
}
}
dif.hedge<-apply(simu.delta,2,diff)#difference between two hedging positions, additional purchase or sell
P.L<-matrix(0,nrow = nrow(simu.path),ncol = ncol(simu.path))
for(i in 1:ncol(P.L)){
P.L[1,i]<-simu.delta[1,i]*simu.path[1,i]-premium
}
for(i in 1:ncol(P.L)){
for (k in 2:nrow(P.L)) {
P.L[k,i]<-P.L[k-1,i]*exp(0.05/period)+dif.hedge[k-1,i]*simu.path[k,i]
}
}
if final stock price \(S_T>K\), final balance position will receive \(K\) to compensate the position, if otherwise(out of the money) the final position would be zero.
final.position<-P.L[1000,]
final.price<-simu.path[1000,]
final.pl <- rep(0,5000)
for(i in 1:5000){
if(final.price[i]>100)
final.pl[i] <- 100-final.position[i]
else
final.pl[i] <- final.position[i]
}
consider 2 as the range of around the money
around.money.index<-which(final.price>98&final.price<102)
error<-rep("ok",5000)
error[around.money.index]<-"around money"
path.index<-seq(1:5000)
result<-as.data.frame(cbind(path.index,final.pl,as.factor(error)))#ggplot can only deal with factor,not string
library(ggplot2)
ggplot(data = result)+geom_point(mapping = aes(x = path.index,y = final.pl,color=error),alpha=0.6)
examples of around the money,in the money and out of the money
par(mfrow=c(2,1))
par(cex=0.6)
plot(y = simu.path[,4],x = 1:1000,col="blue2",xlab="step",ylab="P & L",type="b",main="around the money price")
plot(y = P.L[,4],x = 1:1000,col="red3",xlab="step",ylab="P & L",type="b",main="around the money P & L")
par(mfrow=c(2,1))
par(cex=0.6)
plot(y = simu.path[,9],x = 1:1000,col="blue2",xlab="step",ylab="P & L",type="b",main="in the money price")
plot(y = P.L[,9],x = 1:1000,col="red3",xlab="step",ylab="P & L",type="b",main="in the money P & L")
par(mfrow=c(2,1))
par(cex=0.6)
plot(y = simu.path[,22],x = 1:1000,col="blue2",xlab="step",ylab="P & L",type="b",main="out of the money price")
plot(y = P.L[,22],x = 1:1000,col="red3",xlab="step",ylab="P & L",type="b",main="out of the money P & L")