Averium
Averium

Reputation: 1

Execute Calculation in Shiny

I've created a Black-Scholes formula in rStudio using R (see below)

blackScholesCalculation <-
  function(currentStockPrice,
           strikePrice,
           timeToMaturity,
           volatility,
           interestRate,
           dividendYield,
           optionType) {
    d1 <-
      (
        log(currentStockPrice / strikePrice) + (interestRate - dividendYield + (volatility ^
                                                                                  2) / 2) * timeToMaturity
      ) / (volatility * sqrt(timeToMaturity))
    d2 <- d1 - volatility * sqrt(timeToMaturity)
    
    if (option_type == "Call") {
      delta <- exp(-dividendYield * timeToMaturity) * pnorm(d1)
    } else if (option_type == "Put") {
      delta <- -exp(-dividendYield * timeToMaturity) * pnorm(-d1)
    }
    
    # Gamma Formula
    gamma <-
      exp(-dividendYield * timeToMaturity) * dnorm(d1) / (currentStockPrice * volatility * sqrt(timeToMaturity))
    
    
    # Theta Formula
    theta <-
      -exp(-dividendYield * timeToMaturity) * ((currentStockPrice * dnorm(d1) * volatility) / (2 * sqrt(timeToMaturity))) - interestRate * strikePrice * exp(-interestRate * timeToMaturity) * pnorm(d2) + dividendYield * currentStockPrice * exp(-dividendYield * timeToMaturity) * pnorm(d1)
    
    # Vega Formula
    vega <-
      currentStockPrice * exp(-dividendYield * timeToMaturity) * dnorm(d1) * sqrt(timeToMaturity)
    
    # For European options
    call_price <-
      currentStockPrice * exp(-dividendYield * timeToMaturity) * pnorm(d1) - strikePrice * exp(-interestRate * timeToMaturity) * pnorm(d2)
    
    put_price <-
      strikePrice * exp(-interestRate * timeToMaturity) * pnorm(-d2) - currentStockPrice * exp(-dividendYield * timeToMaturity) * pnorm(-d1)
    
    result <- list(
      call_price = call_price,
      put_price = put_price,
      delta = delta,
      gamma = gamma,
      theta = theta,
      vega = vega
    )
    return(result)
  }

currentStockPrice <- 150
strikePrice <- 150
timeToMaturity <- 30 / 365  # 30 days to expiry
volatility <- 0.2
interestRate <- 0.02
dividendYield <- 0.01  # 1% dividend yield
option_type <- "Call"

blackScholesplusDividend <-
  blackScholesCalculation(
    currentStockPrice,
    strikePrice,
    timeToMaturity,
    volatility,
    interestRate,
    dividendYield,
    option_type
  )

print(blackScholesplusDividend)

So my target here is to create a shiny app that uses this formula, and a set amount of values given by the user (as inputs), and gives an output of the result.

Here's what I've got for my ui so far, what should I have as my server-side code? Again, all I'd like is for the code to read the formula I have listed above to take in the user input values and output the result

ui <- fluidPage(
  
  # App title ----
  titlePanel("Options Strategy Analyser"),
  sidebarLayout(
    sidebarPanel(
      textInput("underlying", "Underlying Symbol", value = "AAPL.O"),
      numericInput("strike", "Strike Price", value = 150),
      numericInput("volatility", "Volatility", value = 0.2),
      sliderInput("timetomaturity", "Time to Maturity", min = 7, max = 365, value = 30),
      numericInput("interest", "Interest Rate", value = 0.02),
      numericInput("dividend", "Dividend Yield", value = 0.01),
      selectInput("optiontype", "Option Type:",
                  c("Call Option" = "call",
                    "Put Option" = "put")),
      actionButton("analyzeBtn", "Determine Option Price")
    ),
    mainPanel(
      textOutput("results")
    )
  )
)

I tried looking around on help files, and executing the black-scholes code in the server <-function(input, output) part of the shinyApp code but to no avail.

Upvotes: 0

Views: 44

Answers (1)

DS_UNI
DS_UNI

Reputation: 2650

here's one way to use your function:

library(shiny)

blackScholesCalculation <-
  function(currentStockPrice,
           strikePrice,
           timeToMaturity,
           volatility,
           interestRate,
           dividendYield,
           optionType) {
    d1 <-
      (
        log(currentStockPrice / strikePrice) + (interestRate - dividendYield + (volatility ^
                                                                                  2) / 2) * timeToMaturity
      ) / (volatility * sqrt(timeToMaturity))
    d2 <- d1 - volatility * sqrt(timeToMaturity)
    
    if (option_type == "Call") {
      delta <- exp(-dividendYield * timeToMaturity) * pnorm(d1)
    } else if (option_type == "Put") {
      delta <- -exp(-dividendYield * timeToMaturity) * pnorm(-d1)
    }
    
    # Gamma Formula
    gamma <-
      exp(-dividendYield * timeToMaturity) * dnorm(d1) / (currentStockPrice * volatility * sqrt(timeToMaturity))
    
    
    # Theta Formula
    theta <-
      -exp(-dividendYield * timeToMaturity) * ((currentStockPrice * dnorm(d1) * volatility) / (2 * sqrt(timeToMaturity))) - interestRate * strikePrice * exp(-interestRate * timeToMaturity) * pnorm(d2) + dividendYield * currentStockPrice * exp(-dividendYield * timeToMaturity) * pnorm(d1)
    
    # Vega Formula
    vega <-
      currentStockPrice * exp(-dividendYield * timeToMaturity) * dnorm(d1) * sqrt(timeToMaturity)
    
    # For European options
    call_price <-
      currentStockPrice * exp(-dividendYield * timeToMaturity) * pnorm(d1) - strikePrice * exp(-interestRate * timeToMaturity) * pnorm(d2)
    
    put_price <-
      strikePrice * exp(-interestRate * timeToMaturity) * pnorm(-d2) - currentStockPrice * exp(-dividendYield * timeToMaturity) * pnorm(-d1)
    
    result <- list(
      call_price = call_price,
      put_price = put_price,
      delta = delta,
      gamma = gamma,
      theta = theta,
      vega = vega
    )

    return(data.frame(result))
  }

#######################################
## The App
#######################################

## The UI
ui <- fluidPage(
  
  # App title ----
  titlePanel("Options Strategy Analyser"),
  sidebarLayout(
    sidebarPanel(
      textInput("underlying", "Underlying Symbol", value = "AAPL.O"),
      numericInput("strike", "Strike Price", value = 150),
      numericInput("volatility", "Volatility", value = 0.2),
      sliderInput("timetomaturity", "Time to Maturity", min = 7, max = 365, value = 30),
      numericInput("interest", "Interest Rate", value = 0.02),
      numericInput("dividend", "Dividend Yield", value = 0.01),
      selectInput("optiontype", "Option Type:",
                  c("Call Option" = "call",
                    "Put Option" = "put")),
      actionButton("analyzeBtn", "Determine Option Price")
    ),
    mainPanel(
      tableOutput("results")
    )
  )
)

## The server function
server <- function(input, output, session) {
  values <- reactiveValues()
  
  observeEvent(input$analyzeBtn, {
    values$results <- blackScholesCalculation(
      150,
      input$strike,
      input$timetomaturity,
      input$volatility,
      input$interest,
      input$dividend,
      input$optiontype
    )
  })
  output$results <- renderTable({
    values$results
  })
}

## run the App
shinyApp(ui, server)

Upvotes: 1

Related Questions