Skip to content

Commit

Permalink
Use JSON API in getSplits() and getDividends()
Browse files Browse the repository at this point in the history
These functions were not updated when the v7 (CSV) API was removed
(see #362).

Fixes #364.
  • Loading branch information
joshuaulrich committed Jun 12, 2022
1 parent f62ee26 commit 085032f
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 26 deletions.
37 changes: 25 additions & 12 deletions R/getDividends.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,39 @@ function(Symbol,from='1970-01-01',to=Sys.Date(),env=parent.frame(),src='yahoo',
to.posix <- .dateToUNIX(to)

handle <- .getHandle()
yahoo.URL <- .yahooURL(Symbol.name, from.posix, to.posix, "1d", "div")
yahoo.URL <- .yahooJsonURL(Symbol.name, from.posix, to.posix, "3mo")
yahoo.URL <- paste0(yahoo.URL, "&events=div|splits")

conn <- curl::curl(yahoo.URL,handle=handle)
fr <- try(read.csv(conn, as.is=TRUE), silent = TRUE)
json <- try(jsonlite::fromJSON(conn, simplifyVector = FALSE)$chart$result, silent = TRUE)
div.events <- json[[1]][["events"]][["dividends"]]

if (inherits(fr, "try-error")) {
fr <- retry.yahoo(Symbol.name, from.posix, to.posix, "1d", "div", conn)
}
if(length(div.events) > 0) {
div.to.xts <- function(x) {
xts(x$amount, as.Date(.POSIXct(x$date, "UTC")))
}
# dividends from Yahoo are split-adjusted
divs <- do.call(rbind, lapply(div.events, div.to.xts))

fr <- xts(fr[,2],as.Date(fr[,1]))
colnames(fr) <- paste(Symbol.name,'div',sep='.')
split.events <- json[[1]][["events"]][["splits"]]
if(!split.adjust || length(split.events) == 0) {
# un-adjust dividends for splits
spl.to.xts <- function(x) {
ratio <- x$numerator/x$denominator
xts(ratio, as.Date(.POSIXct(x$date, "UTC")))
}
splits <- do.call(rbind, lapply(split.events, spl.to.xts))

# dividends from Yahoo are not split-adjusted
if(src[1] == "yahoo" && split.adjust) {
splits <- getSplits(Symbol.name, from="1900-01-01")
if(is.xts(splits) && is.xts(fr) && nrow(splits) > 0 && nrow(fr) > 0) {
fr <- fr * adjRatios(splits=merge(splits, index(fr)))[,1]
divs <- divs * adjRatios(splits=merge(splits, index(divs)))[,1]
}

fr <- divs
} else {
fr <- xts(numeric(0), .Date(integer(0)))
}

colnames(fr) <- paste(Symbol.name,'div',sep='.')

if(is.xts(tmp.symbol)) {
if(auto.update) {
xtsAttributes(tmp.symbol) <- list(dividends=fr)
Expand Down
29 changes: 18 additions & 11 deletions R/getSplits.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,30 @@ function(Symbol,from='1970-01-01',to=Sys.Date(),env=parent.frame(),src='yahoo',
to.posix <- .dateToUNIX(to)

handle <- .getHandle()
yahoo.URL <- .yahooURL(Symbol.name, from.posix, to.posix, "1d", "split")
yahoo.URL <- .yahooJsonURL(Symbol.name, from.posix, to.posix, "3mo")
yahoo.URL <- paste0(yahoo.URL, "&events=splits")

conn <- curl::curl(yahoo.URL, handle=handle)
fr <- try(read.csv(conn, as.is=TRUE), silent=TRUE)
conn <- curl::curl(yahoo.URL,handle=handle)
json <- try(jsonlite::fromJSON(conn, simplifyVector = FALSE)$chart$result, silent = TRUE)

if (inherits(fr, "try-error")) {
fr <- retry.yahoo(Symbol.name, from.posix, to.posix, "1d", "split", conn)
if(inherits(json, "try-error")) {
msg <- paste0("Unable to import splits for", Symmbol.name,
".\n", attr(test, "condition")$message)
stop(msg)
}

if(NROW(fr)==0) {
fr <- NA
split.events <- json[[1]][["events"]][["splits"]]

if(length(split.events) > 0) {
to.xts <- function(x) {
ratio <- x$numerator/x$denominator
xts(ratio, as.Date(.POSIXct(x$date, "UTC")))
}
fr <- 1 / do.call(rbind, lapply(split.events, to.xts))
} else {
fr[,2] <- gsub(":", "/", fr[,2], fixed = TRUE)
fr$V3 <- 1 / vapply(parse(text=fr[,2]), eval, numeric(1))
fr <- xts(fr$V3, as.Date(fr[,1], "%Y-%m-%d"))
colnames(fr) <- paste(Symbol.name,'spl',sep='.')
fr <- xts(numeric(0), .Date(integer(0)))
}
colnames(fr) <- paste(Symbol.name,'spl',sep='.')

if(is.xts(tmp.symbol)) {
if(auto.update) {
Expand Down
6 changes: 3 additions & 3 deletions R/getSymbols.R
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,11 @@ formals(loadSymbols) <- loadSymbols.formals
}

.yahooJsonURL <-
function(symbol, from, to, period, type)
function(symbol, from, to, interval)
{
u <- paste0("https://query2.finance.yahoo.com/v8/finance/chart/",
symbol, sprintf("?period1=%.0f&period2=%.0f", from, to),
"&interval=1d")
symbol,
sprintf("?period1=%.0f&period2=%.0f&interval=%s", from, to, interval))
return(u)
}

Expand Down

0 comments on commit 085032f

Please sign in to comment.