The below code creates functions and plots for Black-Scholes and Monte-Carlo Simulation for vanilla call options, european call options, and down-and-out put options.
It also examines exotic options, hedging portfolios for large price movements, associated transactions costs, and builds a Heston model.
Note : The code uses predetermine inputs for all models.
stock_price = 100
strike_price = 100
r = 0.05
dividend = 0
sigma = 0.2
Time = 1/4
N = 96*90
num_sim = 5
h = Time/N
u = exp((r-dividend)*h + sigma * (h ^ 0.5))
d = exp((r - dividend)*h - sigma * (h ^ 0.5))
prob = (exp((r - dividend) * h) - d) / (u - d)
#lnSt ~ N(lnSo + (r-div - sigma^2 / 2)T, sigma^2 T)
mu = (r - dividend - ((sigma) ** 2 / 2)) * h
std = sigma * (h ** 0.5)
Time_0 = rep(log(stock_price),num_sim)
#Parallel computing function
sim_one_node = function(last_node){
one_node = rnorm(num_sim,mu,std)
new_node = last_node + one_node
return(new_node)
}
ms = as.data.frame(NA)
# Monte Carlo Simulation simulates all of the 5 paths and then take the exponential
last = Time_0
ms = as.data.frame(matrix(numeric(0), ncol = 1, nrow = num_sim))
ms[1] = Time_0
for (i in 1:N) {
# run 96*90 times
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms = exp(ms) #turn back from lnSt to St
BlackScholes <- function(S, K, r, T, sig, div, type){
d1 = (log(S/K) + (r -div + sig^2/2)*T) / (sig*sqrt(T))
d2 = d1 - sig*sqrt(T)
if(type=="C"){
value = S*exp(-div*T)*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
return(value)}
if(type=="P"){
value = (K*exp(-r*T)*pnorm(-d2) - S*exp(-div*T)*pnorm(-d1))
return(value)}
}
BlackScholes(S = 100, K = 100, r = 0.05, T = 1/4, sig = 0.2, div = 0, type = "C")
## [1] 4.614997
So the Black-Scholes call option price is 4.614997.
S=100
K=100
tau=0.25
r=0.05
sigma=0.2
# Compute the Monte Carlo European option price
# Assuming the stock follows a geometric BM
set.seed(0)
N <- 96*90 #90 days and 96 5 min subintervals per day
dt <- tau/N #length of each time sub interval
time <- seq(from=0, to=tau, by=dt) #time moments in which we simulate the process
nSim <- 100 #number of simulations (paths)
#Monte Carlo with analytic formula
Z <- rnorm(nSim, mean=0, sd=1)
WT <- sqrt(tau) * Z
ST = S*exp((r - 0.5*sigma^2)*tau + sigma*WT)
simulated_call_payoffs <- exp(-r*tau)*pmax(ST-K,0)
Call_price_MC_anal_1 <- mean(simulated_call_payoffs)
lower_bound_1 <- Call_price_MC_anal_1 - 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
upper_bound_1 <- Call_price_MC_anal_1 + 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
#------------------------------------------
set.seed(0)
nSim <- 1000 #number of simulations (paths)
#Monte Carlo with analytic formula
Z <- rnorm(nSim, mean=0, sd=1)
WT <- sqrt(tau) * Z
ST = S*exp((r - 0.5*sigma^2)*tau + sigma*WT)
simulated_call_payoffs <- exp(-r*tau)*pmax(ST-K,0)
Call_price_MC_anal_2 <- mean(simulated_call_payoffs)
lower_bound_2 <- Call_price_MC_anal_2 - 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
upper_bound_2 <- Call_price_MC_anal_2 + 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
#------------------------------------------
set.seed(0)
nSim <- 100 #number of simulations (paths)
#Monte Carlo with analytic formula
Z <- rnorm(nSim, mean=0, sd=1)
WT <- sqrt(tau) * Z
ST = S*exp((r - 0.5*sigma^2)*tau + sigma*WT)
simulated_call_payoffs <- exp(-r*tau)*pmax(ST-K,0)
Call_price_MC_anal_3 <- mean(simulated_call_payoffs)
lower_bound_3 <- Call_price_MC_anal_3 - 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
upper_bound_3 <- Call_price_MC_anal_3 + 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
#------------------------------------------
set.seed(0)
nSim <- 1000 #number of simulations (paths)
#Monte Carlo with analytic formula
Z <- rnorm(nSim, mean=0, sd=1)
WT <- sqrt(tau) * Z
ST = S*exp((r - 0.5*sigma^2)*tau + sigma*WT)
simulated_call_payoffs <- exp(-r*tau)*pmax(ST-K,0)
Call_price_MC_anal_4 <- mean(simulated_call_payoffs)
lower_bound_4 <- Call_price_MC_anal_4 - 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
upper_bound_4 <- Call_price_MC_anal_4 + 1.96*sd(simulated_call_payoffs)/sqrt(nSim)
A = matrix(NA, nrow = 4, ncol = 3)
colnames(A) = c("Option Price", "CI Lower Bound", "CI Upper Bound")
rownames(A) = c("100 times", "1,000 times", "1,000,000 times", "100,000,000 times")
A[1, 1] = Call_price_MC_anal_1
A[1, 2] = lower_bound_1
A[1, 3] = upper_bound_1
A[2, 1] = Call_price_MC_anal_2
A[2, 2] = lower_bound_2
A[2, 3] = upper_bound_2
A[3, 1] = Call_price_MC_anal_3
A[3, 2] = lower_bound_3
A[3, 3] = upper_bound_3
A[4, 1] = Call_price_MC_anal_4
A[4, 2] = lower_bound_4
A[4, 3] = upper_bound_4
print(xtable(A, digits = 3))
% latex table generated in R 4.0.2 by xtable 1.8-4 package % Wed Mar 31 18:08:57 2021
The length of the confidence interval decreases as the number of simulated paths increase . Also, the Black-Scholes call option price is 4.614997 which is very similar to the Monte-Carlo price of 4.614193.
Â
BlackScholes <- function(S, K, r, T, sig, div, type){
d1 = (log(S/K) + (r -div + sig^2/2)*T) / (sig*sqrt(T))
d2 = d1 - sig*sqrt(T)
if(type=="C"){
value = S*exp(-div*T)*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
return(value)}
if(type=="P"){
value = (K*exp(-r*T)*pnorm(-d2) - S*exp(-div*T)*pnorm(-d1))
return(value)}
}
BlackScholes(S = 100, K = 100, r = 0.05, T = 1/4, sig = 0.2, div = 0, type = "C")
## [1] 4.614997
set_up = function(r,dividend,sigma,Time,N){
h = Time/N
mu = (r - dividend - ((sigma) ** 2 / 2)) * h
std = sigma * (h ** 0.5)
return(c(h,mu,std))
}
sim_one_node = function(num_sim,mu,std,last_node){
one_node = rnorm(num_sim,mu,std)
new_node = last_node + one_node
return(new_node)
}
sim_matrix_2a = function(setup,S,K,N,num_sim,r,Time,barrier){
h = setup[1]
mu = setup[2]
std = setup[3]
Time_0 = rep(log(S),num_sim)
last = Time_0
prices = as.data.frame(matrix(numeric(0),ncol=1,nrow = num_sim))
prices[,1] = Time_0
for (i in 1:N){
out = sim_one_node(num_sim,mu,std,last)
for(j in 1:num_sim){
if(out[j] < log(barrier) | is.na(out[j])){ #If any price < barrier, this will out, and following simulation will all out
out[j] = NA
}
}
prices[,i+1] = out
last = out
}
prices = exp(prices)
payoff_T = pmax((K - prices[,N+1]), 0)
payoff_0 = payoff_T * exp(-r * Time)
payoff_0[is.na(payoff_0)] = 0 #Change NA to 0
avg_payoff = mean(payoff_0)
NA_terms = sum(is.na(prices[,N+1]))
answer = list("payoff" = avg_payoff, "out" = NA_terms)
return(answer)
}
set_b = set_up(0.05,0,0.2,0.25,864) #setup
twob = sim_matrix_2a(set_b,100,95,864,100,0.05,0.25,75)#Simulate 1000 times
BS_b1 = BlackScholes(100,95,0.05,0.25,0.2,0, "C")[2] #Price of Black Scholes
#Do 20 times to get confidence interval
payoffandNA = as.data.frame(matrix(numeric(0),ncol=2,nrow = 20))
for (i in 1:20){
print(i)
temp = sim_matrix_2a(set_b,100,95,864,100,0.05,0.25,75)
payoffandNA[i,1] = as.numeric(temp[1])
payoffandNA[i,2] = as.numeric(temp[2])
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 15
## [1] 16
## [1] 17
## [1] 18
## [1] 19
## [1] 20
colnames(payoffandNA) = c("Price","OutPath")
total_mean = mean(payoffandNA[,1]) #Mean of 20 times price
total_sd = sd(payoffandNA[,1]) #Sd of 20 times price
interval_down = total_mean - 2 * total_sd #Intervals
interval_up = total_mean + 2 * total_sd
avg_NA = mean(payoffandNA[,2]) #Mean of 20 times out path
The Black Scholes price of put is 1.5342. The average payoff of 20 simulations of Down-And-Out put price is 1.4941. The confidence interval is 1.2590 - 1.7292. The average out path of Down-And-Out put is 3.15 . The Down-And-Out put is cheaper than normal put because the payoff that is larger than 95 - 75 is excluded.
volatility = c(0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4)
out_path = c()
price = c()
for(i in volatility){
set = set_up(0.05,0,i,0.25,8640)
two = sim_matrix_2a(set,100,95,8640,1000,0.05,0.25,75)
out_path = append(out_path,as.numeric(two[2]))
price = append(price , as.numeric(two[1]))
}
As shown in the graph, when the volatility becomes larger, the out paths number increase. This is because when volatility goes up, the probability of the stock price touch the barrier also gets higher.
#3a)
#2 dim BM
#2 risky and 1 Rf
r=.05
beta = r
alpha = .6
sigma11 = .1
sigma12 = .2
sigma21 = .3
S1 = c(10)
S2 = c(10)
delta=.1
dt=1/250 #this is the step wrt time
T=1
rate_paths = matrix(NA, nrow=251, ncol=1000) #each col is a simulated rate path, each row is the evolution of that rate path from t=0 to T=1
rate_paths = as.data.frame(rate_paths)
rate_paths[1,] = r
for(j in 1:1000){ #for each simulated path
for(i in 2:251){
rate_paths[i,j] = rate_paths[i-1,j] + alpha*(beta - rate_paths[i-1,j])*dt + delta*sqrt(rate_paths[i-1,j])*sqrt(dt)*rnorm(1)
}
}
r_T = c(as.numeric(rate_paths[251,]))
hist(r_T, breaks=20, main = "Histogram of r_T given r_0 = 0.05")
#3b
r=.05
beta = r
alpha = .6
sigma11 = .1
sigma12 = .2
sigma21 = .3
S1 = c(10)
S2 = c(10)
delta=.1
dt=(1/52) #this is the step wrt time
T=100
rate_paths2 = matrix(NA, nrow=(52*100 +1), ncol=1)
rate_paths2 = as.data.frame(rate_paths2)
rate_paths2[1,1] = r
for(i in 2:(52*100 +1)){
rate_paths2[i,1] = rate_paths2[i-1,1] + alpha*(beta - rate_paths2[i-1,1])*dt + delta*sqrt(rate_paths2[i-1,1])*sqrt(dt)*rnorm(1)
}
plot(x=seq(0,100,1/52), y=rate_paths2[,1], type='l', main = "Trajectory of interest rate from t=0 to T=100", xlab = "Time", ylab = "Interest rate")
#3c
K=10
T=.5
#first find the i-rate paths: r_t
r=.05
beta = r
alpha = .6
sigma11 = .1
sigma12 = .2
sigma21 = .3
S1 = c(10)
S2 = c(10)
delta=.1
dt=(1/250) #this is the step wrt time
rate_paths3 = matrix(NA, nrow=(250*.5 +1), ncol=1000)
rate_paths3 = as.data.frame(rate_paths3)
rate_paths3[1,] = r
for(j in 1:1000){ #for each simulated path
for(i in 2:(250*.5 +1)){
rate_paths3[i,j] = rate_paths3[i-1,j] + alpha*(beta - rate_paths3[i-1,j])*dt + delta*sqrt(rate_paths3[i-1,j])*sqrt(dt)*rnorm(1)
}
}
#now find the evolution of the asset
asset1 = matrix(NA, nrow=(250*.5 +1), ncol=1000)
asset1 = as.data.frame(asset1)
asset1[1,] = 10 #S1 like we hvae in line 313
for(j in 1:1000){ #for each simulated path
for(i in 2:(250*.5 +1)){
asset1[i,j] = asset1[i-1,j] + rate_paths3[i-1,j]*asset1[i-1,j]*dt + sigma11*sqrt(asset1[i-1,j])*sqrt(dt)*rnorm(1) + sigma12*(asset1[i-1,j])*sqrt(dt)*rnorm(1)
}
}
#now we price the asset call option
K=10
T=.5
r_T = c(as.numeric(rate_paths3[126,])) #this row represents 10,000 observations of r_T at T=.5
ST = c(as.numeric(asset1[126,])) #this row represents 10,000 observations of S_T at T=.5
simulated_call_payoffs = c()
for(i in 1:1000){
simulated_call_payoffs[i] <- exp(-r_T[i]*T)*max(ST[i]-K,0)
}
Call_price_asset_1 <- mean(simulated_call_payoffs)
#now find the evolution of the asset
asset2 = matrix(NA, nrow=(250*.5 +1), ncol=1000)
asset2 = as.data.frame(asset2)
asset2[1,] = 10 #S2 like we hvae in line 314
for(j in 1:1000){ #for each simulated path
for(i in 2:(250*.5 +1)){
asset2[i,j] = asset2[i-1,j] + rate_paths3[i-1,j]*asset2[i-1,j]*dt + sigma21*(asset1[i-1,j]-asset2[i-1,j])*sqrt(dt)*rnorm(1)
}
}
#to find max S1 and S2 along each of the 10,000 simulated paths
max1 = matrix(NA, nrow=1, ncol=1000)
max2 = matrix(NA, nrow=1, ncol=1000)
max1 = as.data.frame(max1)
max2 = as.data.frame(max2)
for(i in 1:1000){
max1[1,i] = max(asset1[,i])
max2[1,i] = max(asset2[,i])
}
overall_max = matrix(NA, nrow=1, ncol=1000)
overall_max = as.data.frame(overall_max)
for(i in 1:1000){
overall_max[1,i] = max(c(max1[1,i],max2[1,i]))
}
#now price the exotic option:
K=10
T=.5
simulated_call_payoffs = c() #these are the payoffs for each simulation
for(i in 1:1000){
simulated_call_payoffs[i] <- exp(-r_T[i]*T)*max(overall_max[1,i]-K,0)
}
Call_price_exotic_option <- mean(simulated_call_payoffs)
A European Call option on asset 1 costs $0.7014
The exotic option costs $1.281464
stock_price = 100
strike_price = 100
r = 0.2 #This is mu instead of r
dividend = 0
sigma = 0.3
Time = 30/365
N = 96*30
num_sim = 1
h = Time/N
u = exp((r-dividend)*h + sigma * (h ^ 0.5))
d = exp((r - dividend)*h - sigma * (h ^ 0.5))
prob = (exp((r - dividend) * h) - d) / (u - d)
#lnSt ~ N(lnSo + (r-div - sigma^2 / 2)T, sigma^2 T)
mu = (r - dividend - ((sigma) ** 2 / 2)) * h
std = sigma * (h ** 0.5)
Time_0 = rep(log(stock_price),num_sim)
#Parallel computing function
sim_one_node = function(last_node){
one_node = rnorm(num_sim,mu,std)
new_node = last_node + one_node
return(new_node)
}
ms = as.data.frame(NA)
# Monte Carlo Simulation simulates all of the path and then take the exponential
last = Time_0
ms = as.data.frame(matrix(numeric(0), ncol = 1, nrow = num_sim))
ms[1] = Time_0
for (i in 1:N) {
# run 96*90 times
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms = exp(ms) #turn back from lnSt to St
delta <- function(S, K, r, T, sig, div, type){
d1 = (log(S/K) + (r -div + sig^2/2)*T) / (sig*sqrt(T))
return (exp(-div*T)*pnorm(d1))
}
#hedge ratio
Delta = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
Delta[j] = delta(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
#rf assets to start with
B = c(BS[1] - Delta[1] * S[1])
#replicating portfolio
V = c(BS[1])
set.seed(2)
stock_price = 100
strike_price = 100
r = 0.2 #This is mu instead of r
dividend = 0
sigma = 0.3
Time = 30/365
N = 96*30
num_sim = 1
h = Time/N
u = exp((r-dividend)*h + sigma * (h ^ 0.5))
d = exp((r - dividend)*h - sigma * (h ^ 0.5))
prob = (exp((r - dividend) * h) - d) / (u - d)
#lnSt ~ N(lnSo + (r-div - sigma^2 / 2)T, sigma^2 T)
mu = (r - dividend - ((sigma) ** 2 / 2)) * h
std = sigma * (h ** 0.5)
Time_0 = rep(log(stock_price),num_sim)
#Parallel computing function
sim_one_node = function(last_node){
one_node = rnorm(num_sim,mu,std)
new_node = last_node + one_node
return(new_node)
}
ms = as.data.frame(NA)
# Monte Carlo Simulation simulates all of the path and then take the exponential
last = Time_0
ms = as.data.frame(matrix(numeric(0), ncol = 1, nrow = num_sim))
ms[1] = Time_0
for (i in 1:N/2) {
# run first half
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms[N/2 + 2] = last + log(0.9) #Because ln(S * 0.9) = lnS + ln0.9
last = ms[N/2 + 2]
for (i in (N/2 + 2):N) {
# run second half
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms = exp(ms) #turn back from lnSt to St
S = ms_plot$value
BS = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
BS[j] = BlackScholes(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
delta <- function(S, K, r, T, sig, div, type){
d1 = (log(S/K) + (r -div + sig^2/2)*T) / (sig*sqrt(T))
return (exp(-div*T)*pnorm(d1))
}
#hedge ratio
Delta = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
Delta[j] = delta(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
#rf assets to start with
B = c(BS[1] - Delta[1] * S[1])
#replicating portfolio
V = c(BS[1])
for (i in 2:length(S)){
V[i] = Delta[i-1] * S[i] + B[i-1] * exp(0.05*(30/365)/(30*96))
B[i] = V[i] - Delta[i] * S[i]
}
Of all the option prices’, replicating portfolio value and hedge ratio show a downward jump as well. Also, the replicating portfolio value shows larger differences from the Black-Scholes option price after the jump.
set.seed(4)
ms = as.data.frame(NA)
# Monte Carlo Simulation simulates all of the path and then take the exponential
last = Time_0
ms = as.data.frame(matrix(numeric(0), ncol = 1, nrow = num_sim))
ms[1] = Time_0
for (i in 1:N/2) {
# run first half
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms[N/2 + 2] = last + log(1.1) #Because ln(S * 1.1) = lnS + ln1.1
last = ms[N/2 + 2]
for (i in (N/2 + 2):N) {
# run second half
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms = exp(ms) #turn back from lnSt to St
S = ms_plot$value
BS = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
BS[j] = BlackScholes(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
delta <- function(S, K, r, T, sig, div, type){
d1 = (log(S/K) + (r -div + sig^2/2)*T) / (sig*sqrt(T))
return (exp(-div*T)*pnorm(d1))
}
#hedge ratio
Delta = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
Delta[j] = delta(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
#rf assets to start with
B = c(BS[1] - Delta[1] * S[1])
#replicating portfolio
V = c(BS[1])
for (i in 2:length(S)){
V[i] = Delta[i-1] * S[i] + B[i-1] * exp(0.05*(30/365)/(30*96))
B[i] = V[i] - Delta[i] * S[i]
}
We observe that all of option price, replicating portfolio value and hedge ratio show an upward jump as well. Also, the replicating portfolio value shows larger differences from the Black-Scholes option price after the jump.
ms = as.data.frame(NA)
# Monte Carlo Simulation simulates all of the path and then take the exponential
last = Time_0
ms = as.data.frame(matrix(numeric(0), ncol = 1, nrow = num_sim))
ms[1] = Time_0
for (i in 1:N) {
# run 96*90 times
out = sim_one_node(last)
ms[i + 1] = out
last = out
}
ms = exp(ms) #turn back from lnSt to St
S = ms_plot$value
BS = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
BS[j] = BlackScholes(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
delta <- function(S, K, r, T, sig, div, type){
d1 = (log(S/K) + (r -div + sig^2/2)*T) / (sig*sqrt(T))
return (exp(-div*T)*pnorm(d1))
}
#hedge ratio
Delta = c()
j = 1
for (T in seq((60/365), (30/365), -(30/365)/(30*96))){
Delta[j] = delta(S = S[j], K = 100, r = 0.05, T = T, sig = 0.3, div = 0, type = "C")
j = j + 1
}
#rf assets to start with
B = c(BS[1] - Delta[1] * S[1])
#replicating portfolio
V = c(BS[1])
for (i in 2:length(S)){
V[i] = Delta[i-1] * S[i] + B[i-1] * exp(0.05*(30/365)/(30*96))
B[i] = (V[i] - abs(Delta[i] - Delta[i-1]) * S[i] * 0.002) - Delta[i] * S[i]
}
It can be observed that if transaction costs are imposed, the value of replicating portfolio will vary greatly from the Black-Scholes option price.
BlackScholes(S = 100, K = 100, r = 0.04, T = 0.5, sig = sqrt(0.02), div = 0, type = "C")
## [1] 5.016981
#X is strike, q is div, v0 is vt, vT is theta, k is keppa
callHestoncf(S = 100, X = 100, tau = 0.5, r = 0.04, q = 0, v0 = 0.01, vT = 0.02, rho = -0.5, k = 6, sigma = 0.3, implVol = F)
## [1] 4.683304
So the Black-Scholes price of the option is \(5.016981\), and the Heston price of the option is \(4.683304\)
BS = c()
Heston = c()
j = 1
for (S in seq(70, 130, 0.1)){
BS[j] = BlackScholes(S = S, K = 100, r = 0.04, T = 0.5, sig = sqrt(0.02), div = 0, type = "C")
Heston[j] = callHestoncf(S = S, X = 100, tau = 0.5, r = 0.04, q = 0, v0 = 0.01, vT = 0.02, rho = -0.5, k = 6, sigma = 0.3, implVol = F)
j = j+1
}
diff = Heston - BS
plot(x = seq(70, 130, 0.1), y = diff, type = "l", col = "blue", main = "Difference in Heston and B-S prices", xlab = "S", ylab = "H - BS")
ImpVol = c()
j = 1
for (S in seq(70, 130, 0.1)) {
ImpVol[j] = callHestoncf(S = S, X = 100, tau = 0.5, r = 0.04, q = 0, v0 = 0.01, vT = 0.02, rho = -0.5, k = 6, sigma = 0.3, implVol = T)[[2]]
j = j + 1
}
ImpVol = c()
j = 1
for (S in seq(70, 130, 0.1)) {
ImpVol[j] = callHestoncf(S = S, X = 100, tau = 0.5, r = 0.04, q = 0, v0 = 0.01, vT = 0.02, rho = 0.5, k = 6, sigma = 0.3, implVol = T)[[2]]
j = j + 1
}
As the correlation between two Brownian motions changes to 0.5, the implied volatility also turns to decreasing with respect to the underlying price.