基于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
相关产品推荐
相关产品推荐

