I am trying to make a web app with the intention of using quantstrat. However I am having a bit of difficulty integrating the two. There is no documentation on this so it's tough to find a place to start. Here is the code I have right now. It would be much appreciated if you could let me know what I am doing wrong. Thank you
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)
Interesting idea. What you're trying to do is a little challenging due to the nature of how the market data for the instruments traded is stored in the local environment in variables that have names equal to their symbols/tickers.
Also, you're some peculiar things with your shiny app; be careful how you use
reactive({
,isolate({
and other server components. For instance when you have server objects likethat are redundant.
Here is an example that does what you're trying to achieve. I've tried to keep the variable names consistent with your example where possible.
You may want to reconsider your workflow: I think you should run large batches of simulations in
quantstrat
independently of shiny, then save the results to disk. Then load these results from disk when you launch your Shiny app. Nevertheless this example will hopefully sort out any remaining confusion you have.Also, you should be careful about how often you request data from yahoo via
getSymbols
. What I do below is request the data only once when the app is first launched, and store the market data in the symbols in an environment calledrawdata
. Then if you stop and restart your app again, you won't keep making requests to yahoo for data (which might give you errors when they throttle how much you can download within a period of time).The app will look something like this: