Skip to content

Commit

Permalink
Handle download errors in getDividends & getSplits
Browse files Browse the repository at this point in the history
We fixed this issue in getSymbols() in #307. Basically, the curl
connection and/or download may fail for one symbol, and we don't want
to throw an error and stop processing all subsequent symbols.

Create a new retry.yahoo() function that throws the warning about the
first download failing, then reconstructs the URL and tries the download
again. It throws an error if the second download fails, like it did for
getSymbols().

Fixes #314.
  • Loading branch information
joshuaulrich committed Oct 27, 2020
1 parent 4ebd1cb commit af6fa37
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 23 deletions.
11 changes: 9 additions & 2 deletions R/getDividends.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
`getDividends` <-
function(Symbol,from='1970-01-01',to=Sys.Date(),env=parent.frame(),src='yahoo',
auto.assign=FALSE,auto.update=FALSE,verbose=FALSE,split.adjust=TRUE,...) {
auto.assign=FALSE,auto.update=FALSE,verbose=FALSE,split.adjust=TRUE,...,
curl.options=list()) {

if(missing(env))
env <- parent.frame(1)
Expand All @@ -17,7 +18,13 @@ function(Symbol,from='1970-01-01',to=Sys.Date(),env=parent.frame(),src='yahoo',
yahoo.URL <- .yahooURL(Symbol.name, from.posix, to.posix,
"1d", "div", handle)

fr <- read.csv(curl::curl(yahoo.URL,handle=handle$ch))
conn <- curl::curl(yahoo.URL,handle=handle$ch)
fr <- try(read.csv(conn, as.is=TRUE), silent = TRUE)

if (inherits(fr, "try-error")) {
fr <- retry.yahoo(Symbol.name, from.posix, to.posix, "1d", "div", conn)
}

fr <- xts(fr[,2],as.Date(fr[,1]))
colnames(fr) <- paste(Symbol.name,'div',sep='.')

Expand Down
10 changes: 8 additions & 2 deletions R/getSplits.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
`getSplits` <-
function(Symbol,from='1970-01-01',to=Sys.Date(),env=parent.frame(),src='yahoo',
auto.assign=FALSE,auto.update=FALSE,verbose=FALSE,...) {
auto.assign=FALSE,auto.update=FALSE,verbose=FALSE,...,
curl.options=list()) {

# Function written by Joshua Ulrich, using
# getSymbols.yahoo as a guide.
Expand All @@ -19,7 +20,12 @@ function(Symbol,from='1970-01-01',to=Sys.Date(),env=parent.frame(),src='yahoo',
yahoo.URL <- .yahooURL(Symbol.name, from.posix, to.posix,
"1d", "split", handle)

fr <- read.csv(curl::curl(yahoo.URL, handle=handle$ch), as.is=TRUE)
conn <- curl::curl(yahoo.URL, handle=handle$ch)
fr <- try(read.csv(conn, as.is=TRUE), silent=TRUE)

if (inherits(fr, "try-error")) {
fr <- retry.yahoo(Symbol.name, from.posix, to.posix, "1d", "split", conn)
}

if(NROW(fr)==0) {
fr <- NA
Expand Down
20 changes: 3 additions & 17 deletions R/getSymbols.R
Original file line number Diff line number Diff line change
Expand Up @@ -338,23 +338,9 @@ function(Symbols,env,return.class='xts',index.class="Date",
fr <- try(read.csv(conn, na.strings="null"), silent = TRUE)

if (inherits(fr, "try-error")) {
# warn user about the failure
warning(Symbols.name, " download failed; trying again.",
call. = FALSE, immediate. = TRUE)
# re-create handle
handle <- .getHandle(curl.options, force.new = TRUE)
# try again. must rebuild url with crumbs
yahoo.URL <- .yahooURL(Symbols.name, from.posix, to.posix,
interval, "history", handle)
close(conn)
conn <- curl::curl(yahoo.URL, handle = handle$ch)
fr <- try(read.csv(conn, na.strings="null"), silent = TRUE)
# error if second attempt also failed
if (inherits(fr, "try-error")) {
close(conn)
stop(Symbols.name, " download failed after two attempts. Error",
" message:\n", attr(fr, "condition")$message, call. = FALSE)
}
fr <- retry.yahoo(Symbols.name, from.posix, to.posix, interval,
"history", curl.options = curl.options,
na.strings = NULL)
}

if(verbose) cat("done.\n")
Expand Down
35 changes: 35 additions & 0 deletions R/tools.R
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,38 @@ function(url, destfile, method, quiet = FALSE, mode = "w", cacheOK = TRUE,
}
}
}

retry.yahoo <-
function(symbol,
from,
to,
interval,
type,
conn,
...,
curl.options = list())
{
warning(symbol, " download failed; trying again.",
call. = FALSE, immediate. = TRUE)

# re-create handle
handle <- .getHandle(curl.options, force.new = TRUE)

# try again. must rebuild url with crumbs
yahoo.URL <- .yahooURL(symbol, from, to, interval, type, handle)

close(conn)
conn <- curl::curl(yahoo.URL, handle = handle$ch)

fr <- try(read.csv(conn, ..., as.is = TRUE), silent = TRUE)

# error if second attempt also failed
if (inherits(fr, "try-error")) {
close(conn)
stop(symbol, " download failed after two attempts. Error",
" message:\n", attr(fr, "condition")$message, call. = FALSE)
}

# return data
return(fr)
}
5 changes: 4 additions & 1 deletion man/getDividends.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ getDividends(Symbol,
auto.assign = FALSE,
auto.update = FALSE,
verbose = FALSE,
split.adjust = TRUE, ...)
split.adjust = TRUE,
...,
curl.options = list())
}
%- maybe also 'usage' for other objects documented here.
\arguments{
Expand All @@ -29,6 +31,7 @@ getDividends(Symbol,
\item{split.adjust}{ adjust dividends for splits (\code{TRUE} by default
because that's what Yahoo returns)}
\item{\dots}{ currently unused }
\item{curl.options}{ options passed to \code{curl::curl} }
}
\details{
Eventually destined to be a wrapper function along the lines
Expand Down
5 changes: 4 additions & 1 deletion man/getSplits.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ getSplits(Symbol,
src = "yahoo",
auto.assign = FALSE,
auto.update = FALSE,
verbose = FALSE, ...)
verbose = FALSE,
...,
curl.options = list())
}
%- maybe also 'usage' for other objects documented here.
\arguments{
Expand All @@ -26,6 +28,7 @@ getSplits(Symbol,
\item{auto.update}{ automatically add split to data object }
\item{verbose}{ display status of retrieval }
\item{\dots}{ currently unused }
\item{curl.options}{ options passed to \code{curl::curl} }
}
\details{
Eventually destined to be a wrapper function along the lines
Expand Down

0 comments on commit af6fa37

Please sign in to comment.