Skip to content

Commit

Permalink
Fixes #249: CRAN API POLICY
Browse files Browse the repository at this point in the history
  • Loading branch information
mdancho84 committed Sep 2, 2024
1 parent cdf4aa1 commit 13402a0
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 608 deletions.
4 changes: 2 additions & 2 deletions CRAN-SUBMISSION
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Version: 1.0.8
Date: 2024-08-19 16:15:06 UTC
SHA: 4d3d65d0aa099dcd551cd6d145cc586d7cbf6990
Date: 2024-08-19 17:15:42 UTC
SHA: cdf4aa12dca23b11eb43b2d265656609025c9157
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: tidyquant
Type: Package
Title: Tidy Quantitative Financial Analysis
Version: 1.0.8
Version: 1.0.8.9000
Authors@R: c(
person("Matt", "Dancho", email = "[email protected]", role = c("aut", "cre")),
person("Davis", "Vaughan", email = "[email protected]", role = c("aut"))
Expand Down
10 changes: 9 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# tidyquant (development version)
# tidyquant 1.0.9

- Fixes to CRAN's API policy:

> "Packages which use Internet resources should fail gracefully with an
informative message if the resource is not available or has changed (and
not give a check warning nor error)."



# tidyquant 1.0.8

Expand Down
595 changes: 57 additions & 538 deletions R/tq_get.R

Large diffs are not rendered by default.

160 changes: 102 additions & 58 deletions R/tq_stock_list.R
Original file line number Diff line number Diff line change
Expand Up @@ -57,35 +57,68 @@ tq_index <- function(x, use_fallback = FALSE) {
x <- clean_index(x)

# Verify index
verified <- verify_index(x)
verified <- tryCatch({
verify_index(x)
}, error = function(e) {
warning(paste("Error verifying index:", e$message), call. = FALSE)
return(NULL)
})

# If not a verified index, error
if(!verified$is_verified) {
# If verification failed or not a verified index, return a warning and empty tibble
if(is.null(verified) || !verified$is_verified) {
warning(verified$err)
return(tibble::tibble())
}

# Use fallback if requested
if(use_fallback) return(index_fallback(x))
if(use_fallback) {
return(tryCatch({
index_fallback(x)
}, error = function(e) {
warning(paste("Error using fallback for index:", e$message), call. = FALSE)
return(tibble::tibble())
}))
}

# Convert index name to SPDR ETF name
x_spdr <- spdr_mapper(x)
x_spdr <- tryCatch({
spdr_mapper(x)
}, error = function(e) {
warning(paste("Error mapping SPDR ETF name:", e$message), call. = FALSE)
return(NULL)
})

# Download
dload <- index_download(x_spdr, index_name = x)
# If SPDR mapping failed, return an empty tibble
if(is.null(x_spdr)) {
return(tibble::tibble())
}

# Report download errors
if(!is.null(dload$err)) {
# Download the index data
dload <- tryCatch({
index_download(x_spdr, index_name = x)
}, error = function(e) {
warning(paste("Error downloading index data:", e$message), call. = FALSE)
return(NULL)
})

# If download failed, return a warning and empty tibble
if(is.null(dload) || !is.null(dload$err)) {
warning(dload$err)
return(tibble::tibble())
}

# Clean holdings
df <- clean_holdings(dload$df)
df <- tryCatch({
clean_holdings(dload$df)
}, error = function(e) {
warning(paste("Error cleaning index holdings:", e$message), call. = FALSE)
return(tibble::tibble())
})

df
}


# tq_exchange ----

#' @rdname tq_index
Expand All @@ -104,71 +137,82 @@ tq_exchange <- function(x) {
if (!(x %in% c(exchange_list))) {
err <- paste0("Error: x must be a character string in the form of a valid exchange.",
" The following are valid options:\n",
stringr::str_c(tq_exchange_options(), collapse = ", ")
)
stop(err)
stringr::str_c(tq_exchange_options(), collapse = ", "))
stop(err, call. = FALSE)
}

# Download

# Example: https://api.nasdaq.com/api/screener/stocks?tableonly=true&exchange=nasdaq&download=true

# Download data
message("Getting data...\n")
base_path_1 <- "https://api.nasdaq.com/api/screener/stocks?tableonly=true&exchange="
base_path_2 <- "&download=true"
url <- paste0(base_path_1, x, base_path_2)
url <- paste0(base_path_1, x, base_path_2)

# Use HTTR2 to make the HTTP request:
response <- httr2::request(url) %>%
httr2::req_user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36") %>%
httr2::req_perform()
# Perform the HTTP request with error handling
response <- tryCatch({
httr2::request(url) %>%
httr2::req_user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36") %>%
httr2::req_perform()
}, error = function(e) {
warning(paste0("Failed to retrieve data for exchange '", x, "'. ", e$message), call. = FALSE)
return(NULL)
})

# Evaluate Response / Clean & Return
if (response$status_code == 200) {
# If the response is NULL (failed request), return NA
if (is.null(response)) {
return(NA)
}

# Collect JSON
# Evaluate the response
if (response$status_code == 200) {
# Collect JSON and process the data
content <- httr2::resp_body_json(response)

# Post-process response
suppressWarnings({

exchange_tbl <- do.call(rbind, lapply(content$data$rows, tibble::as_tibble))

exchange <- exchange_tbl %>%
dplyr::rename(
symbol = symbol,
company = name,
last.sale.price = lastsale,
market.cap = marketCap,
country = country,
ipo.year = ipoyear,
sector = sector,
industry = industry
) %>%
dplyr::mutate(
symbol = as.character(symbol),
company = as.character(company),
last.sale.price = as.numeric(stringr::str_remove(last.sale.price, "\\$")),
market.cap = as.numeric(market.cap),
country = as.character(country),
ipo.year = as.integer(ipo.year),
sector = as.character(sector),
industry = as.character(industry)
) %>%
dplyr::select(symbol:industry) %>%
dplyr::select(-c(netchange, pctchange, volume))
exchange_tbl <- tryCatch({
do.call(rbind, lapply(content$data$rows, tibble::as_tibble))
}, error = function(e) {
warning("Failed to process data from the response.", call. = FALSE)
return(NULL)
})

# If the processing failed, return NA
if (is.null(exchange_tbl)) {
return(NA)
}

# Post-process and clean the data
exchange <- exchange_tbl %>%
dplyr::rename(
symbol = symbol,
company = name,
last.sale.price = lastsale,
market.cap = marketCap,
country = country,
ipo.year = ipoyear,
sector = sector,
industry = industry
) %>%
dplyr::mutate(
symbol = as.character(symbol),
company = as.character(company),
last.sale.price = as.numeric(stringr::str_remove(last.sale.price, "\\$")),
market.cap = as.numeric(market.cap),
country = as.character(country),
ipo.year = as.integer(ipo.year),
sector = as.character(sector),
industry = as.character(industry)
) %>%
dplyr::select(symbol:industry) %>%
dplyr::select(-c(netchange, pctchange, volume))

return(exchange)

} else {
warn <- paste0("Error at ", x, " during call to tq_exchange.\n\n", response)
warning(warn)
return(NA) # Return NA on error
warn <- paste0("Error retrieving data for exchange '", x, "'. Status code: ", response$status_code)
warning(warn, call. = FALSE)
return(NA)
}

}


#' @rdname tq_index
#' @export
tq_index_options <- function() {
Expand Down
2 changes: 1 addition & 1 deletion vignettes/TQ00-introduction-to-tidyquant.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ knitr::opts_chunk$set(message = FALSE,
fig.height = 4.5,
fig.align = 'center',
out.width='95%',
dpi = 200)
dpi = 150)
library(tidyquant)
library(lubridate)
Expand Down
16 changes: 13 additions & 3 deletions vignettes/TQ01-core-functions-in-tidyquant.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ knitr::opts_chunk$set(message = FALSE,
fig.height = 4.5,
fig.align = 'center',
out.width='95%',
dpi = 200)
dpi = 150)
```

> A few core functions with a lot of power
Expand Down Expand Up @@ -107,6 +107,16 @@ aapl_prices <- tq_get("AAPL", get = "stock.prices", from = " 1990-01-01")
aapl_prices
```

We can get multiple stocks:

```{r}
stocks <- c("AAPL", "META", "NFLX") %>%
tq_get(from = "2013-01-01",
to = "2017-01-01")
stocks
```


Yahoo Japan stock prices can be retrieved using a similar call, `get = "stock.prices.japan"`.

```{r, eval = F}
Expand Down Expand Up @@ -207,11 +217,11 @@ tq_get("ZACKS/SHRS", get = "quandl.datatable") # Zacks Shares Out Supplement

## 2.4 Tiingo API

The Tiingo API (https://www.tiingo.com/) is a free source for stock prices, cryptocurrencies, and intraday feeds from the IEX (Investors Exchange). This can serve as an alternate source of data to Yahoo! Finance.
The Tiingo API is a free source for stock prices, cryptocurrencies, and intraday feeds from the IEX (Investors Exchange). This can serve as an alternate source of data to Yahoo! Finance.

### Authentication

To make full use of the integration you need to get an API key and then set your api key. If you don't have one already, go to Tiingo (https://www.tiingo.com/) account and get your FREE API key. You can then set it as follows:
To make full use of the integration you need to get an API key and then set your api key. If you don't have one already, go to Tiingo account and get your FREE API key. You can then set it as follows:

```{r, eval=FALSE}
tiingo_api_key('<your-api-key>')
Expand Down
3 changes: 2 additions & 1 deletion vignettes/TQ02-quant-integrations-in-tidyquant.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ knitr::opts_chunk$set(message = FALSE,
fig.width = 8,
fig.height = 4.5,
fig.align = 'center',
out.width='95%')
out.width='95%',
dpi=150)
# devtools::load_all() # Travis CI fails on load_all()
```

Expand Down
2 changes: 1 addition & 1 deletion vignettes/TQ03-scaling-and-modeling-with-tidyquant.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ knitr::opts_chunk$set(message = FALSE,
fig.height = 4.5,
fig.align = 'center',
out.width='95%',
dpi = 200)
dpi = 150)
# devtools::load_all() # Travis CI fails on load_all()
```

Expand Down
3 changes: 2 additions & 1 deletion vignettes/TQ04-charting-with-tidyquant.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ knitr::opts_chunk$set(message = FALSE,
fig.width = 8,
fig.height = 4.5,
fig.align = 'center',
out.width='95%')
out.width='95%',
dpi=150)
# devtools::load_all() # Travis CI fails on load_all()
```

Expand Down
2 changes: 1 addition & 1 deletion vignettes/TQ05-performance-analysis-with-tidyquant.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ knitr::opts_chunk$set(message = FALSE,
fig.height = 4.5,
fig.align = 'center',
out.width='95%',
dpi = 200)
dpi = 150)
# devtools::load_all() # Travis CI fails on load_all()
```

Expand Down

0 comments on commit 13402a0

Please sign in to comment.