--- title: "How-to xts" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{How-to xts} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` This vignette demonstrates the step-by-step `FFdownload()` workflow — browse available datasets, download, and process separately — using `xts` as the output format. This separation is valuable for reproducible research: you can save a dated snapshot of the raw zip files and re-process them at any time without re-downloading. For a simpler one-step approach (especially for interactive use), see `vignette("FFD-tibble-how-to")` and the `FFget()` function. ```{r setup, eval=TRUE, echo=FALSE, warning=FALSE, message=FALSE} library(FFdownload) outd <- paste0(tempdir(),"/",format(Sys.time(), "%F_%H-%M")) outfile <- paste0(outd,"FFData_xts.RData") listfile <- paste0(outd,"FFList.txt") ``` ```{r setup2, eval=FALSE, echo=TRUE} library(FFdownload) outd <- paste0("data/", format(Sys.time(), "%F_%H-%M")) outfile <- paste0(outd, "FFData_xts.RData") listfile <- paste0(outd, "FFList.txt") ``` ## Step 1: Browse available datasets ### Option A — `FFlist()` (recommended, new in v1.2.0) `FFlist()` returns a tidy data frame that you can filter directly: ```{r xts_fflist, eval=FALSE} fl <- FFlist(exclude_daily = TRUE) nrow(fl) # 100+ non-daily datasets head(fl) # Filter with dplyr library(dplyr) fl |> filter(grepl("Momentum|Reversal|5_Factors", name)) ``` ### Option B — `listsave` (classic approach, still supported) ```{r xts_list_save} FFdownload(exclude_daily=TRUE, download=FALSE, download_only=TRUE, listsave=listfile) read.delim(listfile, sep=",")[c(1:4, 73:74), ] ``` ### Verifying your search strings with `FFmatch()` Before downloading, use `FFmatch()` to confirm that your (partial) names map to the datasets you intend: ```{r xts_ffmatch, eval=FALSE} FFmatch(c("F-F_Research_Data_Factors_CSV", "F-F_Momentum_Factor_CSV")) ``` ## Step 2: Download selected datasets ```{r xts_download} inputlist <- c("F-F_Research_Data_Factors_CSV","F-F_Momentum_Factor_CSV") FFdownload(exclude_daily=TRUE, tempd=outd, download=TRUE, download_only=TRUE, inputlist=inputlist) list.files(outd) ``` The `action` parameter (new in v1.2.0) is equivalent and more readable: ```{r xts_download_action, eval=FALSE} FFdownload(exclude_daily=TRUE, tempd=outd, action="download_only", inputlist=inputlist) ``` The `cache_days` parameter prevents re-downloading files that are already fresh: ```{r xts_download_cache, eval=FALSE} # Reuse any cached file younger than 7 days; only download if stale FFdownload(exclude_daily=TRUE, tempd=outd, action="download_only", inputlist=inputlist, cache_days=7) ``` ## Step 3: Process downloaded files ```{r xts_processing} FFdownload(exclude_daily=TRUE, tempd=outd, download=FALSE, download_only=FALSE, inputlist=inputlist, output_file=outfile) ``` To also get the data back directly (skipping a separate `load()` call), add `return_data=TRUE`: ```{r xts_return_data, eval=FALSE} FFdata <- FFdownload(exclude_daily=TRUE, tempd=outd, download=FALSE, download_only=FALSE, inputlist=inputlist, output_file=outfile, return_data=TRUE) ``` To replace French's missing-value sentinels (`-99`, `-999`, `-99.99`) with `NA` during processing: ```{r xts_na_values, eval=FALSE} FFdownload(exclude_daily=TRUE, tempd=outd, download=FALSE, download_only=FALSE, inputlist=inputlist, output_file=outfile, na_values=c(-99, -999, -99.99)) ``` ## Step 4: Inspect the result ```{r xts_load} load(outfile) ls.str(FFdata) ``` The output is a named list. Each element corresponds to one dataset and contains three sub-lists: `$monthly`, `$annual`, and `$daily`. Within each sub-list, sub-tables are named after the section headings in French's CSV. When a section has no heading the name defaults to `Temp1`, `Temp2`, etc. — in factor files the main returns table is always `Temp2`. ```{r xts_names, eval=FALSE} # Discover sub-table names for the factors dataset names(FFdata[["x_F-F_Research_Data_Factors"]]$monthly) #> [1] "Temp2" names(FFdata[["x_F-F_Research_Data_Factors"]]$annual) #> [1] "annual_factors:_january-december" ``` ## Step 5: Use the data Code below merges all monthly `xts` objects, trims to post-1963, and plots cumulative wealth indices (credit: Joshua Ulrich): ```{r xts_process, eval=FALSE, echo=TRUE} monthly <- do.call(merge, lapply(FFdata, function(i) i$monthly$Temp2)) monthly_1963 <- na.omit(monthly)["1963/"] monthly_returns <- cumprod(1 + monthly_1963 / 100) - 1 plot(monthly_returns) ``` ```{r xts_process2, eval=TRUE, echo=FALSE, out.width="100%", fig.width=8, fig.height=4} monthly <- do.call(merge, lapply(FFdata, function(i) i$monthly$Temp2)) monthly_1963 <- na.omit(monthly)["1963/"] monthly_returns <- cumprod(1 + monthly_1963 / 100) - 1 plot(monthly_returns, col=viridis::viridis(5, direction=-1), legend.loc="topleft", lwd=2, main="Fama-French & Carhart Factor Wealth Index") ```