The goal of etfdata is to provide tools to fetch, clean, and store historical and metadata for European bond and equity index ETFs (UCITS) listed on the London Stock Exchange
Installation
You can install the development version of etfdata from GitHub with:
# install.packages("devtools")
devtools::install_github("JohnGavin/etf-data/etfdata")Example
This example demonstrates how to retrieve the ETF universe, fetch metadata (including AUM), filter for the largest funds, and visualize their price history.
library(etfdata)
library(dplyr)
library(ggplot2)
# 1. Get the universe of ETFs
universe <- get_etf_universe()
# 2. Fetch metadata (AUM, TER, etc.) for the first few ETFs to identify top funds
# (In a real scenario, you might fetch metadata for the whole universe)
sample_isins <- head(universe$isin, 5)
metadata <- fetch_etf_metadata(sample_isins)
# Join metadata to the universe subset
detailed_universe <- universe %>%
filter(isin %in% sample_isins) %>%
left_join(metadata, by = "isin")
print(detailed_universe)
# For demonstration, we'll assume we identified top tickers
top_tickers <- c("VUSA.L", "CSP1.L", "INRG.L", "EQQQ.L")
# 3. Fetch Price History for Top 4
history <- fetch_price_history(top_tickers)
# 4. Plot the performance
history %>%
ggplot(aes(x = date, y = close, color = ticker)) +
geom_line() +
facet_wrap(~ticker, scales = "free_y") +
labs(
title = "Price History of Top ETFs",
x = "Date",
y = "Close Price (GBP)"
) +
theme_minimal() +
theme(legend.position = "none")Example output (cached snapshot):
# A tibble: 5 x 6
ticker name isin currency aum_text ter_text
<chr> <chr> <chr> <chr> <chr> <chr>
1 VUSA.L Vanguard S&P 500 UCITS ETF IE00B3XXRP09 GBP GBP 36,957 m 0.07% p.a.
2 CSPX.L iShares Core S&P 500 UCITS ETF IE00B5BMR087 GBP GBP 98,470 m 0.07% p.a.
3 INRG.L iShares Global Clean Energy UCITS ETF IE00B1XNHC34 GBP GBP 1,889 m 0.65% p.a.
4 EQQQ.L Invesco EQQQ Nasdaq-100 UCITS ETF IE0032077012 GBP GBP 8,283 m 0.30% p.a.
5 VWRL.L Vanguard FTSE All-World UCITS ETF IE00B3RBWM25 GBP GBP 16,116 m 0.19% p.a.

JustETF Screener
You can also fetch a live list of ETFs directly from the JustETF screener API, allowing you to filter by AUM (Assets Under Management) and TER (Total Expense Ratio).
# Fetch ETFs with > £200m AUM and < 0.75% TER
screener_data <- fetch_justetf_screener(min_aum_gbp = 200, max_ter = 0.75)
print(head(screener_data))Example output (cached snapshot):
## WebR, CORS, and Cached Data
Browser builds cannot call JustETF or Yahoo Finance directly because the browser enforces cross-site request restrictions (CORS). To keep the WebR and Shinylive demos working, the project precomputes a full LSE ETF snapshot in CI using `targets` and stores it in:
- `inst/extdata/etf_universe_curated.csv` (manual universe list; edit to add/remove ETFs)
- `inst/extdata/etf_universe.csv`
- `inst/extdata/history_cache.rds`
- `inst/extdata/history_summary.rds`
- `inst/extdata/vignette_data.rds`
See `docs/wiki/ETF_Data_Sources.md` for the rationale, refresh steps, and alternative data sources. The cached data coverage summary is in the vignette `vignettes/data_snapshot.qmd` (published as `articles/data_snapshot.html`).
To refresh the snapshot locally (only missing dates/tickers are downloaded):
```r
setwd("etfdata")
targets::tar_make()
A tibble: 6 x 6
isin aum_text ter_text ticker name currency
## Reproducibility with Nix
This project is reproducible using [Nix](https://nixos.org/).
### Installation
We recommend the [Determinate Systems Nix Installer](https://github.com/DeterminateSystems/nix-installer):
```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh
Running
From the project root (etf-data), drop into a reproducible R environment with all dependencies:
Install the package into your user library inside the nix shell (once per shell):
Then run the examples (e.g. print the universe). Use one of the following options:
Option A: Load the package directly from source (no install step needed):
Rscript --vanilla -e 'devtools::load_all("etfdata"); packageVersion("etfdata"); str(get_etf_universe())'Option B: Use your custom library path explicitly:
R_LIBS_USER=$HOME/.Rlibs_etf Rscript --vanilla -e 'library(etfdata); packageVersion("etfdata"); str(get_etf_universe())'Note: devtools is included in the Nix development shell for convenience, but it is not a runtime dependency of the etfdata package.
Expected output:
[1] ‘0.0.0.9000’
tibble [20 × 4] (S3: tbl_df/tbl/data.frame)
$ ticker : chr [1:20] "VUSA.L" "CSPX.L" "INRG.L" "EQQQ.L" ...
$ name : chr [1:20] "Vanguard S&P 500 UCITS ETF" "iShares Core S&P 500 UCITS ETF" ...
$ isin : chr [1:20] "IE00B3XXRP09" "IE00B5BMR087" "IE00B1XNHC34" "IE0032077012" ...
$ currency: chr [1:20] "GBP" "GBP" "GBP" "GBP" ...