mirror of
https://github.com/ArthurDanjou/ArtStudies.git
synced 2026-01-14 15:54:13 +01:00
Implement Black‑Scholes Shiny app: complete server & UI (call/put pricing, plotly plots, add volatility/rates/dividend inputs, run app) and add kable/paged_table examples to tp3.Rmd
This commit is contained in:
@@ -1,64 +1,46 @@
|
|||||||
# Original source : https://srdas.github.io/MLBook/Shiny.html#the-application-program
|
# R
|
||||||
|
# Black-Scholes Shiny app — fixed plots for call and put
|
||||||
|
|
||||||
library(shiny)
|
library(shiny)
|
||||||
library(plotly)
|
library(plotly)
|
||||||
library(ggplot2)
|
library(ggplot2)
|
||||||
library(ggthemes)
|
library(ggthemes)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### CONSIGNES #####
|
|
||||||
# 1. Completer le code du serveur (???) permet de compléter l'objet `output` (argument plotCall
|
|
||||||
# et plotPut). Il s'agit de deux figures qui permet de presenter la valeur
|
|
||||||
# d'un call et d'un put en fonction du Strike K.
|
|
||||||
|
|
||||||
# 2. Compléter le code de l'ui (???) afin de creer des box affichant la valeur de l'action
|
|
||||||
# 'Stock Price' et du strike 'Strike Price'. Prendre par dééfaut la valeur 100.
|
|
||||||
|
|
||||||
# 3 . Sur la base du slider pour la Maturité, ajouter un slider pour la volatilité,
|
|
||||||
# le taux sans risque et le taux de dividende.
|
|
||||||
|
|
||||||
# 4. Lancer l'application.
|
|
||||||
|
|
||||||
##### SERVER #####
|
##### SERVER #####
|
||||||
|
|
||||||
# Define server logic for random distribution application
|
|
||||||
server <- function(input, output) {
|
server <- function(input, output) {
|
||||||
|
|
||||||
#Generate Black-Scholes values
|
# Generate Black-Scholes values
|
||||||
BS = function(S,K,T,v,rf,dv) {
|
BS = function(S, K, T, v, rf, dv) {
|
||||||
d1 = (log(S/K) + (rf-dv+0.5*v^2)*T)/(v*sqrt(T))
|
d1 = (log(S/K) + (rf - dv + 0.5 * v^2) * T) / (v * sqrt(T))
|
||||||
d2 = d1 - v*sqrt(T)
|
d2 = d1 - v * sqrt(T)
|
||||||
bscall = S*exp(-dv*T)*pnorm(d1) - K*exp(-rf*T)*pnorm(d2)
|
bscall = S * exp(-dv * T) * pnorm(d1) - K * exp(-rf * T) * pnorm(d2)
|
||||||
bsput = -S*exp(-dv*T)*pnorm(-d1) + K*exp(-rf*T)*pnorm(-d2)
|
bsput = -S * exp(-dv * T) * pnorm(-d1) + K * exp(-rf * T) * pnorm(-d2)
|
||||||
res = c(bscall,bsput)
|
c(bscall, bsput)
|
||||||
}
|
}
|
||||||
|
|
||||||
#Call option price
|
# Call option price
|
||||||
output$BScall <- renderText({
|
output$BScall <- renderText({
|
||||||
#Get inputs
|
|
||||||
S = input$stockprice
|
S = input$stockprice
|
||||||
K = input$strike
|
K = input$strike
|
||||||
T = input$maturity
|
T = input$maturity
|
||||||
v = input$volatility
|
v = input$volatility
|
||||||
rf = input$riskfreerate
|
rf = input$riskfreerate
|
||||||
dv = input$divrate
|
dv = input$divrate
|
||||||
res = round(BS(S,K,T,v,rf,dv)[1],4)
|
round(BS(S, K, T, v, rf, dv)[1], 4)
|
||||||
})
|
})
|
||||||
|
|
||||||
#Put option price
|
# Put option price
|
||||||
output$BSput <- renderText({
|
output$BSput <- renderText({
|
||||||
#Get inputs
|
|
||||||
S = input$stockprice
|
S = input$stockprice
|
||||||
K = input$strike
|
K = input$strike
|
||||||
T = input$maturity
|
T = input$maturity
|
||||||
v = input$volatility
|
v = input$volatility
|
||||||
rf = input$riskfreerate
|
rf = input$riskfreerate
|
||||||
dv = input$divrate
|
dv = input$divrate
|
||||||
res = round(BS(S,K,T,v,rf,dv)[2],4)
|
round(BS(S, K, T, v, rf, dv)[2], 4)
|
||||||
})
|
})
|
||||||
|
|
||||||
#Call plot
|
# Call plot (shows call and put curves across strikes)
|
||||||
output$plotCall <- renderPlotly({
|
output$plotCall <- renderPlotly({
|
||||||
S = input$stockprice
|
S = input$stockprice
|
||||||
K = input$strike
|
K = input$strike
|
||||||
@@ -66,36 +48,62 @@ server <- function(input, output) {
|
|||||||
v = input$volatility
|
v = input$volatility
|
||||||
rf = input$riskfreerate
|
rf = input$riskfreerate
|
||||||
dv = input$divrate
|
dv = input$divrate
|
||||||
vcall = NULL; vput = NULL
|
|
||||||
strikes = seq(K-30,K+30)
|
strikes = seq(K - 30, K + 30)
|
||||||
for (k in strikes) {
|
vcall = sapply(strikes, function(k) BS(S, k, T, v, rf, dv)[1])
|
||||||
vcall = ???
|
vput = sapply(strikes, function(k) BS(S, k, T, v, rf, dv)[2])
|
||||||
vput = ???
|
|
||||||
}
|
df = data.frame(strikes = strikes, Call = vcall, Put = vput)
|
||||||
df = data.frame(strikes,vcall,vput)
|
p <- ggplot(df, aes(x = strikes)) +
|
||||||
p <- ggplot(???) + ???
|
geom_line(aes(y = Call, color = "Call")) +
|
||||||
|
geom_line(aes(y = Put, color = "Put")) +
|
||||||
|
labs(title = "Black-Scholes Option Pricing",
|
||||||
|
x = "Strike Price",
|
||||||
|
y = "Option Price") +
|
||||||
|
theme_minimal() +
|
||||||
|
scale_color_manual("", values = c("Call" = "steelblue", "Put" = "firebrick"))
|
||||||
plotly::ggplotly(p)
|
plotly::ggplotly(p)
|
||||||
})
|
})
|
||||||
|
|
||||||
#Put plot
|
# Put plot (same curves — kept for tab separation)
|
||||||
output$plotPut <- ???
|
output$plotPut <- renderPlotly({
|
||||||
|
S = input$stockprice
|
||||||
|
K = input$strike
|
||||||
|
T = input$maturity
|
||||||
|
v = input$volatility
|
||||||
|
rf = input$riskfreerate
|
||||||
|
dv = input$divrate
|
||||||
|
|
||||||
|
strikes = seq(K - 30, K + 30)
|
||||||
|
vcall = sapply(strikes, function(k) BS(S, k, T, v, rf, dv)[1])
|
||||||
|
vput = sapply(strikes, function(k) BS(S, k, T, v, rf, dv)[2])
|
||||||
|
|
||||||
|
df = data.frame(strikes = strikes, Call = vcall, Put = vput)
|
||||||
|
p <- ggplot(df, aes(x = strikes)) +
|
||||||
|
geom_line(aes(y = Put, color = "Put")) +
|
||||||
|
geom_line(aes(y = Call, color = "Call")) +
|
||||||
|
labs(title = "Black-Scholes Option Pricing",
|
||||||
|
x = "Strike Price",
|
||||||
|
y = "Option Price") +
|
||||||
|
theme_minimal() +
|
||||||
|
scale_color_manual("", values = c("Call" = "steelblue", "Put" = "firebrick"))
|
||||||
|
plotly::ggplotly(p)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
##### UI #####
|
##### UI #####
|
||||||
|
|
||||||
ui <- shinyUI(fluidPage(
|
ui <- shinyUI(fluidPage(
|
||||||
|
|
||||||
titlePanel("Black-Scholes-Merton (1973)"),
|
titlePanel("Black-Scholes-Merton (1973)"),
|
||||||
|
|
||||||
sidebarLayout(
|
sidebarLayout(
|
||||||
sidebarPanel(
|
sidebarPanel(
|
||||||
numericInput(???,'Stock Price', ???),
|
numericInput('stockprice', 'Stock Price', 100),
|
||||||
numericInput(???,'Strike Price', ???),
|
numericInput('strike', 'Strike Price', 100),
|
||||||
sliderInput('maturity','Maturity (years)',min=0.1,max=10,value=1,step=0.01),
|
sliderInput('maturity', 'Maturity (years)', min = 0.1, max = 10, value = 1, step = 0.01),
|
||||||
sliderInput(???),
|
sliderInput('volatility', 'Volatility (annualized)', min = 0.1, max = 2, value = 0.2, step = 0.01),
|
||||||
sliderInput(???),
|
sliderInput('riskfreerate', 'Risk-free Rate (annualized)', min = 0, max = 0.5, value = 0.01, step = 0.01),
|
||||||
sliderInput(???),
|
sliderInput('divrate', 'Dividend Yield (annualized)', min = 0, max = 0.5, value = 0, step = 0.01),
|
||||||
hr(),
|
hr(),
|
||||||
p('Please refer to following for more details:',
|
p('Please refer to following for more details:',
|
||||||
a("Black-Scholes (1973)",
|
a("Black-Scholes (1973)",
|
||||||
@@ -111,12 +119,12 @@ ui <- shinyUI(fluidPage(
|
|||||||
textOutput("BSput"),
|
textOutput("BSput"),
|
||||||
hr(),
|
hr(),
|
||||||
tabsetPanel(
|
tabsetPanel(
|
||||||
tabPanel("Calls", plotlyOutput("plotCall",width="100%")),
|
tabPanel("Calls", plotlyOutput("plotCall", width = "100%")),
|
||||||
tabPanel("Puts", plotlyOutput("plotPut",width="100%"))
|
tabPanel("Puts", plotlyOutput("plotPut", width = "100%"))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
|
|
||||||
##### Run #####
|
##### Run #####
|
||||||
???
|
shinyApp(ui = ui, server = server)
|
||||||
@@ -28,3 +28,16 @@ plot(pressure)
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
|
Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
|
||||||
|
|
||||||
|
|
||||||
|
```{r}
|
||||||
|
library(kableExtra)
|
||||||
|
mtcars[1:5, 1:5] %>%
|
||||||
|
kbl() %>%
|
||||||
|
kable_styling()
|
||||||
|
```
|
||||||
|
|
||||||
|
```{r}
|
||||||
|
library(rmarkdown)
|
||||||
|
paged_table(mtcars, options = list(rows.print = 15))
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user