Search code examples
rquantstratfinancialinstrument

How to get current "symbol" inside custom function when applyIndicators or applyStrategy in quantstrat


i would like to access the current symbol string eg "GOOG" inside my custom indicator function. Here is the most basic example i could make.

require(quantstrat)
Sys.setenv(TZ="UTC")
symbols <- c("GOOG", "AAPL")
getSymbols(symbols, src="yahoo")
strategy.st  <- "test"
strategy(strategy.st, store=TRUE)


test_fun <- function(x){
  print(symbol)  ##### i want to access the current symbol eg "GOOG"
  return(x)
} 



add.indicator(strategy = strategy.st,
              name = "test_fun",
              arguments = list(x = quote(Cl(mktdata))),
              label = "test_ind")


mktdata <- applyIndicators(strategy = strategy.st, GOOG)

Error in print(symbol) : object 'symbol' not found
Called from: print(symbol)

Solution

  • Good question.

    Getting the symbol from your applyIndicator function as a stand alone function call doesn't really make much sense, because the mktdata = GOOG argument already contains the data you want. I suspect you want to get the symbol in the applyIndicator call though when you to work when you call applyStrategy though...

    You can do this:

    require(quantstrat)
    Sys.setenv(TZ="UTC")
    symbols <- c("GOOG", "AAPL")
    getSymbols(symbols, src="yahoo")
    
    currency("USD")
    stock(c("GOOG", "AAPL"), "USD")
    
    strategy.st  <- "test"
    portfolio.st  <- "test"
    rm.strat(strategy.st)
    initPortf(portfolio.st, symbols = symbols)
    strategy(strategy.st, store=TRUE)
    
    
    account.st  <- "test"
    initAcct(account.st, portfolios = portfolio.st, initEq = 1000)
    initOrders(portfolio.st)
    
    
    
    test_fun <- function(x){
      symbol <- parent.frame(n = 2)$symbol
      print(symbol)  ##### i want to access the current symbol eg "GOOG"
      return(x)
    } 
    
    
    
    add.indicator(strategy = strategy.st,
                  name = "test_fun",
                  arguments = list(x = quote(Cl(mktdata))),
                  label = "test_ind")
    applyStrategy(strategy.st, portfolio.st)
    

    This works for applyStrategy because the parent environment up a few levels loops around a symbols loop (calling applyIndicators on each iteration), with symbol holding the current symbol for which indicators are being computed.

    This obviously allows you to pull in external data from your global environment or other environments, if you want to do more advanced indicator construction with more than just the data in your mktdata object for the currenct symbol that is passed to applyIndicators.

    (An easier approach is also to simply extract the symbol name from the OHLC column names, which may exist in the x object inside testfun, if the column names contain the symbol label.)