Library / SDK
guptarohit/cryptoCMD avatar
guptarohit/cryptoCMD

cryptoCMD: scraping CoinMarketCap history into dataframes

Cryptocurrency historical price data library in Python. Data from https://coinmarketcap.com.

611 stars119 forksPythonBSD-3-Clause

At a glance

What is it?
cryptoCMD is a small Python library that pulls historical cryptocurrency price data from CoinMarketCap and hands it back as a list of lists, a JSON document, a CSV file or a pandas dataframe. It is BSD licensed, its runtime dependencies are requests and tablib, and it depends on the shape of a third party website remaining stable.
Who is it for?
Adopt cryptoCMD if you need CoinMarketCap history for a handful of coins as a one-off dataset for a notebook or a chart, and you are comfortable with a library that reads a website rather than an API.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 90 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A scraper with a dataframe front end

cryptoCMD is a Python library for cryptocurrency historical market price data, and the source of the data is named in the repository description: CoinMarketCap. The README describes it as a cryptocurrency historical market price data scraper written in Python.

The API is one class, CmcScraper, and it covers the three things you normally want to do with historical price data: get it in memory, get it in a serialised form, or get it into a pandas dataframe. The first example sets up the scraper for one coin and then shows all four shapes of the result:

python
from cryptocmd import CmcScraper

# initialise scraper without time interval
scraper = CmcScraper("XRP")

# get raw data as list of list
headers, data = scraper.get_data()

# get data in a json format
xrp_json_data = scraper.get_data("json")

# export the data as csv file, you can also pass optional `name` parameter
scraper.export("csv", name="xrp_all_time")

# Pandas dataFrame for the same data
df = scraper.get_dataframe()

The pandas option is not a core dependency. It is an optional extra in the project metadata, so a user who never touches dataframes does not install pandas, and the manifest makes the split explicit.

The columns are documented as a fixed list, and this is the single most important line in the README for anyone who plans to parse the output:

`Date, Open, High, Low, Close, Volume, Market Cap, Time Open, Time High, Time Low, Time Close`

The four time columns alongside the four price columns are what you would expect from a source that reports daily candles with an intraday timestamp for the open, high, low and close. A fixed column list is convenient, and it is also a contract: your downstream code depends on those eleven names and their order.

Date ranges and the coin code collision problem

The constructor takes a coin and optionally a start and end date, and the range form is where the interesting detail is: the dates are given as day, month, year strings, which is a European order and not the ISO order most Python code uses.

python
from cryptocmd import CmcScraper

# initialise scraper with time interval
scraper = CmcScraper("XRP", "15-10-2017", "25-10-2017")

The second constructor form exists because coin symbols are not unique. There are several coins whose ticker is a prefix of another's, and the library handles that by letting you supply both a code and a name:

python
from cryptocmd import CmcScraper

# initialise scraper with coin name as well
scraper = CmcScraper(coin_code="sol", coin_name="solana")

The examples directory makes the same point from the other direction, with files named get_by_coin_name.py, get_by_id_number.py and get_csv.py, which suggests the library resolves a coin in three ways, by code, by name and by an identifier number.

The range is inclusive of the start date, and the scrape pulls whatever the site has for that window, so the two arguments are the only control you have over the size of the result. There is no pagination parameter, no limit and no field selection, which is consistent with a scraper over a page that returns a single table.

The export method takes a format and an optional name, and the default output goes to a file in the working directory. For a script that runs repeatedly, that means you are choosing filenames by hand, which is a small operational wrinkle for anyone building this into a scheduler.

Why the whole thing depends on a web page

The acknowledgements section states that the data is being scraped from CoinMarketCap and links to the site's FAQ to note that the data is free to use. That is the entire legal and technical basis of the library, and both halves of that sentence deserve a second look.

Technically, a scraper has no contract. It parses whatever the page returns, so when CoinMarketCap changes its markup, changes its URL structure, or starts serving a different response to clients that look like a script, the library breaks. The upstream project has had three releases since 2023 and the most recent, v0.6.5, is from 2026-04-26, with the previous two from 2023, which is a release pattern consistent with a library that mostly waits for the site to change rather than shipping features.

The second half is the licensing question, and it is a genuine one rather than a formality. A public data page and a data licence are different things, and the README cites the FAQ page rather than a licence. The practical implication for an adopter is that the data is convenient for personal analysis and a chart, and that a product which redistributes it or depends on it commercially wants a different arrangement with the source.

The project metadata shows how small the surface is: the runtime dependencies are requests, tablib for the tabular data handling, and setuptools for Python 3.12 and later, and the build backend is hatchling. The package supports Python 3.9 upward, is BSD-3-Clause licensed, and is classified as a beta.

The tests directory configuration in the project metadata is the tell for anyone planning to use this in automation. There is a pytest marker named integration, described as marking tests as integration tests that make live network calls, so the suite is explicitly split between tests that can run offline and tests that reach the real site.

Installing and the shape of a first script

Installation is a single pip command:

sh
pip install cryptocmd

and to install from the latest source:

sh
pip install git+git://github.com/guptarohit/cryptoCMD.git

The first script you write is short. Pick a coin, ask for the data, and either use it or export it:

python
from cryptocmd import CmcScraper

scraper = CmcScraper("XRP", "15-10-2017", "25-10-2017")
headers, data = scraper.get_data()
df = scraper.get_dataframe()

If you want the dataframe, the pandas extra has to be installed, and the project metadata records it as an optional dependency group named pandas. If you only want the CSV, you need nothing beyond the base install.

The repository is small in the way you would expect for a library with one public class: a cryptocmd/ package directory, an examples/ directory with the three scripts, a tests/ directory, a CHANGELOG.md, a CONTRIBUTING.md, a .pre-commit-config.yaml, a release-please configuration with its manifest, a uv.lock, and both a pyproject.toml and a setup.cfg. The presence of release-please means the version in the manifest and the changelog are generated from commit messages, and the pyproject declares the version statically at 0.6.5, which is the same version as the latest release tag.

There is one documentation convention worth knowing. The README is written in a format that is processed for PyPI, and the PyPI page links back to the GitHub README, so the usage examples you read on the package index and in the repository are the same document.

Where cryptoCMD is the wrong choice

The first limitation is the one the design implies rather than states: there is no caching, no retry policy, no rate limit handling and no local database. Every call to get_data is a network round trip that parses a live page. In a notebook that runs once, that is invisible. In a scheduler that runs every hour for fifty coins, it is fifty page fetches and fifty chances to be rate limited or to hit a layout change at an inconvenient moment.

The second limitation is the missing dimension. The documented columns are a daily series with an open, high, low, close, volume and market cap. If you need hourly bars, minute bars, order book data, on-chain data or anything about individual trades, this library does not have it, and the underlying site may or may not.

The third limitation is reproducibility. A dataset you pulled last year and a dataset you pull today come from the same page, and the site revises and extends its history, so a backtest built on yesterday's pull and one built on today's pull may not agree. For research, that means keeping the exported CSV, which is exactly what the export method is for, and it means the data has no version stamp.

There are two real alternatives, and they differ in approach. The first is a market data API, the kind of service that returns historical bars as JSON over a documented contract with an API key. That is the better answer for anything running on a schedule, because you get a stable contract, a rate limit you can plan around and data you can attribute to a source and a date. It costs money, and the free tiers are usually limited.

The second is the site itself, downloaded once. If you need history for a research question rather than a live feature, running the scraper once and keeping the CSV gives you exactly the same data with none of the fragility, and the export method is built for that. The honest framing is that cryptoCMD is a convenience wrapper for a one-off download rather than an infrastructure component, and treating it as the latter is where the failures come from.

Editorial conclusion

Adopt cryptoCMD if you need CoinMarketCap history for a handful of coins as a one-off dataset for a notebook or a chart, and you are comfortable with a library that reads a website rather than an API. Do not adopt it as the data source for a system that runs on a schedule or on a request path, because every call goes to the live site and the parser is tied to a page layout that can change without notice, and do not adopt it if you need licensed data with a service agreement behind it. Before you build a pipeline on it, read the column list in the README and confirm it still matches what CoinMarketCap returns today, and check the integration test marker in the project configuration, since the test suite is explicitly separated into tests that make live network calls.

Frequently asked questions

What is cryptoCMD?

It is a Python library for cryptocurrency historical market price data, scraping CoinMarketCap. The CmcScraper class returns the data as raw rows, as JSON, as an exported CSV file, or as a pandas dataframe, and the project is BSD-3-Clause licensed with the latest release v0.6.5 from 2026-04-26.

How do I install cryptoCMD?

Run pip install cryptocmd, or pip install git+git://github.com/guptarohit/cryptoCMD.git to install from the latest source. The library requires Python 3.9 or newer, and pandas is an optional extra that is only needed if you call get_dataframe.

What columns does cryptoCMD return?

The README documents them as Date, Open, High, Low, Close, Volume, Market Cap, Time Open, Time High, Time Low, Time Close, in that order, so the four price columns are paired with the four intraday timestamps of the open, high, low and close.

How do I get data for a coin whose ticker is ambiguous?

Pass both a coin code and a coin name to the constructor, for example CmcScraper(coin_code="sol", coin_name="solana"), since several coins share ticker prefixes. The examples directory includes separate scripts for fetching by coin name, by id number, and for writing CSV.

How do I fetch a date range of cryptoCMD data?

Pass the start and end dates to the constructor along with the coin, for example CmcScraper("XRP", "15-10-2017", "25-10-2017"). The dates are written as day, month, year, and the scrape returns everything the source has for that window.

Official sources

  1. guptarohit/cryptoCMD on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/guptarohit-cryptocmd.svg)](https://hysenlabs.com/projects/guptarohit-cryptocmd)

Was this useful?