From b9eb8ca50eaab205df0f8765ac47d35b59106e9d Mon Sep 17 00:00:00 2001 From: Matt Dancho Date: Mon, 2 Sep 2024 11:02:07 -0400 Subject: [PATCH] #250 tq_fund_holdings() --- NAMESPACE | 2 + NEWS.md | 9 +++- R/tq_stock_list.R | 122 +++++++++++++++++++++++++++++++++++++++++----- _pkgdown.yml | 1 + man/tq_index.Rd | 35 +++++++++++-- 5 files changed, 153 insertions(+), 16 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 00b90f3d..0c8d97bf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -162,6 +162,8 @@ export(tidyquant_conflicts) export(tiingo_api_key) export(tq_exchange) export(tq_exchange_options) +export(tq_fund_holdings) +export(tq_fund_source_options) export(tq_get) export(tq_get_options) export(tq_index) diff --git a/NEWS.md b/NEWS.md index 1f97ba9b..f077ee5d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,12 @@ # tidyquant 1.0.9 -- Fixes to CRAN's API policy: +## New Function: + +- `tq_fund_holdings()`: Retrieves the fund holdings and compositions for a fund and source combination. Example: `tq_fund_holdings("SPY", source = "SSGA")` #250 + +## Fixes and Improvements: + +- Fixes to CRAN's API policy #249: > "Packages which use Internet resources should fail gracefully with an informative message if the resource is not available or has changed (and @@ -8,6 +14,7 @@ not give a check warning nor error)." + # tidyquant 1.0.8 ## TQ INDEX AND EXCHANGE: diff --git a/R/tq_stock_list.R b/R/tq_stock_list.R index fca784e0..45cb968c 100644 --- a/R/tq_stock_list.R +++ b/R/tq_stock_list.R @@ -22,12 +22,21 @@ #' `tq_exchange_options()` returns a list of stock exchanges you can #' choose from. The options are AMEX, NASDAQ and NYSE. #' +#' `tq_fund_holdings()` returns the the stock symbol, company name, weight, and sector of every stock +#' in an fund. The `source` parameter specifies which investment management company to use. +#' Example: `source = "SSGA"` connects to State Street Global Advisors (SSGA). +#' If `x = "SPY"`, then SPDR SPY ETF holdings will be returned. +#' +#' `tq_fund_source_options()`: returns the options that can be used for the `source` API for `tq_fund_holdings()`. +#' #' @seealso #' [tq_get()] to get stock prices, financials, key stats, etc using the stock symbols. #' #' #' @examples #' +#' # Stock Indexes: +#' #' # Get the list of stock index options #' tq_index_options() #' @@ -36,6 +45,8 @@ #' tq_index("DOW") #' } #' +#' # Stock Exchanges: +#' #' # Get the list of stock exchange options #' tq_exchange_options() #' @@ -44,6 +55,16 @@ #' tq_exchange("NYSE") #' } #' +#' # Mutual Funds and ETFs: +#' +#' # Get the list of stock exchange options +#' tq_fund_source_options() +#' +#' # Get all stocks in a fund +#' \dontrun{ +#' tq_fund_holdings("SPY", source = "SSGA") +#' } +#' #' @name tq_index #' @export @@ -95,7 +116,7 @@ tq_index <- function(x, use_fallback = FALSE) { # Download the index data dload <- tryCatch({ - index_download(x_spdr, index_name = x) + ssga_download(x_spdr, index_name = x) }, error = function(e) { warning(paste("Error downloading index data:", e$message), call. = FALSE) return(NULL) @@ -118,6 +139,18 @@ tq_index <- function(x, use_fallback = FALSE) { df } +#' @rdname tq_index +#' @export +tq_index_options <- function() { + c( + "DOW", + "DOWGLOBAL", + "SP400", + "SP500", + "SP600" + ) +} + # tq_exchange ---- @@ -215,21 +248,69 @@ tq_exchange <- function(x) { #' @rdname tq_index #' @export -tq_index_options <- function() { - c( - "DOW", - "DOWGLOBAL", - "SP400", - "SP500", - "SP600" - ) +tq_exchange_options <- function() { + c("AMEX", "NASDAQ", "NYSE") } +# tq_fund_holdings ---- #' @rdname tq_index +#' @param source The API source to use. #' @export -tq_exchange_options <- function() { - c("AMEX", "NASDAQ", "NYSE") +tq_fund_holdings <- function(x, source = "SSGA") { + + # Verify index + verified <- tryCatch({ + verify_fund_source(source) + }, error = function(e) { + warning(paste("Error verifying index:", e$message), call. = FALSE) + return(NULL) + }) + + # 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()) + } + + # Download the index data + dload <- tryCatch({ + source <- stringr::str_to_upper(source) + + if (source == "SSGA") { + ssga_download(x, index_name = x) + } else { + + } + + + }, 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 <- tryCatch({ + clean_holdings(dload$df) + }, error = function(e) { + warning(paste("Error cleaning index holdings:", e$message), call. = FALSE) + return(tibble::tibble()) + }) + + df + +} + +#' @rdname tq_index +#' @export +tq_fund_source_options <- function() { + c("SSGA") } # Utility ---------------------------------------------------------------------------------------------------- @@ -261,6 +342,23 @@ verify_index <- function(x) { verified } +verify_fund_source <- function(x) { + + # Setup with initial values + verified <- list(is_verified = FALSE, err = "") + + if(!(x %in% tq_fund_source_options())) { + + verified$err <- paste0(x, " must be a character string in the form of a valid Fund Source. ", + "The following are valid options:\n", + stringr::str_c(tq_fund_source_options(), collapse = ", ")) + } else { + verified$is_verified <- TRUE + } + + verified +} + # Map the index to the SPDR ETF name spdr_mapper <- function(x) { @@ -281,7 +379,7 @@ spdr_mapper <- function(x) { } # Download the index data from SPDR -index_download <- function(x, index_name) { +ssga_download <- function(x, index_name) { # Contruct download link # OLD (< 2019-12-15): https://us.spdrs.com/site-content/xls/SPY_All_Holdings.xls diff --git a/_pkgdown.yml b/_pkgdown.yml index f4651231..2782dd15 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -49,6 +49,7 @@ reference: - starts_with("tq_get") - starts_with("tq_index") - starts_with("tq_exchange") + - starts_with("tq_fund") - subtitle: API Keys contents: - starts_with("quandl") diff --git a/man/tq_index.Rd b/man/tq_index.Rd index e2e7b6b8..f412ba16 100644 --- a/man/tq_index.Rd +++ b/man/tq_index.Rd @@ -2,18 +2,24 @@ % Please edit documentation in R/tq_stock_list.R \name{tq_index} \alias{tq_index} -\alias{tq_exchange} \alias{tq_index_options} +\alias{tq_exchange} \alias{tq_exchange_options} +\alias{tq_fund_holdings} +\alias{tq_fund_source_options} \title{Get all stocks in a stock index or stock exchange in \code{tibble} format} \usage{ tq_index(x, use_fallback = FALSE) -tq_exchange(x) - tq_index_options() +tq_exchange(x) + tq_exchange_options() + +tq_fund_holdings(x, source = "SSGA") + +tq_fund_source_options() } \arguments{ \item{x}{A single character string, a character vector or tibble representing a @@ -22,6 +28,8 @@ single stock index or multiple stock indexes.} \item{use_fallback}{A boolean that can be used to return a fallback data set last downloaded when the package was updated. Useful if the website is down. Set to \code{FALSE} by default.} + +\item{source}{The API source to use.} } \value{ Returns data in the form of a \code{tibble} object. @@ -42,9 +50,18 @@ in an exchange. Three stock exchanges are available (AMEX, NASDAQ, and NYSE). \code{tq_exchange_options()} returns a list of stock exchanges you can choose from. The options are AMEX, NASDAQ and NYSE. + +\code{tq_fund_holdings()} returns the the stock symbol, company name, weight, and sector of every stock +in an fund. The \code{source} parameter specifies which investment management company to use. +Example: \code{source = "SSGA"} connects to State Street Global Advisors (SSGA). +If \code{x = "SPY"}, then SPDR SPY ETF holdings will be returned. + +\code{tq_fund_source_options()}: returns the options that can be used for the \code{source} API for \code{tq_fund_holdings()}. } \examples{ +# Stock Indexes: + # Get the list of stock index options tq_index_options() @@ -53,6 +70,8 @@ tq_index_options() tq_index("DOW") } +# Stock Exchanges: + # Get the list of stock exchange options tq_exchange_options() @@ -61,6 +80,16 @@ tq_exchange_options() tq_exchange("NYSE") } +# Mutual Funds and ETFs: + +# Get the list of stock exchange options +tq_fund_source_options() + +# Get all stocks in a fund +\dontrun{ +tq_fund_holdings("SPY", source = "SSGA") +} + } \seealso{ \code{\link[=tq_get]{tq_get()}} to get stock prices, financials, key stats, etc using the stock symbols.