Home > Mobile >  download stock prices from yahoo using R loop
download stock prices from yahoo using R loop

Time:04-15

I am trying to download stock prices from yahoo of several shares at once using R loops. I tried the following code, and it produces results but I would like the results to be presented in column per share.

options(digits=4, width=70)

library("PerformanceAnalytics")
library("tseries")
library("zoo")

ticker<-c('AAPL','MSFT','AMZN','TSLA','GOOGL','GOOG','BRK-B','NVDA','UNH','FB')
n <- length(ticker)

cours_bours<- function(){
  for (i in 1:n){
        prices <- get.hist.quote(instrument=ticker[i], start="2009-12-01",
                                      end="2020-02-01", quote="AdjClose",
                                      provider="yahoo", origin="2000-09-01",
                                      compression="m", ret)
        
        dimnames(prices)[[2]] <- as.character(ticker[i])
        
        index(prices) <- as.yearmon(index(prices))
        
        print(prices)
  }
}

cours_bours()

What I get as a result is a column with all time series of the 3 shares. I would like to have them all in 3 columns as:

Date              AAPL     MSFT    GOOG ....

2015-xx-xx      xx.xx    xx.xx   xx.xx  ....

CodePudding user response:

First let's redefine your function and avoid the for-loop:

func_cb <- function(ticker) {
  my_list <- lapply(ticker,
                    function(i) 
                      tseries::get.hist.quote(
                        instrument = i, 
                        start = "2009-12-01",
                        end = "2020-02-01", 
                        quote = "AdjClose",
                        provider = "yahoo", 
                        origin = "2000-09-01",
                        compression = "m", 
                        retclass = "zoo"
                        )
                    )
  
  names(my_list) <- ticker
  
  return(my_list)
}

Now this function takes a ticker vector as input and returns a list.

ticker <- c('AAPL','MSFT','AMZN','TSLA','GOOGL','GOOG','BRK-B','NVDA','UNH','FB')

my_ts_list <- func_cb(ticker)

Next we use tidyverse to reshape the list into your expected output:

library(tidyverse)

my_ts_list %>% 
  map_dfr(~.x %>% 
            as.data.frame() %>% 
            rownames_to_column(var = "date"),
          .id = "name") %>% 
  pivot_wider(names_from = "name", values_from = "Adjusted")

This returns

# A tibble: 122 x 11
   date        AAPL  MSFT  AMZN  TSLA GOOGL  GOOG `BRK-B`  NVDA   UNH    FB
   <chr>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl>
 1 2009-12-01  6.44  23.5  135. NA     310.  309.    65.7  4.29  25.4    NA
 2 2010-01-01  5.87  21.7  125. NA     265.  264.    76.4  3.53  27.5    NA
 3 2010-02-01  6.26  22.1  118. NA     264.  262.    80.1  3.72  28.2    NA
 4 2010-03-01  7.19  22.7  136. NA     284.  283.    81.3  4.00  27.2    NA
 5 2010-04-01  7.98  23.6  137. NA     263.  262.    77    3.61  25.2    NA
 6 2010-05-01  7.86  20.0  125. NA     243.  242.    70.6  3.02  24.2    NA
 7 2010-06-01  7.69  17.9  109. NA     223.  222.    79.7  2.34  23.7    NA
 8 2010-07-01  7.87  20.1  118.  3.99  243.  242.    78.1  2.11  25.5    NA
 9 2010-08-01  7.43  18.3  125.  3.90  225.  224.    78.8  2.14  26.5    NA
10 2010-09-01  8.68  19.2  157.  4.08  263.  262.    82.7  2.68  29.4    NA
# ... with 112 more rows

CodePudding user response:

Use Map to create the list L of zoo objects and then use merge.zoo to merge them into a single zoo object. Finally convert the index to yearmon giving the z.ym zoo object. Optionally use fortify.zoo(z.ym) if you need a data frame.

library(tseries)
library(zoo)
  
ticker<-c('AAPL','MSFT','AMZN')
L  <- Map(get.hist.quote, ticker, start="2009-12-01", end="2020-02-01", 
  quote="AdjClose", provider="yahoo", origin="2000-09-01", compression="m", 
  ret)
z <- setNames(do.call("merge", L), ticker)
z.ym <- aggregate(z, as.yearmon, c)

head(z.ym)
##              AAPL     MSFT   AMZN
## Dec 2009 6.444381 23.49339 134.52
## Jan 2010 5.873429 21.72060 125.41
## Feb 2010 6.257530 22.09828 118.40
## Mar 2010 7.186586 22.68174 135.77
## Apr 2010 7.984454 23.64972 137.10
## May 2010 7.855704 19.97913 125.46

Alternately express this as a pipeline:

clean_names <- function(x) setNames(x, sub("Adjusted.", "", names(x)))
out <- ticker |>
  Map(f = get.hist.quote, start="2009-12-01", end="2020-02-01", quote="AdjClose", 
    provider="yahoo", origin="2000-09-01", compression="m", ret) |>
  do.call(what = "merge") |>
  clean_names() |>
  aggregate(as.yearmon, c)
  •  Tags:  
  • r
  • Related