Obscura

Crypto Markets

Per-coin market data from CoinGecko: price, market cap and volume across thousands of cryptocurrencies.

crypto_markets — the dataset name to pass to the Obscura API.

Category Markets Columns 22 Refresh Daily Entity key symbol Point-in-time available_date

What one row means

One CoinGecko top-market-cap coin's price/market-cap/volume/supply snapshot as returned by the `coins/markets` endpoint at the moment of one scrape, upserted per coin per UTC calendar day.

One row per (coin_id, captured_date).

Point-in-time availability

Every Obscura dataset carries available_date: the calendar day the publisher made the row available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the same thing on every dataset in the catalog.

For crypto_markets: snapshot: available_date = captured_date, a STORED GENERATED column (migration 000205). WHY THAT IS THE DAY IT BECAME AVAILABLE: /coins/markets is a CURRENT-STATE endpoint — it answers only for `now`, offers no historical parameter, and keeps no archive — so this row exists solely because the collector asked on that day, and the day it asked IS the day the fact was obtainable. There is no publication event to lag behind and no source date to prefer. EVIDENCE that captured_date is the capture day and not a payload date: the collector sets it to Utc::now().date_naive() on a live run and to BronzeObject::captured_day() on a replay, so replaying a year-old capture reproduces that capture's day rather than today's. It is generated rather than written because a column a collector writes can be written from a clock, which is what a replay must never do.

Refresh cadence

Obscura refreshes crypto_markets daily — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.

Schema — 22 columns

The full public column list for crypto_markets, with the meaning of every field. The same schema is served unauthenticated at https://api.obscura.trade/v1/catalog/crypto_markets.

ColumnTypeDescription
coin_idtext · not nullCoinGecko's slug id for the coin (e.g. "bitcoin", "ethereum", "tether"), taken verbatim from the API's `id` field. Half of the composite primary key; stable across runs and the natural join key back to CoinGecko for any given asset.
captured_datedate · not nullThe UTC calendar day the collector CONTACTED CoinGecko: Utc::now().date_naive() once per task invocation on a live run, and the bronze object's own capture day on a replay. Other half of the composite primary key. Because /coins/markets answers only for `now` and keeps no archive, the day we asked is the day this state was obtainable — which is why available_date is generated directly from this column.
symboltextTicker symbol for the coin, upper-cased on ingest (e.g. "BTC", "ETH", "USDT"). Sourced from the API's `symbol` field; nullable because the upstream JSON field is optional and a small share of listings omit it.
nametextHuman-readable display name of the coin/project (e.g. "Bitcoin", "Ethereum", "Tether"), copied from the API's `name` field; nullable when upstream omits it.
price_usddouble precisionSpot price in the requested vs_currency (default USD; CoinGecko field `current_price`) at the moment of the API call — an instantaneous quote, not an OHLC close. Nullable if CoinGecko has no live quote for the coin.
market_capdouble precisionCirculating-supply market capitalization in the vs_currency at capture time (API field `market_cap`); price_usd * circulating_supply as computed by CoinGecko, not derived locally.
market_cap_rankintegerCoinGecko's market-cap rank among all listed coins at capture time (API field `market_cap_rank`, 1 = largest). Also drives which coins are included: the task requests order=market_cap_desc so market_cap_rank is monotonic with the row's position in the fetched page.
total_volumedouble precisionTrailing 24-hour trading volume in the vs_currency across CoinGecko's aggregated exchanges (API field `total_volume`), as of capture time — a rolling window, not a calendar-day total.
high_24hdouble precisionHighest price observed over the trailing 24 hours ending at capture time (API field `high_24h`), in the vs_currency.
low_24hdouble precisionLowest price observed over the trailing 24 hours ending at capture time (API field `low_24h`), in the vs_currency.
price_change_pct_24hdouble precisionPercent change in price_usd over the trailing 24 hours ending at capture time (API field `price_change_percentage_24h`, requested explicitly via price_change_percentage=24h). Can be negative; e.g. -0.00883 means roughly flat/-0.009%.
circulating_supplydouble precisionNumber of coin units in public circulation at capture time (API field `circulating_supply`), used by CoinGecko as the market_cap multiplier; denominated in the coin's own native units, not USD.
total_supplydouble precisionTotal coin units in existence (issued, including any not yet circulating) at capture time (API field `total_supply`), in native units; may equal circulating_supply for fully-circulating assets or exceed it for coins with locked/unminted supply, and may be null for uncapped/unknown-supply assets.
fully_diluted_valuationdouble precisionFully-diluted valuation in the vs_currency at capture time (API field `fully_diluted_valuation`): CoinGecko's price × max_supply market cap. A distinct valuation measure that is NOT derivable from what we otherwise store; null for coins CoinGecko has no diluted figure for.
max_supplydouble precisionHard supply cap in the coin's native units (API field `max_supply`): the maximum number of units that can ever exist (e.g. Bitcoin's 21,000,000). Distinct from total_supply (currently issued); null for uncapped/unknown-supply coins.
athdouble precisionAll-time-high price in the vs_currency (API field `ath`): the historical maximum price CoinGecko has ever recorded for the coin. A historical extreme not reconstructable from an ingest-onward daily snapshot series.
atldouble precisionAll-time-low price in the vs_currency (API field `atl`): the historical minimum price CoinGecko has ever recorded for the coin. Same rationale as `ath`.
ath_datetimestamp with time zoneTimestamp of the all-time-high price (API field `ath_date`, an RFC3339 instant like "2025-10-06T18:57:42.558Z"). A natural temporal attribute of the coin's price history with no local equivalent.
atl_datetimestamp with time zoneTimestamp of the all-time-low price (API field `atl_date`, an RFC3339 instant). Natural temporal attribute, as with `ath_date`.
market_cap_change_pct_24hdouble precisionPercent change in market_cap over the trailing 24 hours ending at capture time (API field `market_cap_change_percentage_24h`). A rolling metric our daily snapshots can otherwise only approximate; can be negative.
last_updatedtimestamp with time zoneUpstream quote-freshness timestamp (API field `last_updated`, an RFC3339 instant): the moment CoinGecko last refreshed this row's quote. Finer provenance than the capture-day available_date; distinct from synced_at (our own ingestion time).
available_datedatePUBLIC-availability date = captured_date. STORED GENERATED column (migration 000205), read-only; the point-in-time column to filter and join on. It is the day the collector polled CoinGecko, because a current-state endpoint with no archive makes that the only day this state could have been obtained.

Access crypto_markets

Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.

import obscura

client = obscura.Client("obs_live_…")

df = client.query(
    dataset="crypto_markets",
    symbols=["NVDA", "AAPL"],
    start="2024-01-01",
)

Create a free account Browse all 95 datasets

Frequently asked questions

What is in the crypto_markets dataset?

Per-coin market data from CoinGecko: price, market cap and volume across thousands of cryptocurrencies. One CoinGecko top-market-cap coin's price/market-cap/volume/supply snapshot as returned by the `coins/markets` endpoint at the moment of one scrape, upserted per coin per UTC calendar day.

How do I avoid look-ahead bias with crypto_markets?

Filter on crypto_markets.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — snapshot: available_date = captured_date, a STORED GENERATED column (migration 000205). WHY THAT IS THE DAY IT BECAME AVAILABLE: /coins/markets is a CURRENT-STATE endpoint — it answers only for `now`, offers no historical parameter, and keeps no archive — so this row exists solely because the collector asked on that day, and the day it asked IS the day the fact was obtainable. There is no publication event to lag behind and no source date to prefer. EVIDENCE that captured_date is the capture day and not a payload date: the collector sets it to Utc::now().date_naive() on a live run and to BronzeObject::captured_day() on a replay, so replaying a year-old capture reproduces that capture's day rather than today's. It is generated rather than written because a column a collector writes can be written from a clock, which is what a replay must never do. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get crypto_markets?

As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="crypto_markets". The column schema is public at https://api.obscura.trade/v1/catalog/crypto_markets.

Can I filter crypto_markets by company or symbol?

Yes. crypto_markets carries symbol, the column the API's symbols filter resolves against.

How often is crypto_markets updated?

Obscura refreshes crypto_markets on a daily schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.

Related datasets

Cboe IndicesDaily history of Cboe's volatility indices, including VIX, sourced directly from Cboe. DeFiLlama ProtocolsTotal value locked in each DeFi protocol, tracked by DeFiLlama. DeFiLlama StablecoinsCirculating supply of each stablecoin over time, from DeFiLlama. DeFiLlama TVLTotal value locked on each blockchain, from DeFiLlama. Flow MetricsTrade-flow metrics per symbol in fixed time windows: taker (aggressor) buy versus sell volume and trade counts, broken o… Forex OrderbookOANDA's order book and position book by currency pair: where retail traders' open orders and positions sit relative to p… Forex PositionsRetail forex positioning by pair (share of traders long versus short), collected from several broker sentiment feeds. Forex Positions AggregateA consensus long/short reading per currency pair, blending the individual broker sentiment feeds.