CoinGecko integration: a second source for crypto2

Why a second source?

crypto2 was built around CoinMarketCap (CMC). The cg_* functions are a second, independent source that returns tibbles with the same column conventions as the CMC functions, so research code that already consumes a crypto_* tibble works on a cg_* tibble too.

Three concrete reasons to bother with a second source:

This vignette focuses on how to actually pull a complete history out of CG for asset-pricing research.

Build a survivorship-bias-free price history (free, no key)

The end-to-end recipe is three lines of code. It produces a daily panel of (slug, date, close, volume, market_cap) for every coin CoinGecko has ever tracked – active and delisted – back to each coin’s listing date.

library(crypto2)
library(arrow)

# 1. Full historic universe: active + delisted, via cg_id_mapping()
universe <- cg_list(only_active = FALSE)

# 2. Daily close / volume / market cap in USD, full lifetime per coin
#    (one CSV download per coin). Skip OHLC here -- it adds a 2nd HTTP
#    call per coin and only covers the last 30 days (see "What is NOT in
#    the free tier" below).
options(crypto2.cg_what = c("price", "market_cap"))
hist <- cg_history(universe)

# 3. Persist
arrow::write_parquet(hist, "data/cg_history.parquet")

Output shape (hist): columns match crypto_history() exactly – id, slug, name, symbol, timestamp, ref_cur_id, ref_cur_name, open, high, low, close, volume, market_cap, time_open, .... Under the default date_convention = "end_of_day", dates are labelled with CMC’s convention so close[X] / close[X-1] - 1 is the return earned during date X (see vignette("cg-vs-cmc") for the date-convention story).

Preconditions

What you get back

Column Coverage on free tier
close full lifetime of each coin (daily)
volume full lifetime of each coin (daily)
market_cap full lifetime of each coin (daily)
open, high, low only the most recent 30 days; older rows have NA here

Full history is available in any quote currency (convert = "BTC", "EUR", …). All of it comes from CoinGecko’s website, without an API key.

For complete OHLC over the full history (microstructure work, candlestick-based signals, intraday volatility models), see the Pro recipes in vignette("coingecko-pro-backfill").

Function reference

All four exported cg_* functions accept the same arguments as their crypto_* counterparts. Arguments without a CG equivalent (e.g. add_untracked, requestLimit, single_id) are kept for parity and silently ignored. Arguments where CG is more restrictive (e.g. which = "historical" in cg_listings()) emit a one-line warning and coerce to the supported mode.

Purpose CMC CoinGecko
Coin universe crypto_list() cg_list()
Current snapshot crypto_listings() cg_listings()
Daily history crypto_history() cg_history()
Per-coin metadata crypto_info() cg_info()

cg_list() – the universe

universe       <- cg_list()                       # active coins only
universe_full  <- cg_list(only_active = FALSE)    # + historic mapping

only_active = FALSE is the survivorship-bias-corrected universe: the output is cg_list()’s active rows plus the historic-only rows from cg_id_mapping(). A single one-line message reports the mapping’s harvest date: “Historic data retrieval is current until YYYY-MM-DD”.

cg_listings() – current cross-section

snap <- cg_listings(limit = 1000)   # prices included by default

The snapshot carries every /coins/markets field: price, 24h volume and range, price and market-cap changes, all-time high/low and ROI (see ?cg_listings for the column mapping). Two caveats:

which = "historical" and which = "new" warn and coerce to "latest" – CG’s free tier does not expose the historical cross-section in a single call. To build your own cross-section history on the free tier, snapshot cg_listings() periodically (cron) and accumulate the parquet output:

arrow::write_dataset(
  cg_listings(),
  path        = "data/cg_listings",
  partitioning = "harvested_at"
)

cg_history() – the workhorse

Covered in the recipe at the top of this vignette. Key knobs:

cg_info() – per-coin metadata

info <- cg_info(cg_list()[1:10, ])

Description, categories, contract addresses across chains, and various link fields. Same column conventions as crypto_info().

What is NOT in the free tier

The free tier covers every cell needed for daily asset-pricing work in USD except the older end of the OHLC quartet:

Cross-checking against CMC

Triangulation is one click away once you have the parquet from the recipe above. The dedicated vignette cg-vs-cmc walks through:

A live cross-source test (tests/testthat/test-cg-vs-cmc.R) runs in CI and will fail loudly if either provider drifts.