You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于R语言Black-Scholes公式的Shiny应用后端代码求助

含股息的Black-Scholes期权定价Shiny应用Server端实现

问题背景

我已用R语言编写了含股息的Black-Scholes期权定价计算函数,现在要开发Shiny应用调用该函数,UI部分已完成,但Server端调用函数失败,求对应的Server端代码。

现有Black-Scholes函数代码

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)
    
    # 修正变量名:与函数参数统一为optionType
    if (optionType == "Call") {
      delta <- exp(-dividendYield * timeToMaturity) * pnorm(d1)
    } else if (optionType == "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)
  }

已完成的Shiny 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(
      textOutput("results")
    )
  )
)

解决方案:Server端代码实现

server <- function(input, output) {
  
  # 监听分析按钮点击事件,触发计算
  observeEvent(input$analyzeBtn, {
    # 提取并转换用户输入参数,匹配函数要求
    params <- list(
      currentStockPrice = 150,  # 可后续接入财经API替换为实时价格
      strikePrice = input$strike,
      timeToMaturity = input$timetomaturity / 365,  # 转换为年单位
      volatility = input$volatility,
      interestRate = input$interest,
      dividendYield = input$dividend,
      optionType = toupper(input$optiontype)  # 转为大写匹配函数参数
    )
    
    # 调用Black-Scholes计算函数
    calc_result <- do.call(blackScholesCalculation, params)
    
    # 格式化输出结果
    output$results <- renderText({
      target_price <- if(params$optionType == "CALL") calc_result$call_price else calc_result$put_price
      
      paste0(
        "标的代码: ", input$underlying, "\n",
        "期权类型: ", if(params$optionType == "CALL") "看涨期权" else "看跌期权", "\n",
        "期权价格: ", round(target_price, 4), "\n",
        "Delta值: ", round(calc_result$delta, 4), "\n",
        "Gamma值: ", round(calc_result$gamma, 4), "\n",
        "Theta值: ", round(calc_result$theta, 4), "\n",
        "Vega值: ", round(calc_result$vega, 4)
      )
    })
  })
}

# 启动Shiny应用
shinyApp(ui = ui, server = server)

关键修复与说明

  • 修正原函数变量名不一致问题:将函数内判断用的option_type统一为optionType,与函数参数名匹配,避免报错
  • 处理参数格式匹配:将滑块输入的天数转换为年单位,把UI传递的小写期权类型转为大写,符合函数输入要求
  • 优化参数传递:用do.call统一传递参数,代码更简洁
  • 格式化输出结果:让计算结果更清晰易读,同时保留所有 Greeks 指标

内容的提问来源于stack exchange,提问作者Averium

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 16:15:13