Clear Working Space

rm(list = ls())

Option Pricing Formula

# Black-Scholes Option Pricing Formula

black_scholes_call <- function(S, K, r, T, sigma, q) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  d2 <- d1 - sigma * sqrt(T)
  
  call_price <- S * exp(-q * T) * pnorm(d1) - K * exp(-r * T) * pnorm(d2)
  
  return(call_price)
}

black_scholes_put <- function(S, K, r, T, sigma, q) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  d2 <- d1 - sigma * sqrt(T)
  
  put_price <- K * exp(-r * T) * pnorm(-d2) - S * exp(-q * T) * pnorm(-d1)
  
  return(put_price)
}

# Example usage
S <- 100   # Current stock price
K <- 105   # Strike price
r <- 0.05  # Risk-free interest rate
T <- 1     # Time to expiration (in years)
sigma <- 0.2  # Volatility
q <- 0.02  # Dividend yield

call_option <- black_scholes_call(S, K, r, T, sigma, q)
put_option <- black_scholes_put(S, K, r, T, sigma, q)

# Print the option prices and delta
print(paste("Call Option Price:", call_option))
## [1] "Call Option Price: 6.98691953205511"
print(paste("Put Option Price:", put_option))
## [1] "Put Option Price: 8.84614177395456"

Option Greeks

# Option Greeks Calculation using Black-Scholes Formula

# Delta
delta <- function(S, K, r, T, sigma, q, option_type) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  
  if (option_type == "call") {
    delta <- exp(-q * T) * pnorm(d1)
  } else if (option_type == "put") {
    delta <- exp(-q * T) * (pnorm(d1) - 1)
  } else {
    stop("Invalid option type. Please specify 'call' or 'put'.")
  }
  
  return(delta)
}

# Gamma
gamma <- function(S, K, r, T, sigma, q) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  gamma <- (exp(-q * T) * dnorm(d1)) / (S * sigma * sqrt(T))
  
  return(gamma)
}

# Vega
vega <- function(S, K, r, T, sigma, q) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  vega <- S * exp(-q * T) * dnorm(d1) * sqrt(T)
  
  return(vega)
}

# Rho
rho <- function(S, K, r, T, sigma, q, option_type) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  d2 <- d1 - sigma * sqrt(T)
  
  if (option_type == "call") {
    rho <- K * T * exp(-r * T) * pnorm(d2)
  } else if (option_type == "put") {
    rho <- -K * T * exp(-r * T) * pnorm(-d2)
  } else {
    stop("Invalid option type. Please specify 'call' or 'put'.")
  }
  
  return(rho)
}

# Theta
theta <- function(S, K, r, T, sigma, q, option_type) {
  d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
  d2 <- d1 - sigma * sqrt(T)
  
  if (option_type == "call") {
    theta <- -S * exp(-q * T) * dnorm(d1) * sigma / (2 * sqrt(T)) -
             r * K * exp(-r * T) * pnorm(d2) +
             q * S * exp(-q * T) * pnorm(d1)
  } else if (option_type == "put") {
    theta <- -S * exp(-q * T) * dnorm(d1) * sigma / (2 * sqrt(T)) +
             r * K * exp(-r * T) * pnorm(-d2) -
             q * S * exp(-q * T) * pnorm(-d1)
  } else {
    stop("Invalid option type. Please specify 'call' or 'put'.")
  }
  
  return(theta)
}

# Example usage
S <- 100   # Current stock price
K <- 105   # Strike price
r <- 0.05  # Risk-free interest rate
T <- 1     # Time to expiration (in years)
sigma <- 0.2  # Volatility
q <- 0.02  # Dividend yield

call_delta <- delta(S, K, r, T, sigma, q, "call")
call_gamma <- gamma(S, K, r, T, sigma, q)
call_rho   <- rho(S, K, r, T, sigma, q, "call")
call_theta <- theta(S, K, r, T, sigma, q, "call")

put_delta <- delta(S, K, r, T, sigma, q, "put")
put_gamma <- gamma(S, K, r, T, sigma, q)
put_rho   <- rho(S, K, r, T, sigma, q, "put")
put_theta <- theta(S, K, r, T, sigma, q, "put")

Implied Volatility

# Option Implied Volatility Calculation using Black-Scholes Formula

option_implied_volatility <- function(S, K, r, T, market_price, q, option_type, accuracy = 0.001, max_iterations = 100) {
  # Define the Black-Scholes formula for option price
  black_scholes_price <- function(sigma) {
    d1 <- (log(S / K) + (r - q + 0.5 * sigma^2) * T) / (sigma * sqrt(T))
    d2 <- d1 - sigma * sqrt(T)
    
    if (option_type == "call") {
      option_price <- S * exp(-q * T) * pnorm(d1) - K * exp(-r * T) * pnorm(d2)
    } else if (option_type == "put") {
      option_price <- K * exp(-r * T) * pnorm(-d2) - S * exp(-q * T) * pnorm(-d1)
    } else {
      stop("Invalid option type. Please specify 'call' or 'put'.")
    }
    
    return(option_price)
  }
  
# Define the function for which we will search for the implied volatility
  implied_vol_function <- function(sigma) {
    return(black_scholes_price(sigma) - market_price)
  }
  
# Use the uniroot function to find the root (implied volatility)
implied_vol <- uniroot(implied_vol_function, interval = c(-5, 5), tol = accuracy, maxiter = max_iterations)$root
  
  return(implied_vol)
}

# Example usage
S <- 100   # Current stock price
K <- 105   # Strike price
r <- 0.05  # Risk-free interest rate
T <- 1     # Time to expiration (in years)
market_price <- 7.0  # Market price of the option
q <- 0.02  # Dividend yield
option_type <- "call"  # Specify 'call' or 'put'

implied_vol <- option_implied_volatility(S, K, r, T, market_price, q, option_type)

# Print the implied volatility
print(paste("Implied Volatility:", implied_vol))
## [1] "Implied Volatility: 0.200551177219362"

Get Option Data From Yahoo Finance

library(quantmod)
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.0.2
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.0.2
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
# Get Financial Data from Yahoo Finance
symbol <- "AAPL"  # Example symbol for Apple Inc.
start_date <- "2022-01-01"
end_date <- "2022-12-31"

# Fetching historical price data
data <- getSymbols(symbol, from = start_date, to = end_date, src = "yahoo", auto.assign = FALSE)

prices <- Ad(data)

options_data <- getOptionChain(symbol, NULL)