Search code examples
rquantmod

Screen stocks based on Bollinger bands


I am trying to screen several stocks in a list based on Bollinger bands.

Let's say this is the list: c("AMZN","GOOG","TSLA","AAPL")

This is how I am trying to start the code:

stock.list = c("AMZN","GOOG","TSLA","AAPL")
res = list()
for(ss in stock.list) {
stock.data = na.omit(getSymbols(ss, from="1900-01-01", auto.assign=F))
}

I am not sure how to proceed further, but I want to filter the stocks in the list to select only those below the 2nd standard deviation for 50-day average: addBBands(n=50, sd=2)

How would I do that?


Solution

  • Extract the closing prices to a single xts data frame and use rollapply from the zoo package to calculate the bands. Then its smooth sailing.

    library(quantmod)
    
    stock.list = c("AMZN","GOOG","TSLA","AAPL")
    
    res = list()
    
    # Modifying your loop to store closing prices in a separate data frame
    df = xts()
    for(ss in stock.list) {
      res[[ss]] <-na.omit(getSymbols(ss, from="1900-01-01", auto.assign=F))
      names(res[[ss]]) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
      df <- cbind(df, res[[ss]][, "Close"])
    }
    
    names(df) <- stock.list
    
    
    # Calculate standard deviation and moving average
    sigma <- rollapply(df,
                       width = 50,
                       FUN = sd,
                       by.column = TRUE,
                       align = "right",
                       fill = NA)
    
    mu <- rollapply(df,
                    width = 50,
                    FUN = mean,
                    by.column = TRUE,
                    align = "right",
                    fill = NA)
    
    
    # Calculate bollinger bands
    upperBand <- mu + 1.96 * sigma
    lowerBand <- mu - 1.96 * sigma
    
    # Detect signals
    breachedUpper <- df > upperBand
    breachedLower <- df < lowerBand
    
    # AAPL has breached its upper band
    tail(breachedUpper)