Options contracts have become an increasingly liquid segment of crypytoasset derivatives. Coin Metrics currently offers options data through various endpoints in our Market Data Feed offering. Available endpoints include market greeks, implied volatility, contract prices, market quotes, open interest, and more.
Resources
This notebook demonstrates basic functionality offered by the Coin Metrics Python API Client and Market Data Feed.
Coin Metrics offers a vast assortment of data for hundreds of cryptoassets. The Python API Client allows for easy access to this data using Python without needing to create your own wrappers using requests and other such libraries.
To understand the data that Coin Metrics offers, feel free to peruse the resources below.
The Coin Metrics API v4 website contains the full set of endpoints and data offered by Coin Metrics.
Download the entire notebook as either a jupyter notebook to run yourself or as a pdf from the two links below
Notebook Setup
from os import environimport pandas as pdimport numpy as npimport seaborn as snsimport loggingfrom datetime import date, timedeltafrom coinmetrics.api_client import CoinMetricsClientimport loggingimport calendarfrom datetime import dateimport matplotlib.ticker as mtickimport matplotlib.pyplot as plt%matplotlib inline
# We recommend privately storing your API key in your local environment.try: api_key = environ["CM_API_KEY"] logging.info("Using API key found in environment")exceptKeyError: api_key ="" logging.info("API key not found. Using community client")client =CoinMetricsClient(api_key)
2024-02-13 13:17:42 INFO Using API key found in environment
'Volatility smiles' are a popular options data visualization tool that help traders understand predicted asset volatility across various contract expiration dates. The 'smile' is plotted by mapping the strike price and implied volatility of a group of options with the same underlying asset and expiration date.
asset ='btc'
Catalog Endpoint
The Coin Metrics API contains two types of catalog endpoints (Python client functions in paranthesis): the catalog (catalog_*) and catalog-all (catalog_full_*). The catalog endpoint displays the set of data available to your API key. The catalog-all endpoint displays the full set of data for CM Pro users.
Catalog objects return a list of dictionaries. For catalog_full_market_implied_volatility_v2, each element of the list is an option market that supports implied volatility data.
# Select contracts that are still trading as of yesterdayend_date = (date.today()-timedelta(days=1)).strftime("%Y-%m-%d")deribit_current = markets_deribit.loc[(markets_deribit["max_time"]>= end_date)]
Collect Contract Reference Data
ref_data = client.reference_data_markets( exchange ='deribit', type ='option', base = asset, page_size=10000).to_dataframe()
l = sns.lineplot(data=calls, x="strike", y="iv_mark", hue='expiration')l.set_xlabel("\nStrike Price", fontsize =17)l.set_ylabel("Implied Volatility \n", fontsize =17)l.set_xlim([0, calls['strike'].max()])l.set_xticks(l.get_xticks().tolist())l.set_xticklabels(['${:,.0f}'.format(x) for x in l.get_xticks().tolist()],fontsize=14)l.set_yticks(l.get_yticks().tolist())l.set_yticklabels(['{:.2f}'.format(y) for y in l.get_yticks().tolist()],fontsize=14)plt.setp(l.get_yticklabels()[0], visible=False)leg = plt.legend(loc='upper right',ncol=2,fontsize=13.5)for text in leg.get_texts(): text.set_color("white")l.set_title('\n'+ asset.upper() +' Volatility Smiles\n', fontsize =25)plt.suptitle('\n\n Deribit Options by Expiration',fontsize=16);
# Convert 'expiration' to datetime and extract monthcalls_oi['expiration']= pd.to_datetime(calls_oi['expiration'])calls_oi['Expiration Month']= calls_oi['expiration'].dt.monthputs_oi['expiration']= pd.to_datetime(puts_oi['expiration'])puts_oi['Expiration Month']= puts_oi['expiration'].dt.month# Group by 'expiration_month' and sum 'value_usd'calls_oi_grouped = calls_oi.groupby('Expiration Month')['value_usd'].sum()puts_oi_grouped = puts_oi.groupby('Expiration Month')['value_usd'].sum()# Convert Series to DataFrame and reset indexcalls_oi_df = calls_oi_grouped.reset_index()puts_oi_df = puts_oi_grouped.reset_index()# Replace month numbers with month namescalls_oi_df['Expiration Month']= calls_oi_df['Expiration Month'].apply(lambdax: calendar.month_name[x])puts_oi_df['Expiration Month']= puts_oi_df['Expiration Month'].apply(lambdax: calendar.month_name[x])
calls_oi_df
# Add a new column to distinguish between calls and putscalls_oi_df['type']='calls'puts_oi_df['type']='puts'# Concatenate the dataframesdf = pd.concat([calls_oi_df, puts_oi_df])df = df.rename(columns={"value_usd": "Open Interest (USD)"})# Plot the bars side by sidep = sns.barplot(data=df, x='Expiration Month', y='Open Interest (USD)', hue='type', palette=['green', 'red'])p.set_title('\nBTC Options Open Interest (USD)\nby Expiration Month\n',fontsize=16)# Format y-axis in billionsfmt ='${x:,.0f}B'p.legend_.remove()tick = mtick.FuncFormatter(lambdax, pos: '${:,.2f}B'.format(x*1e-9))p.yaxis.set_major_formatter(tick)
2024-02-13 13:18:16 INFO Using categorical units to plot a list of strings that are all parsable as floats or dates. If these strings should be plotted as numbers, cast to the appropriate data type before plotting.
2024-02-13 13:18:16 INFO Using categorical units to plot a list of strings that are all parsable as floats or dates. If these strings should be plotted as numbers, cast to the appropriate data type before plotting.