Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
结合shiny和Quantstrat回溯测试_R_Shiny_Quantstrat - Fatal编程技术网

结合shiny和Quantstrat回溯测试

结合shiny和Quantstrat回溯测试,r,shiny,quantstrat,R,Shiny,Quantstrat,我正在尝试使用quantstrat制作一个web应用程序。然而,我在整合这两个方面有点困难。没有关于这个的文档,所以很难找到一个开始的地方。这是我现在的代码。如果你能让我知道我做错了什么,我将不胜感激。多谢各位 library(shiny) library(devtools) library(quantmod) library(quantstrat) library(TTR) library(png) library(dplyr) Sys.setenv(TZ = "UTC") currency(

我正在尝试使用quantstrat制作一个web应用程序。然而,我在整合这两个方面有点困难。没有关于这个的文档,所以很难找到一个开始的地方。这是我现在的代码。如果你能让我知道我做错了什么,我将不胜感激。多谢各位

library(shiny)
library(devtools)
library(quantmod)
library(quantstrat)
library(TTR)
library(png)
library(dplyr)
Sys.setenv(TZ = "UTC")
currency('USD')

ui <- fluidPage(

# Application title
titlePanel("myfirst"),


sidebarLayout(
  sidebarPanel(
    selectInput(
     "stocks", label = "chose stock", choices = 
      c("AAPL", "CAT")
    ),
    dateInput("init_date", "chose init date", 
     value = Sys.Date() -100),
    dateInput("start_date", "chose start date", 
     value = Sys.Date() - 99),
    dateInput("end_date", "chose end date", 
     value = Sys.Date()),
    selectInput("init_equity", "starting 
    equity", choices = c(1000, 50000))
  ),


  mainPanel(
     plotOutput("plot"),
     textOutput("text")
  )
  )

  )

  server <- function(input, output) {
  init_date = reactive({
  input$init_date
   })
  start_date = reactive({
input$start_date
})
end_date = reactive({
input$end_date
 })
 init_equity = reactive({
  input$init_equity
 })

  V = reactive({
  getSymbols(input$stocks, from = start_date(), 
 to = end_date(), index.class = "POSIXct", 
adjust = T)
 })

 observe({
stock(input$stocks, currency = "USD", multiplier 
= 1)
   })

  portfolio.st = account.st = strategy.st = 
 "my.first"

 rm.strat(portfolio.st)
 rm.strat(account.st)

 observe({ 
   initPortf(name = portfolio.st,
        symbols = "V",
        initDate = init_date())
 initAcct(name = account.st,
         portfolios = portfolio.st,
         initDate = init_date(),
         initEq = init_equity())
 initOrders(portfolio = portfolio.st,
           symbols = "V",
           initDate = init_date()
           )
 strategy(strategy.st, store = T)


 })

observe({ add.indicator(strategy = strategy.st,
            name = "SMA",
            arguments = list(x = 
  quote(Cl(mktdata)), 
                             n = 10),
            label = "nFast")

add.indicator(strategy = strategy.st, 
              name = "SMA", 
              arguments = list(x = 
quote(Cl(mktdata)), 
                               n = 30), 
              label = "nSlow")

add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("nFast", "nSlow"),
                            relationship = "gte"),
           label = "long")
add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("nFast", "nSlow"),
                            relationship = "lt"),
           label = "short")
add.rule(strategy = strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "long",
                          sigval = TRUE,
                          orderqty = 100,
                          ordertype = "stoplimit",
                          orderside = "long", 
                          threshold = 0.0005,
                          prefer = "High", 
                          TxnFees = -10, 
                          replace = FALSE),
         type = "enter",
         label = "EnterLONG")
add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "short",
                          sigval = TRUE,
                          orderqty = -100,
                          ordertype = "stoplimit",
                          threshold = -0.005, 
                          orderside = "short", 
                          replace = FALSE, 
                          TxnFees = -10, 
                          prefer = "Low"),
         type = "enter",
         label = "EnterSHORT")
add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "short", 
                          sigval = TRUE, 
                          orderside = "long", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -10, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2SHORT")
add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "long", 
                          sigval = TRUE, 
                          orderside = "short", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -10, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2LONG")
applyStrategy(strategy.st, portfolios = portfolio.st)
updatePortf(portfolio.st)
updateAcct(account.st)
updateEndEq(account.st)

})

 output$plot = reactive(
  chart.Posn(portfolio.st, Symbol = "V")
  )
 }

 # Run the application 
  shinyApp(ui = ui, server = server)
库(闪亮)
图书馆(devtools)
图书馆(quantmod)
图书馆(quantstrat)
图书馆(TTR)
图书馆(png)
图书馆(dplyr)
Sys.setenv(TZ=“UTC”)
货币(美元)

ui有趣的想法。由于交易工具的市场数据是如何存储在本地环境中的变量中的,这些变量的名称与其符号/股票代码相同,因此您试图做的事情有点挑战性

此外,你的闪亮应用程序也有一些独特之处;注意如何使用
被动({
隔离({
和其他服务器组件

start_date = reactive({
input$start_date
})` 
这是多余的

下面是一个示例,它实现了您试图实现的目标。我已尽可能使变量名与您的示例保持一致

您可能需要重新考虑您的工作流程:我认为您应该在
quantstrat
中独立于Shining运行大量模拟,然后将结果保存到磁盘。然后在启动Shining应用程序时从磁盘加载这些结果。不过,此示例有望解决您仍然存在的任何困惑

另外,你应该注意你通过
getSymbols
向雅虎请求数据的频率。我在下面做的是在应用程序首次启动时只请求一次数据,并将市场数据存储在名为
rawdata
的环境中的符号中。然后,如果你停止并再次重新启动应用程序,你将不会继续发出请求o雅虎的数据(这可能会给你错误时,他们节流多少,你可以下载在一段时间内)


#可以把这些放在全局变量中。R,这些全局变量是“硬编码的”----------------

min_date_barrier Hi@FXQuantTrader,感谢您的深入回复。我想用R对一些带有自定义指标的策略进行回溯测试。我想知道Quanstart是否仍然是go-to软件包。在github上,软件包“失败”。也许有更好的替代方案?具体来说,我正在尝试回溯测试“海龟交易员”策略。我期待着您的回复。在github页面上,它说构建失败。我会接受您的建议,因为您似乎很有知识,我喜欢阅读您的帖子。@FXQuantTrader,如果您不介意的话,我想亲自问您一些问题。我正在开发一个应用程序,该应用程序基于著名交易员/策略创建投资组合gies。例如CANSLIM、TurtleTraders等。用户可以模仿投资组合。另外,您是否介意对为什么您认为Quanstart是最好的开源backtester给出更多的说明?

# Could put these in global.R, these global variables are "hard coded"  ----------------
min_date_barrier <- "2012-01-01"
max_date_barrier <- "2019-04-17"
stock_universe <- c("AAPL", "CAT", "BB")

# These variables won't change when the app launches, so hard code them too:

Sys.setenv(TZ = "UTC")
currency('USD')
stock(stock_universe, currency = "USD", multiplier = 1)

portfolio.st <- account.st <- strategy.st <- "my.first"

# In here, store the original market data which contains your full range of possible values for the market data:
# Don't keep requesting data frequently otherwise you won't be able to download the data temporarily.
if (!exists("rawdata")) {
    rawdata <- new.env()
    assign("rawdata", rawdata, envir = .GlobalEnv)

    lapply(stock_universe, function(sym) {
        # if (exists(sym, envir = rawdata)) {
        #     message("Have already downloaded data for ", sym)
        #     return()
        # } else {
            getSymbols(stock_universe,
                       env = rawdata,  # important to specify environment
                       from = min_date_barrier,
                       to = max_date_barrier,
                       adjust = T, auto.assign = TRUE)
        #}
        return()
    })

}

# UI ----------------------------------------------------------------------

ui <- fluidPage(

    # Application title
    titlePanel("myfirst"),


    sidebarLayout(
        sidebarPanel(
            selectInput(
                "stock", label = "Choose stock", choices = stock_universe
            ),

            dateInput("start_date", "Choose start date",
                      value = "2018-02-03"),
            dateInput("end_date", "Choose end date",
                      value = "2019-04-10"),
            selectInput("init_equity", "starting
    equity", choices = c(1000, 50000))
        ),


        mainPanel(
            plotOutput("plot_backtest"),
            verbatimTextOutput("results")
        )
    )

)



# server ------------------------------------------------------------------

server <- function(input, output, session) {

    # all your reactives don't make sense -- only use the inputs when you need them on the server side


    backtest_setup <- reactive({

        # need these input variables in this reactive to avoid bugs in the app when you change the time range:

        input$start_date
        input$end_date
        rm.strat(portfolio.st, silent = FALSE)
        initPortf(name = portfolio.st,
                  symbols = input$stock,        #------------------------ correct way to apply the "stock" input
                  initDate = "2000-01-01")
        initAcct(name = account.st,
                 portfolios = portfolio.st,
                 initDate = "2000-01-01",
                 initEq = as.numeric(input$init_equity)) # convert equity to numeric from string
        initOrders(portfolio = portfolio.st,
                   symbols = input$stock,  # ----------------------------------
                   initDate = "2000-01-01"
        )
        strategy(strategy.st, store = T)


        add.indicator(strategy = strategy.st,
                      name = "SMA",
                      arguments = list(x =
                                           quote(Cl(mktdata)),
                                       n = 10),
                      label = "nFast")

        add.indicator(strategy = strategy.st,
                      name = "SMA",
                      arguments = list(x =
                                           quote(Cl(mktdata)),
                                       n = 30),
                      label = "nSlow")

        add.signal(strategy = strategy.st,
                   name="sigCrossover",
                   arguments = list(columns = c("nFast", "nSlow"),
                                    relationship = "gte"),
                   label = "long")
        add.signal(strategy = strategy.st,
                   name="sigCrossover",
                   arguments = list(columns = c("nFast", "nSlow"),
                                    relationship = "lt"),
                   label = "short")
        add.rule(strategy = strategy.st,
                 name = "ruleSignal",
                 arguments = list(sigcol = "long",
                                  sigval = TRUE,
                                  orderqty = 100,
                                  ordertype = "stoplimit",
                                  orderside = "long",
                                  threshold = 0.0005,
                                  prefer = "High",
                                  TxnFees = -10,
                                  replace = FALSE),
                 type = "enter",
                 label = "EnterLONG")
        add.rule(strategy.st,
                 name = "ruleSignal",
                 arguments = list(sigcol = "short",
                                  sigval = TRUE,
                                  orderqty = -100,
                                  ordertype = "stoplimit",
                                  threshold = -0.005,
                                  orderside = "short",
                                  replace = FALSE,
                                  TxnFees = -10,
                                  prefer = "Low"),
                 type = "enter",
                 label = "EnterSHORT")
        add.rule(strategy.st,
                 name = "ruleSignal",
                 arguments = list(sigcol = "short",
                                  sigval = TRUE,
                                  orderside = "long",
                                  ordertype = "market",
                                  orderqty = "all",
                                  TxnFees = -10,
                                  replace = TRUE),
                 type = "exit",
                 label = "Exit2SHORT")
        add.rule(strategy.st,
                 name = "ruleSignal",
                 arguments = list(sigcol = "long",
                                  sigval = TRUE,
                                  orderside = "short",
                                  ordertype = "market",
                                  orderqty = "all",
                                  TxnFees = -10,
                                  replace = TRUE),
                 type = "exit",
                 label = "Exit2LONG")

    })

    V <- reactive({

        validate(need(input$start_date >= as.Date(min_date_barrier), "start date cannot be less than hard coded min_date_barrier"))
        validate(need(input$end_date <= as.Date(max_date_barrier), "end date cannot be greater than  hard coded max_date_barrier"))
        validate(need(as.Date(input$start_date) < as.Date(input$end_date), "start date must be less than end date."))
        # assign symbol market data to the global environment for the range of dates you want:
        time_rng <- paste0(input$start_date, "/", input$end_date)
        mdata <- get(input$stock, envir = rawdata)
        mdata <- mdata[time_rng]

        validate(need(NROW(mdata) > 0, "no data available, choose an appropriate time range"))

        mdata
    })

    backtest_results <- reactive({

        backtest_setup()
        mdata <- V()
        assign(input$stock, mdata, envir = .GlobalEnv)
        # not supplying mktdata as a parameter, so look in global environment for objects with the symbol names (which will exist because V assigns to .GlobalEnv):
        applyStrategy(strategy.st, portfolios = portfolio.st)
        # alternatively you could pass in the data directly to apply strategy if you're just using one symbol of data in the applyStrategy call, instead of having applyStrategy directly search in the .GlobalEnv for the symbol name
        #applyStrategy(strategy.st, portfolios = portfolio.st, mktdata = mdata)
        updatePortf(portfolio.st)
        updateAcct(account.st)
        updateEndEq(account.st)

    })

    output$plot_backtest = renderPlot({
        backtest_results()
        chart.Posn(portfolio.st, Symbol = input$stock)
    })

    output$results = renderPrint({
        backtest_setup()
        tmpdata <- V() # need this here so that any changes to the inputs will reprint the trade stats table
        print(tradeStats(portfolio.st))
    })

}

# Run the application
shinyApp(ui = ui, server = server)