Spaces:
Sleeping
Sleeping
| # 必要パッケージ | |
| library(shiny) | |
| library(ggplot2) | |
| library(dplyr) | |
| library(readr) | |
| library(writexl) | |
| library(tidyr) | |
| # UI定義 | |
| ui <- fluidPage( | |
| titlePanel("Gibson-Schwartzモデルによる銅価格シミュレーション"), | |
| sidebarLayout( | |
| sidebarPanel( | |
| numericInput("kappa", "κ(平均回帰速度)", 3.77), | |
| numericInput("alpha", "α(便利性利得の平均)", -0.003), | |
| numericInput("sigma_delta", "σδ(便利性利得のボラティリティ)", 0.015), | |
| numericInput("sigma_S", "σS(価格のボラティリティ)", 0.02), | |
| numericInput("rho", "相関係数ρ", 0.3), | |
| numericInput("n_path", "シミュレーションパス数", 20, min = 1, max = 100), | |
| actionButton("run", "シミュレーション実行"), | |
| downloadButton("download", "CSVでダウンロード") | |
| ), | |
| mainPanel( | |
| plotOutput("simPlot") | |
| ) | |
| ) | |
| ) | |
| # サーバー定義 | |
| server <- function(input, output) { | |
| sim_data <- reactiveVal(NULL) | |
| observeEvent(input$run, { | |
| df <- read_csv("copper_futures_cleaned.csv") | |
| df <- df %>% drop_na() | |
| S0 <- exp(mean(df$log_price, na.rm = TRUE)) | |
| T_days <- 252 | |
| dt <- 1 / T_days | |
| n <- input$n_path | |
| logS <- matrix(0, nrow = T_days + 1, ncol = n) | |
| delta <- matrix(0, nrow = T_days + 1, ncol = n) | |
| logS[1, ] <- log(S0) | |
| delta[1, ] <- input$alpha | |
| set.seed(123) | |
| for (i in 2:(T_days + 1)) { | |
| Z1 <- rnorm(n) | |
| Z2 <- rnorm(n) | |
| W_delta <- Z1 | |
| W_S <- input$rho * Z1 + sqrt(1 - input$rho^2) * Z2 | |
| delta[i, ] <- delta[i - 1, ] + input$kappa * (input$alpha - delta[i - 1, ]) * dt + input$sigma_delta * sqrt(dt) * W_delta | |
| logS[i, ] <- logS[i - 1, ] + (- delta[i - 1, ] - 0.5 * input$sigma_S^2) * dt + input$sigma_S * sqrt(dt) * W_S | |
| } | |
| # ワイド形式のデータフレーム作成 | |
| df_sim <- as.data.frame(exp(logS)) | |
| colnames(df_sim) <- paste0("path_", 1:n) | |
| df_sim$day <- 0:T_days | |
| df_sim <- df_sim %>% relocate(day) | |
| sim_data(df_sim) | |
| # ロング形式でプロット用データも作成 | |
| df_long <- df_sim %>% pivot_longer(-day, names_to = "path", values_to = "price") | |
| output$simPlot <- renderPlot({ | |
| ggplot(df_long, aes(x = day, y = price, group = path, color = path)) + | |
| geom_line(alpha = 0.8) + | |
| scale_color_viridis_d(option = "D") + | |
| labs(title = "Copper Price Simulation using the Gibson-Schwartz Model", | |
| x = "Days", y = "Copper Price (USD/t)", color = "Path") + | |
| theme_minimal(base_size = 14) + | |
| theme(legend.position = "none") | |
| }) | |
| }) | |
| output$download <- downloadHandler( | |
| filename = function() { | |
| paste0("copper_simulation_", Sys.Date(), ".csv") | |
| }, | |
| content = function(file) { | |
| write.csv(sim_data(), file, row.names = FALSE) | |
| } | |
| ) | |
| } | |
| # アプリ起動 | |
| shinyApp(ui = ui, server = server) |