Core Concepts
This page covers the building blocks you'll use most often: how the client lazily models requests as DataCollection objects, how to convert them into DataFrames, and how to export them to files.
DataCollection
Every method on CoinMetricsClient returns a DataCollection. A DataCollection is a lazy wrapper around the underlying request: it captures the endpoint and parameters, but it does not hit the API until you iterate over it or call a transformation method (to_list(), to_dataframe(), export_to_csv(), ...).
By default, time-series methods stream their response (format='json_stream'), so a single iteration over a DataCollection typically fetches everything in one continuous response. For example, to get market trades for the Coinbase BTC-USD pair:
for trade in client.get_market_trades(
markets='coinbase-btc-usd-spot',
start_time='2020-01-01',
end_time='2020-01-03',
limit_per_market=10,
):
print(trade)
The same pattern works for daily metrics:
for metric_data in client.get_asset_metrics(
assets='btc',
metrics=['ReferenceRateUSD', 'BlkHgt', 'AdrActCnt', 'AdrActRecCnt', 'FlowOutBFXUSD'],
frequency='1d',
limit_per_asset=10,
):
print(metric_data)
Exploring Available Data
Use the catalog_*_v2 methods to discover what data is available. For example, to list markets that report trades data:
print(client.catalog_market_trades_v2(markets='coinbase-btc-usd-spot').to_list())
You can also filter by exchange, base, or quote:
print(client.catalog_market_trades_v2(exchange='coinbase', base='btc', quote='usd').to_list())
The catalog-v2 endpoints are designed to feed the historical-data endpoints. For example, to fetch one hour of all BTC market trades from Coinbase:
btc_coinbase_markets = [
market['market']
for market in client.catalog_market_trades_v2(exchange="coinbase", asset="btc").to_list()
]
client.get_market_trades(
markets=btc_coinbase_markets,
start_time="2023-01-01T00:00:00",
end_time="2023-01-01T01:00:00",
).export_to_csv("coinbase_trades.csv")
DataFrames
Pandas
DataCollection.to_dataframe() materializes the response as a pandas DataFrame:
print(client.catalog_market_metrics_v2(exchange="coinbase", base='btc', quote='usd').to_dataframe())
You can use the full pandas API to filter, transform, and persist the result:
import pandas as pd
import os
from datetime import timedelta
from coinmetrics.api_client import CoinMetricsClient
client = CoinMetricsClient(os.environ['CM_API_KEY'])
coinbase_markets = client.catalog_market_trades_v2(
exchange="coinbase", base="btc", quote="usd",
).to_dataframe()
coinbase_markets['max_time'] = pd.to_datetime(coinbase_markets['max_time'], utc=True)
one_day_ago = pd.Timestamp.now(tz='UTC') - timedelta(days=1)
recent = coinbase_markets[coinbase_markets['max_time'] > one_day_ago]
Time-series data converts the same way:
trades = client.get_market_trades(
markets='coinbase-btc-usd-spot',
start_time='2021-09-19T00:00:00Z',
limit_per_market=10,
)
trades_df = trades.to_dataframe()
print(trades_df.head())
Column types are derived from the endpoint's schema. To override types for specific columns, pass a dtype_mapper:
mapper = {'SplyFF': 'Float64', 'AdrBalUSD1Cnt': 'Int64'}
df_mapped = client.get_asset_metrics(
assets=['btc', 'xmr'],
metrics=['volume_trusted_spot_usd_1d', 'SplyFF', 'AdrBalUSD1Cnt'],
start_time='2021-12-01',
limit_per_asset=3,
).to_dataframe(dtype_mapper=mapper)
Polars
Polars is a high-performance DataFrame library and a more performant alternative to pandas in many cases. Pass dataframe_type="polars" to to_dataframe():
df = client.get_asset_metrics(
'btc', 'ReferenceRateUSD', limit_per_asset=1,
).to_dataframe(dataframe_type="polars")
LazyFrames
DataFrames eagerly load data into memory. Lazy execution defers materialization, which is useful when you want to apply intermediate transformations to large datasets before collecting. Convert a DataCollection into a polars LazyFrame with to_lazyframe(). See the Best Practices guide for an in-depth example.
Data Exports
You can stream a DataCollection directly to a CSV, JSON, or Parquet file using export_to_csv(), export_to_json(), and export_to_parquet():
import datetime
start_date = datetime.date(2022, 1, 1)
end_date = datetime.date(2022, 1, 2)
client.get_market_trades(
markets="coinbase-btc-usd-spot",
start_time=start_date,
end_time=end_date,
).export_to_csv("jan_1_2022_coinbase_btc_trades.csv")
client.get_market_trades(
markets="coinbase-eth-usd-spot",
start_time=start_date,
end_time=end_date,
).export_to_json("jan_1_2022_coinbase_eth.json")
client.get_market_trades(
markets="coinbase-sol-usd-spot",
start_time=start_date,
end_time=end_date,
).export_to_parquet("jan_1_2022_coinbase_sol.parquet")
For large historical exports across many assets or markets, see the Parallel Execution section in the Best Practices guide, which uses parallel().export_to_csv_files(), parallel().export_to_json_files(), and parallel().export_to_parquet_files() to write one file per worker.