joshuaulrich / quantmod

Quantitative Financial Modelling Framework
http://www.quantmod.com/
GNU General Public License v3.0
794 stars 219 forks source link

Return a list when `auto.assign = TRUE` and there is more than 1 symbol #373

Open joshuaulrich opened 1 year ago

joshuaulrich commented 1 year ago

getSymbols() currently errors if you specify auto.assign = FALSE with more than one symbol.

Error in getSymbols(c("SPY", "AAPL"), auto.assign = FALSE) : 
  must use auto.assign = TRUE when reloading multiple Symbols

Instead of throwing an error, we can return a named list of xts objects. This will make it easier to avoid the side-effect of assigning to the calling environment without breaking any backward compatibility.

ethanbsmith commented 1 year ago

this will return different types based on the length of the output (list vs xts) would be nice to be able to have it always return a list, regardless of length

joshuaulrich commented 1 year ago

So getSymbols("SPY", auto.assign = FALSE) would return a list? That would break backward compatibility. Maybe leave getSymbols as-is and create an importSymbols() function that always returns a list?

ethanbsmith commented 1 year ago

just thinking out loud:

ideally, getSymbols​ would always return a list and getSymbol​ (singular) would wrap that with an unlist(), and auto.assign and env would get deprecated. if thats an agreed target state, (prolly a big if) whats the best interim approach?

  1. new get_Symbol/get_Symbols that implement new pattern. maybe turn existing getSymbols into a wrapper
  2. overload auto.assign​ to take T,F,"list". very ugly
  3. always return a list for auto.assign​ == FALSE, and implement new getSymbol()​ wrapper. def breaks back-compat, but slightly less ugly
  4. new argument simplify = TRUE, that controls whether to unlist() a single return value, when auto.assign == FALSE​​. doesn't break back-compat, but does add complexity to argument interaction and overall "intuitiveness" of the API

i'd prolly vote for something like 1 or 4

joshuaulrich commented 1 year ago

Thanks for your thoughts. Making getSymbols() always return a list would break a lot of code, so that's not an option.

I prefer (1) and I like the idea of a get_symbol() function that only works for a single symbol.