Search code examples
rquantmodyahoo-finance

Is there a better way to retrieve accurate Weekly and Monthly stock price data with R's 'quantmod'?


I have tried using BatchGetSymbols to retrieve price data for multiple stock tickers for Weekly and Monthly price data (ohlc) but weekly and monthly functions fail to return to correct data. When using the 'batchgetsymbols' 'freq.data = "weekly' argument the weekly price starts from a Wednesday which is incorrect for weekly price data. It Weekly ohlc data should be at the end of each week (Monday-Friday).

The closest thing I have found to retrieving the correct weekly/monthly data is using the 'getsymbols' function with 'quantmod' but currently only limited to searching one single ticker. Is anyone able to help me alter this script to search and retrieve weekly ohlc data for multiple tickers? For example:

> library(quantmod)
stock_list <- c("FB", "AAPL", "GOOG","BA","DAL","TSLA")
start_date <- Sys.Date()-14
end_date <- Sys.Date()
master_df <- NULL
for (idx in seq(length(stock_list))){
  idx = 1
  stock_index = stock_list[idx]
  getSymbols(stock_index, verbose = TRUE, src = "yahoo", 
             from=start_date,to=end_date)
  temp_df = as.data.frame(to.weekly(get(stock_index))) # weekly data
  temp_df$Date = row.names(temp_df)
  temp_df$Index = stock_index
  row.names(temp_df) = NULL
  colnames(temp_df) = c("Open", "High", "Low", "Close", 
                        "Volume", "Adjusted", "Date", "Index")
  temp_df = temp_df[c("Date", "Index", "Open", "High", 
                      "Low", "Close", "Volume", "Adjusted")]
  master_df = rbind(master_df, temp_df)
}

Any help would be much appreciated.


Solution

  • A fast way of doing this is using tidyquant. There is a weekly and monthly option in getSymbols, which is called when using tq_get. Don't pay attention to the the way a tibble is being printed to the screen, just check the data in the RStudio viewer.

    library(tidyquant)
    library(dplyr)
    
    stock_list <- c("FB", "AAPL", "GOOG","BA","DAL","TSLA")
    start_date <- Sys.Date()-14
    end_date <- Sys.Date()
    
    stocks_weekly <- tq_get(stock_list, from = start_date, to = end_date, periodicity = "weekly")
    
    stocks_weekly 
    
    # A tibble: 12 x 8
       symbol date         open   high    low  close    volume adjusted
       <chr>  <date>      <dbl>  <dbl>  <dbl>  <dbl>     <dbl>    <dbl>
     1 FB     2020-11-02  265.   297.   257.   293.  118206600    293. 
     2 FB     2020-11-09  290.   293.   264    277.   92433100    277. 
     3 AAPL   2020-11-02  109.   120.   107.   119.  609571800    118. 
     4 AAPL   2020-11-09  120.   122.   114.   119.  589577900    119. 
     5 GOOG   2020-11-02 1628.  1794.  1616.  1762.   11494700   1762. 
     6 GOOG   2020-11-09 1791.  1818.  1717.  1777.    8915800   1777. 
     7 BA     2020-11-02  146.   158.   143.   158.   58773000    158. 
     8 BA     2020-11-09  179    194.   172.   187.  165339400    187. 
     9 DAL    2020-11-02   30.6   32.3   29.7   31.4  65773500     31.4
    10 DAL    2020-11-09   37.4   38.7   34.0   36.5 150014900     36.5
    11 TSLA   2020-11-02  394    440    392.   430.  145636400    430. 
    12 TSLA   2020-11-09  440.   452.   396.   408.  122101100    408. 
    

    If you want to see the data a bit better, use print(as.data.frame(stocks_weekly))

    update:

    There are some issues with all of the functions to get the correct weekly / monthly data. I'm in the process of creating (or adding info to) github issues.

    Below is code that can handle a lot of tickers without running into download errors.

    The mutate function uses functions from time_tk and xts to get everything correctly. I use only the columns that are needed as BatchGetSymbols also calculates the daily returns. In the end I rename the columns to get them named correctly. All time_tk functions could be replaced by just base and xts functions, but this saved me some time.

    library(BatchGetSymbols)
    library(timetk)
    library(xts)
    library(dplyr)
    library(tidyr)
    library(purrr)
    
    stocks <- BatchGetSymbols(stock_list, 
                              first.date = start_date, 
                              last.date = end_date, 
                              freq.data = "daily")
    
    stocks_weekly <- stocks$df.tickers %>% 
      group_by(ticker) %>% 
      nest() %>% 
      mutate(data = map(data, function(x) {x = tk_xts(x, 
                                                      select = c(price.open, price.high, price.low, price.close, volume, price.adjusted), 
                                                      date_var =  ref.date)
                                            tk_tbl(to.period(x, period = "weeks"))
                                              })
             ) %>% 
      unnest(cols = c(data)) %>% 
      rename_with( ~ tolower(gsub("x.", "", .x)),  starts_with("x."))
    

    update 2

    An update to the github version of BatchGetSymbols does the weekly figures correctly (Note that the date will be the first day of the week (Monday)). You can install the github version of wait until the update is available on cran.

    stocks_week <- BatchGetSymbols(stock_list, 
                               first.date = start_date, 
                               last.date = end_date, 
                               freq.data = "weekly", 
                               how.to.aggregate = 'last')