---
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")
```
