I have this function that won't generate a 3D surface:
black_scholes <- function(S, X, r, sigma, t, optionType, greekType, graphics) {
# Compute d1 and d2
d1 <- (log(S/X) + (r + (sigma^2)/2)*t) / (sigma*sqrt(t))
d2 <- d1 - sigma*sqrt(t)
# Compute greek value
if (optionType == "call") {
greek <- switch(greekType,
delta = pnorm(d1),
gamma = (dnorm(d1))/(S*sigma*sqrt(t)),
vega = (S*dnorm(d1)*sqrt(t))/100,
theta = (-S*sigma*dnorm(d1))/(2*sqrt(t)) - r*X*exp(-r*t)*pnorm(d2),
rho = X*t*exp(-r*t)*pnorm(d2))
} else if (optionType == "put") {
greek <- switch(greekType,
delta = pnorm(-d1),
gamma = (dnorm(d1))/(S*sigma*sqrt(t)),
vega = (S*dnorm(d1)*sqrt(t))/100,
theta = (-S*sigma*dnorm(d1))/(2*sqrt(t)) + r*X*exp(-r*t)*pnorm(-d2),
rho = -X*t*exp(-r*t)*pnorm(-d2))
}
# Import required library
library(plotly)
# Plot surface if graphics is TRUE
if (graphics) {
Sarray <- seq(from = S-round(0.20*S), to = S + round(0.20*S), by = 0.1)
Tarray <- seq(from = t*360-round(0.20*t*360), to = t*360 + round(0.20*t*360), by = 1)/360
# Allocate greek_array as a matrix
greek_array <- matrix(0, nrow = length(Sarray), ncol = length(Tarray))
for (i in (1:length(Sarray))) {
for(j in (1:length(Tarray))) {
greek_array[i,j] <- black_scholes(Sarray[i], X, r, sigma, Tarray[j]/365, optionType, greekType, graphics = FALSE)
}
}
# Create df using expand.grid
df <- expand.grid(Sarray = Sarray, Tarray = Tarray)
df$greek_array <- as.vector(greek_array)
# Use plotly to create an interactive 3D surface plot
plot_ly(df, x = Sarray, y = Tarray, z = greek_array, type = "surface", colorscale = "Viridis") %>%
layout(scene = list(xaxis = list(title = "Stock Price"),
yaxis = list(title = "Time to expiration"),
zaxis = list(title = greekType)))
}
return(greek)
}
print(black_scholes(S <- 60, X <- 65, r <- 0.08, sigma <- 0.3, t <- 0.25, optionType = "call", greekType = "delta", graphics = FALSE))
out <- black_scholes(S <- 60, X <- 65, r <- 0.08, sigma <- 0.3, t <- 0.25, optionType = "call", greekType = "delta", graphics = TRUE)
I'm trying to generate a surface only when graphics=TRUE
, but despite the code doesn't give me any error, the surface won't appear. Can anyone help me understand what I'm doing wrong?
You need to save your plot and return it as the output of your UDF.
black_scholes <- function(S, X, r, sigma, t, optionType, greekType, graphics) {
# Compute d1 and d2
d1 <- (log(S/X) + (r + (sigma^2)/2)*t) / (sigma*sqrt(t))
d2 <- d1 - sigma*sqrt(t)
# Compute greek value
if (optionType == "call") {
greek <- switch(greekType,
delta = pnorm(d1),
gamma = (dnorm(d1))/(S*sigma*sqrt(t)),
vega = (S*dnorm(d1)*sqrt(t))/100,
theta = (-S*sigma*dnorm(d1))/(2*sqrt(t)) - r*X*exp(-r*t)*pnorm(d2),
rho = X*t*exp(-r*t)*pnorm(d2))
} else if (optionType == "put") {
greek <- switch(greekType,
delta = pnorm(-d1),
gamma = (dnorm(d1))/(S*sigma*sqrt(t)),
vega = (S*dnorm(d1)*sqrt(t))/100,
theta = (-S*sigma*dnorm(d1))/(2*sqrt(t)) + r*X*exp(-r*t)*pnorm(-d2),
rho = -X*t*exp(-r*t)*pnorm(-d2))
}
# Import required library
library(plotly)
# Plot surface if graphics is TRUE
if (graphics) {
Sarray <- seq(from = S-round(0.20*S), to = S + round(0.20*S), by = 0.1)
Tarray <- seq(from = t*360-round(0.20*t*360), to = t*360 + round(0.20*t*360), by = 1)/360
# Allocate greek_array as a matrix
greek_array <- matrix(0, nrow = length(Sarray), ncol = length(Tarray))
for (i in (1:length(Sarray))) {
for(j in (1:length(Tarray))) {
greek_array[i,j] <- black_scholes(Sarray[i], X, r, sigma, Tarray[j]/365, optionType, greekType, graphics = FALSE)
}
}
# Create df using expand.grid
df <- expand.grid(Sarray = Sarray, Tarray = Tarray)
df$greek_array <- as.vector(greek_array)
# Use plotly to create an interactive 3D surface plot
plot_ly(df, x = Sarray, y = Tarray, z = greek_array, type = "surface", colorscale = "Viridis") %>%
layout(scene = list(xaxis = list(title = "Stock Price"),
yaxis = list(title = "Time to expiration"),
zaxis = list(title = greekType))) -> plt
}
ifelse(graphics, return(plt), return(greek))
}
black_scholes(S <- 60, X <- 65, r <- 0.08, sigma <- 0.3, t <- 0.25,
optionType = "call", greekType = "delta", graphics = FALSE)
#> [1] 0.3724828
black_scholes(S <- 60, X <- 65, r <- 0.08, sigma <- 0.3, t <- 0.25,
optionType = "call", greekType = "delta", graphics = TRUE)
Created on 2022-12-22 by the reprex package (v2.0.1)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.