4

I have looked far and wide for a solution to this issue, but I cannot seem to figure it out. I do not have much experience working with xts objects in R.

I have 40 xts objects (ETF data) and I want to run the quantmod function WeeklyReturn on each of them individually.

I have tried to refer to them by using the ls() function:

lapply(ls(), weeklyReturn) 

I have also tried the object() function

lapply(object(), weeklyReturn)

I have also tried using as.xts() in my call to coerce the ls() objects to be used as xts but to no avail.

How can I run this function on every xts object in the environment?

Thank you,

Jared Marks
  • 948
  • 8
  • 15

2 Answers2

9

It would be better to load all of your xts objects into a list or create them in a way that returns them in a list to begin with. Then you could do results = lapply(xts.list, weeklyReturn).

To work with objects in the global environment, you could test for whether the object is an xts object and then run weeklyReturn on it if it is. Something like this:

results = lapply(setNames(ls(), ls()), function(i) {
  x = get(i)
  if(is.xts(x)) {
    weeklyReturn(x)
  }
})

results = results[!sapply(results, is.null)]

Or you could select only the xts objects to begin with:

results = sapply(ls()[sapply(ls(), function(i) is.xts(get(i)))],
       function(i) weeklyReturn(get(i)), simplify=FALSE, USE.NAMES=TRUE)

lapply(ls(), weeklyReturn) doesn't work, because ls() returns the object names as strings. The get function takes a string as an argument and returns the object with that name.

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • Like I commented, you mean? ;-) – RobertMyles Jun 22 '17 at 19:27
  • @ChiPak It's a fine answer, there's no problem with that, but I've seen people forced to delete answers when they turned somebody's comment into an answer without crediting the comment, or mentioning it at least. Anyway. – RobertMyles Jun 22 '17 at 19:39
  • @RobertMc: We commented at about the same time (I was a few seconds behind you). I expanded my comment into an answer and then deleted my comment. If it's really that important to you, please add your own answer and I'll delete mine. – eipi10 Jun 22 '17 at 19:40
  • No one really cares about fake internet points. RobertMc is just teasing...I only upvoted eipi10 because you expanded on your answer, which could be more helpful to OP – CPak Jun 22 '17 at 19:41
  • 1
    @ChiPak haha, it's because I'm 20-odd points away from seeing review queues and I'm curious! – RobertMyles Jun 22 '17 at 19:42
  • @RobertMc considering how often I see you contribute, you'll get there in no time. – CPak Jun 22 '17 at 19:43
2

An alternate solution using the tidyquant package. Note that this is data frame based so I will not be working with xts objects. I use two core functions to scale the analysis. First, tq_get() is used to go from a vector of ETF symbols to getting the prices. Second, tq_transmute() is used to apply the weeklyReturn function to the adjusted prices.


library(tidyquant)

etf_vec <- c("SPY", "QEFA", "TOTL", "GLD")

# Use tq_get to get prices
etf_prices <- tq_get(etf_vec, get = "stock.prices", from = "2017-01-01", to = "2017-05-31")
etf_prices
#> # A tibble: 408 x 8
#>    symbol       date    open    high     low  close   volume adjusted
#>     <chr>     <date>   <dbl>   <dbl>   <dbl>  <dbl>    <dbl>    <dbl>
#>  1    SPY 2017-01-03 227.121 227.919 225.951 225.24 91366500 223.1760
#>  2    SPY 2017-01-04 227.707 228.847 227.696 226.58 78744400 224.5037
#>  3    SPY 2017-01-05 228.363 228.675 227.565 226.40 78379000 224.3254
#>  4    SPY 2017-01-06 228.625 229.856 227.989 227.21 71559900 225.1280
#>  5    SPY 2017-01-09 229.009 229.170 228.514 226.46 46265300 224.3848
#>  6    SPY 2017-01-10 228.575 229.554 228.100 226.46 63771900 224.3848
#>  7    SPY 2017-01-11 228.453 229.200 227.676 227.10 74650000 225.0190
#>  8    SPY 2017-01-12 228.595 228.847 227.040 226.53 72113200 224.4542
#>  9    SPY 2017-01-13 228.827 229.503 228.786 227.05 62717900 224.9694
#> 10    SPY 2017-01-17 228.403 228.877 227.888 226.25 61240800 224.1767
#> # ... with 398 more rows

# Use tq_transmute to apply weeklyReturn to multiple groups
etf_returns_w <- etf_prices %>%
    group_by(symbol) %>%
    tq_transmute(select = adjusted, mutate_fun = weeklyReturn)
etf_returns_w
#> # A tibble: 88 x 3
#> # Groups:   symbol [4]
#>    symbol       date weekly.returns
#>     <chr>     <date>          <dbl>
#>  1    SPY 2017-01-06   0.0087462358
#>  2    SPY 2017-01-13  -0.0007042173
#>  3    SPY 2017-01-20  -0.0013653367
#>  4    SPY 2017-01-27   0.0098350474
#>  5    SPY 2017-02-03   0.0016159256
#>  6    SPY 2017-02-10   0.0094619381
#>  7    SPY 2017-02-17   0.0154636969
#>  8    SPY 2017-02-24   0.0070186222
#>  9    SPY 2017-03-03   0.0070964211
#> 10    SPY 2017-03-10  -0.0030618336
#> # ... with 78 more rows
Matt Dancho
  • 6,840
  • 3
  • 35
  • 26