Skip to main content

Exploring Options, Open Interest, and Volatility Data

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.

File Download​

Download the entire notebook as either a jupyter notebook to run yourself or as a pdf from the two links below

Download MDF_options_exploration.ipynb

Download MDF_options_exploration.pdf

Notebook Setup​

from os import environ
import pandas as pd
import numpy as np
import seaborn as sns
import logging
from datetime import date, timedelta
from coinmetrics.api_client import CoinMetricsClient
import logging
import calendar
from datetime import date
import matplotlib.ticker as mtick
import matplotlib.pyplot as plt
# %matplotlib inline
sns.set_theme()
sns.set(rc={'figure.figsize':(18,8)})
sns.set_palette("YlGn",3)
sns.set_style("ticks", {"xtick.major.size":20,"ytick.major.size":20})
sns.set_style("whitegrid",{'axes.grid' : True,'grid.linestyle': '--', 'grid.color': '#b0b0b0','axes.edgecolor': 'white',
'font.family': ['arial'],'axes.facecolor':'#4b5359'})
logging.basicConfig(
format='%(asctime)s %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S'
)
# 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")
except KeyError:
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

Query Examples​

Retrieving Market Greeks​


greeks_deribit = client.get_market_greeks(
markets='deribit-BTC-30DEC22-*-option',
limit_per_market=1
).to_dataframe()
greeks_deribit.head()
markettimedatabase_timevegathetarhodeltagammaexchange_time
0deribit-BTC-30DEC22-10000-C-option2022-05-11 14:09:00+00:002022-05-11 14:09:14.701194+00:0012.95354-2.4064658.034780.978930.02022-05-11 14:09:13.336000+00:00
1deribit-BTC-30DEC22-10000-P-option2022-05-11 14:09:00+00:002022-05-11 14:09:14.701194+00:0012.95354-2.40646-5.73063-0.021070.02022-05-11 14:09:13.329000+00:00
2deribit-BTC-30DEC22-100000-C-option2021-12-30 08:02:00+00:002021-12-30 08:02:03.247339+00:00158.05411-14.1717886.789390.240020.000012021-12-30 08:02:02.591000+00:00
3deribit-BTC-30DEC22-100000-P-option2021-12-30 08:02:00+00:002021-12-30 08:02:04.257489+00:00156.75983-13.9386-914.15583-0.763540.000012021-12-30 08:02:03.416000+00:00
4deribit-BTC-30DEC22-11000-C-option2022-11-16 09:06:00+00:002022-11-16 09:06:40.873351+00:009.65147-11.4140410.997310.905880.000032022-11-16 09:06:40.094000+00:00

Retrieving Market Quotes​


quotes_deribit = client.get_market_quotes(
markets='deribit-BTC-30DEC22-*-option',
limit_per_market=1,
).to_dataframe()
quotes_deribit.head()
markettimecoin_metrics_idask_priceask_sizebid_pricebid_size
0deribit-BTC-30DEC22-10000-C-option2022-05-11 14:09:00+00:001652278140000000-00.00.00.00.0
1deribit-BTC-30DEC22-10000-P-option2022-05-11 14:09:00+00:001652278140000000-00.0121.90.012.3
2deribit-BTC-30DEC22-100000-C-option2021-12-30 08:02:00+00:001640851320000000-00.00.00.01852.5
3deribit-BTC-30DEC22-100000-P-option2021-12-30 08:02:00+00:001640851320000000-00.00.00.00.0
4deribit-BTC-30DEC22-11000-C-option2022-11-16 09:06:00+00:001668589560000000-00.00.00.00.0

Retrieving Contract Prices​


prices_deribit = client.get_market_contract_prices(
markets='deribit-BTC-30DEC22-*-option',
limit_per_market=1,
).to_dataframe()
prices_deribit.head()
markettimedatabase_timemark_priceindex_priceexchange_time
0deribit-BTC-30DEC22-10000-C-option2022-05-11 14:09:00+00:002022-05-11 14:09:14.701194+00:000.69531350.762022-05-11 14:09:13.336000+00:00
1deribit-BTC-30DEC22-10000-P-option2022-05-11 14:09:00+00:002022-05-11 14:09:14.701194+00:000.00731350.762022-05-11 14:09:13.329000+00:00
2deribit-BTC-30DEC22-100000-C-option2021-12-30 08:02:00+00:002021-12-30 08:02:03.247339+00:000.06932947033.612021-12-30 08:02:02.591000+00:00
3deribit-BTC-30DEC22-100000-P-option2021-12-30 08:02:00+00:002021-12-30 08:02:04.257489+00:001.03456847034.052021-12-30 08:02:03.416000+00:00
4deribit-BTC-30DEC22-11000-C-option2022-11-16 09:06:00+00:002022-11-16 09:06:40.873351+00:000.354716744.612022-11-16 09:06:40.094000+00:00

Retrieving Open Interest​


oi_deribit = client.get_market_open_interest(
markets='deribit-BTC-30DEC22-*-option',
limit_per_market=1,
).to_dataframe()
oi_deribit.head()
markettimecontract_countvalue_usddatabase_timeexchange_time
0deribit-BTC-30DEC22-10000-C-option2022-05-11 14:09:00+00:00002022-05-11 14:09:39.584165+00:002022-05-11 14:09:00+00:00
1deribit-BTC-30DEC22-10000-P-option2022-05-11 14:09:00+00:00002022-05-11 14:09:39.584165+00:002022-05-11 14:09:00+00:00
2deribit-BTC-30DEC22-100000-C-option2021-12-30 08:02:00+00:00002021-12-30 08:02:35.912527+00:002021-12-30 08:02:00+00:00
3deribit-BTC-30DEC22-100000-P-option2021-12-30 08:02:00+00:00002021-12-30 08:02:37.918026+00:002021-12-30 08:02:00+00:00
4deribit-BTC-30DEC22-11000-C-option2022-11-16 09:06:00+00:00002022-11-16 09:06:24.566250+00:002022-11-16 09:06:00+00:00

Plotting Options 'Volatility Smiles'​


'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.

markets_deribit = client.catalog_full_market_implied_volatility_v2(
exchange='deribit',
market_type='option',
base=asset,
page_size=10000
).to_dataframe()
markets_deribit.sort_values(by='max_time')
marketmin_timemax_time
29064deribit-BTC-2SEP21-53000-C-option2021-09-01 13:24:00+00:002021-09-02 08:00:00+00:00
29049deribit-BTC-2SEP21-45000-P-option2021-09-01 13:24:00+00:002021-09-02 08:00:00+00:00
29048deribit-BTC-2SEP21-45000-C-option2021-09-01 13:24:00+00:002021-09-02 08:00:00+00:00
29046deribit-BTC-2SEP21-44000-C-option2021-09-01 13:24:00+00:002021-09-02 08:00:00+00:00
29045deribit-BTC-2SEP21-43000-P-option2021-09-01 13:24:00+00:002021-09-02 08:00:00+00:00
............
24053deribit-BTC-27DEC24-61000-P-option2024-01-02 11:29:00+00:002024-02-13 17:43:00+00:00
24054deribit-BTC-27DEC24-62000-C-option2024-01-08 22:41:00+00:002024-02-13 17:43:00+00:00
24055deribit-BTC-27DEC24-62000-P-option2024-01-08 22:41:00+00:002024-02-13 17:43:00+00:00
24049deribit-BTC-27DEC24-59000-P-option2024-01-02 03:35:00+00:002024-02-13 17:43:00+00:00
27297deribit-BTC-29MAR24-26000-P-option2023-03-30 08:03:00+00:002024-02-13 17:43:00+00:00

40442 rows × 3 columns

markets_deribit["min_time"] = pd.to_datetime(markets_deribit.min_time)
markets_deribit["max_time"] = pd.to_datetime(markets_deribit.max_time)
# Select contracts that are still trading as of yesterday
end_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()
ref_data.head()
marketexchangetypebasequotepairsymbolsize_assetstrikeoption_contract_typeis_europeancontract_sizelistingexpirationsettlement_pricestatusorder_amount_minorder_price_incrementorder_taker_feeorder_maker_fee
0deribit-BTC-10APR20-4750-C-optionderibitoptionbtcusdbtc-usdBTC-10APR20-4750-Cbtc4750callTrue12020-03-28T03:21:00.000000000Z2020-04-10T08:00:00.000000000Z6931.78offline0.10.00050.00040.0004
1deribit-BTC-10APR20-4750-P-optionderibitoptionbtcusdbtc-usdBTC-10APR20-4750-Pbtc4750putTrue12020-03-28T03:21:00.000000000Z2020-04-10T08:00:00.000000000Z6931.78offline0.10.00050.00040.0004
2deribit-BTC-10APR20-5000-C-optionderibitoptionbtcusdbtc-usdBTC-10APR20-5000-Cbtc5000callTrue12020-03-26T08:19:00.000000000Z2020-04-10T08:00:00.000000000Z6931.78offline0.10.00050.00040.0004
3deribit-BTC-10APR20-5000-P-optionderibitoptionbtcusdbtc-usdBTC-10APR20-5000-Pbtc5000putTrue12020-03-26T08:19:00.000000000Z2020-04-10T08:00:00.000000000Z6931.78offline0.10.00050.00040.0004
4deribit-BTC-10APR20-5250-P-optionderibitoptionbtcusdbtc-usdBTC-10APR20-5250-Pbtc5250putTrue12020-03-26T08:00:08.000000000Z2020-04-10T08:00:00.000000000Z6931.78offline0.10.00050.00040.0004
deribit_current = pd.merge(deribit_current, ref_data[['market','expiration','option_contract_type','strike']], on='market', how='left')
# Set max expiration date
max_expiry = (date.today() + timedelta(days=365)).strftime("%Y-%m-%d")
max_expiry = (pd.to_datetime(max_expiry)).strftime("%Y-%m-%d")
deribit_current = pd.DataFrame(deribit_current.loc[(deribit_current["expiration"] < max_expiry)])
deribit_current = deribit_current.sort_values(by=['expiration'])
deribit_current
marketmin_timemax_timeexpirationoption_contract_typestrike
0deribit-BTC-12FEB24-41000-C-option2024-02-09 08:03:00+00:002024-02-12 08:00:00+00:002024-02-12T08:00:00.000000000Zcall41000
36deribit-BTC-12FEB24-48750-C-option2024-02-11 08:03:00+00:002024-02-12 08:00:00+00:002024-02-12T08:00:00.000000000Zcall48750
37deribit-BTC-12FEB24-48750-P-option2024-02-11 08:03:00+00:002024-02-12 08:00:00+00:002024-02-12T08:00:00.000000000Zput48750
38deribit-BTC-12FEB24-49000-C-option2024-02-09 08:03:00+00:002024-02-12 08:00:00+00:002024-02-12T08:00:00.000000000Zcall49000
39deribit-BTC-12FEB24-49000-P-option2024-02-09 08:03:00+00:002024-02-12 08:00:00+00:002024-02-12T08:00:00.000000000Zput49000
.....................
557deribit-BTC-27DEC24-120000-P-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:002024-12-27T08:00:00.000000000Zput120000
558deribit-BTC-27DEC24-125000-C-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:002024-12-27T08:00:00.000000000Zcall125000
559deribit-BTC-27DEC24-125000-P-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:002024-12-27T08:00:00.000000000Zput125000
547deribit-BTC-27DEC24-10000-P-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:002024-12-27T08:00:00.000000000Zput10000
579deribit-BTC-27DEC24-28000-P-option2023-12-28 18:57:00+00:002024-02-13 17:43:00+00:002024-12-27T08:00:00.000000000Zput28000

1008 rows × 6 columns

Retrieve Implied Volatility​

iv_asset_contracts = client.get_market_implied_volatility(
markets='deribit-*-option',
start_time = end_date,
limit_per_market=1,
page_size=10000
).to_dataframe()
iv_asset_contracts = iv_asset_contracts.loc[iv_asset_contracts['market'].isin(deribit_current['market'].to_list())]
iv_asset_contracts
markettimedatabase_timeiv_bidiv_askiv_markexchange_time
0deribit-BTC-12FEB24-41000-C-option2024-02-12 00:00:00+00:002024-02-12 00:00:15.649992+00:000.00.00.6772024-02-12 00:00:13.899000+00:00
1deribit-BTC-12FEB24-41000-P-option2024-02-12 00:00:00+00:002024-02-12 00:00:14.602653+00:000.02.12730.6772024-02-12 00:00:13.900000+00:00
2deribit-BTC-12FEB24-42000-C-option2024-02-12 00:00:00+00:002024-02-12 00:00:03.599239+00:000.03.00760.61762024-02-12 00:00:02.821000+00:00
3deribit-BTC-12FEB24-42000-P-option2024-02-12 00:00:00+00:002024-02-12 00:00:03.599239+00:000.02.11750.61762024-02-12 00:00:00.808000+00:00
4deribit-BTC-12FEB24-42500-C-option2024-02-12 00:00:00+00:002024-02-12 00:00:12.040598+00:000.00.00.57862024-02-12 00:00:09.872000+00:00
........................
1001deribit-BTC-29MAR24-80000-P-option2024-02-12 00:00:00+00:002024-02-12 00:00:16.038858+00:000.00.88660.69282024-02-12 00:00:13.898000+00:00
1002deribit-BTC-29MAR24-85000-C-option2024-02-12 00:00:00+00:002024-02-12 00:00:04.033371+00:000.70720.72880.71952024-02-12 00:00:03.827000+00:00
1003deribit-BTC-29MAR24-85000-P-option2024-02-12 00:00:00+00:002024-02-12 00:00:10.038068+00:000.00.89340.71942024-02-12 00:00:08.863000+00:00
1004deribit-BTC-29MAR24-90000-C-option2024-02-12 00:00:00+00:002024-02-12 00:00:04.033371+00:000.72480.74760.74092024-02-12 00:00:02.820000+00:00
1005deribit-BTC-29MAR24-90000-P-option2024-02-12 00:00:00+00:002024-02-12 00:00:11.038214+00:000.00.95180.74082024-02-12 00:00:09.870000+00:00

1006 rows × 7 columns

iv_only = iv_asset_contracts.drop(['time', 'database_time','iv_bid','iv_ask','exchange_time'], axis=1).drop_duplicates()
iv_only
marketiv_mark
0deribit-BTC-12FEB24-41000-C-option0.677
1deribit-BTC-12FEB24-41000-P-option0.677
2deribit-BTC-12FEB24-42000-C-option0.6176
3deribit-BTC-12FEB24-42000-P-option0.6176
4deribit-BTC-12FEB24-42500-C-option0.5786
.........
1001deribit-BTC-29MAR24-80000-P-option0.6928
1002deribit-BTC-29MAR24-85000-C-option0.7195
1003deribit-BTC-29MAR24-85000-P-option0.7194
1004deribit-BTC-29MAR24-90000-C-option0.7409
1005deribit-BTC-29MAR24-90000-P-option0.7408

1006 rows × 2 columns

merged = pd.merge(deribit_current, iv_only, on="market").drop_duplicates()
calls = pd.DataFrame(merged.loc[merged['option_contract_type'] == 'call'])
calls['expiration'] = pd.to_datetime(calls['expiration']).dt.strftime('%b %d, %Y')
calls = calls.dropna(subset=['strike'])
calls['strike'] = calls['strike'].astype('int64')
calls['iv_mark'] = calls['iv_mark'].astype('float64')
calls['expiration'] = calls['expiration'].astype('category')
calls = calls.dropna(subset=['strike', 'iv_mark'])
calls = calls[np.isfinite(calls['strike']) & np.isfinite(calls['iv_mark'])]
calls
marketmin_timemax_timeexpirationoption_contract_typestrikeiv_mark
0deribit-BTC-12FEB24-41000-C-option2024-02-09 08:03:00+00:002024-02-12 08:00:00+00:00Feb 12, 2024call410000.6770
1deribit-BTC-12FEB24-48750-C-option2024-02-11 08:03:00+00:002024-02-12 08:00:00+00:00Feb 12, 2024call487500.3703
3deribit-BTC-12FEB24-49000-C-option2024-02-09 08:03:00+00:002024-02-12 08:00:00+00:00Feb 12, 2024call490000.3908
5deribit-BTC-12FEB24-49250-C-option2024-02-11 08:14:00+00:002024-02-12 08:00:00+00:00Feb 12, 2024call492500.4235
7deribit-BTC-12FEB24-49500-C-option2024-02-09 08:03:00+00:002024-02-12 08:00:00+00:00Feb 12, 2024call495000.4815
........................
994deribit-BTC-27DEC24-105000-C-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:00Dec 27, 2024call1050000.6558
996deribit-BTC-27DEC24-110000-C-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:00Dec 27, 2024call1100000.6580
998deribit-BTC-27DEC24-115000-C-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:00Dec 27, 2024call1150000.6633
1000deribit-BTC-27DEC24-120000-C-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:00Dec 27, 2024call1200000.6656
1002deribit-BTC-27DEC24-125000-C-option2023-12-28 08:02:00+00:002024-02-13 17:43:00+00:00Dec 27, 2024call1250000.6690

503 rows × 7 columns

calls = calls.sort_values(by='expiration')
calls.dtypes
market string[python]
min_time datetime64[ns, UTC]
max_time datetime64[ns, UTC]
expiration category
option_contract_type string[python]
strike int64
iv_mark float64
dtype: object
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);

Plotting Calls vs. Puts by Open Interest​

options_oi = client.get_market_open_interest(
markets='deribit-*-option',
limit_per_market=1,
paging_from='end',
start_time=end_date,
page_size=10000
).to_dataframe()
options_oi['value_usd'] = pd.to_numeric(options_oi['value_usd'])
options_oi = options_oi.loc[options_oi['value_usd'] > 0]
options_oi = options_oi.sort_values('value_usd',ascending=False)
oi_only = options_oi[['market','contract_count','value_usd']]
oi_only
marketcontract_countvalue_usd
1356deribit-ETH-23FEB24-2400-C-option97938.0256834569.96
972deribit-BTC-29MAR24-50000-C-option5204.3254888763.251
992deribit-BTC-29MAR24-60000-C-option4830.8236604371.64
1716deribit-ETH-29MAR24-3000-C-option86689.0227343636.28
994deribit-BTC-29MAR24-65000-C-option4572.5223940793.825
............
1511deribit-ETH-27DEC24-6000-P-option1.02622.57
1599deribit-ETH-27SEP24-7500-P-option1.02622.53
1593deribit-ETH-27SEP24-6000-P-option1.02622.52
1177deribit-ETH-15FEB24-2200-P-option1.02622.37
1737deribit-ETH-29MAR24-5000-P-option1.02622.27

1387 rows × 3 columns

asset_deribit_oi = deribit_current[['market','expiration','strike','option_contract_type']]
oi_merged = pd.merge(asset_deribit_oi, oi_only, on="market").drop_duplicates()
oi_merged
marketexpirationstrikeoption_contract_typecontract_countvalue_usd
0deribit-BTC-12FEB24-48750-C-option2024-02-12T08:00:00.000000000Z48750call61.32959931.187
1deribit-BTC-12FEB24-48750-P-option2024-02-12T08:00:00.000000000Z48750put4.7226944.294
2deribit-BTC-12FEB24-49000-C-option2024-02-12T08:00:00.000000000Z49000call141.16813157.422
3deribit-BTC-12FEB24-49250-C-option2024-02-12T08:00:00.000000000Z49250call6.6318687.732
4deribit-BTC-12FEB24-49500-C-option2024-02-12T08:00:00.000000000Z49500call28.61380979.028
.....................
820deribit-BTC-27DEC24-120000-P-option2024-12-27T08:00:00.000000000Z120000put1.363681.397
821deribit-BTC-27DEC24-125000-C-option2024-12-27T08:00:00.000000000Z125000call37.91856453.805
822deribit-BTC-27DEC24-125000-P-option2024-12-27T08:00:00.000000000Z125000put1.678372.704
823deribit-BTC-27DEC24-10000-P-option2024-12-27T08:00:00.000000000Z10000put20.71013795.748
824deribit-BTC-27DEC24-28000-P-option2024-12-27T08:00:00.000000000Z28000put132.16470647.695

825 rows × 6 columns

oi_merged.expiration = pd.to_datetime(oi_merged.expiration).dt.strftime('%b %d, %Y')
oi_merged
marketexpirationstrikeoption_contract_typecontract_countvalue_usd
0deribit-BTC-12FEB24-48750-C-optionFeb 12, 202448750call61.32959931.187
1deribit-BTC-12FEB24-48750-P-optionFeb 12, 202448750put4.7226944.294
2deribit-BTC-12FEB24-49000-C-optionFeb 12, 202449000call141.16813157.422
3deribit-BTC-12FEB24-49250-C-optionFeb 12, 202449250call6.6318687.732
4deribit-BTC-12FEB24-49500-C-optionFeb 12, 202449500call28.61380979.028
.....................
820deribit-BTC-27DEC24-120000-P-optionDec 27, 2024120000put1.363681.397
821deribit-BTC-27DEC24-125000-C-optionDec 27, 2024125000call37.91856453.805
822deribit-BTC-27DEC24-125000-P-optionDec 27, 2024125000put1.678372.704
823deribit-BTC-27DEC24-10000-P-optionDec 27, 202410000put20.71013795.748
824deribit-BTC-27DEC24-28000-P-optionDec 27, 202428000put132.16470647.695

825 rows × 6 columns

oi_merged_sum = oi_merged.groupby(
['expiration', 'option_contract_type']).value_usd.sum().reset_index()
oi_merged_sum
expirationoption_contract_typevalue_usd
0Apr 26, 2024call746759409.804
1Apr 26, 2024put362391927.898
2Dec 27, 2024call327845484.001
3Dec 27, 2024put76852459.777
4Feb 12, 2024call61221827.396
5Feb 12, 2024put53636084.351
6Feb 13, 2024call60612528.457
7Feb 13, 2024put55888112.274
8Feb 14, 2024call62115453.667
9Feb 14, 2024put47578321.782
10Feb 15, 2024call15652452.769
11Feb 15, 2024put19036582.686
12Feb 16, 2024call486055096.137
13Feb 16, 2024put407674392.781
14Feb 23, 2024call1849252067.898
15Feb 23, 2024put1101826630.192
16Jun 28, 2024call1703153232.984
17Jun 28, 2024put446922981.015
18Mar 01, 2024call150328051.677
19Mar 01, 2024put105881633.482
20Mar 29, 2024call2641595742.536
21Mar 29, 2024put1245411237.802
22Sep 27, 2024call480871248.568
23Sep 27, 2024put169771991.037
calls_oi = pd.DataFrame(oi_merged_sum.loc[oi_merged_sum['option_contract_type'] == 'call'])
puts_oi = pd.DataFrame(oi_merged_sum.loc[oi_merged_sum['option_contract_type'] == 'put'])
# Convert 'expiration' to datetime and extract month
calls_oi['expiration'] = pd.to_datetime(calls_oi['expiration'])
calls_oi['Expiration Month'] = calls_oi['expiration'].dt.month

puts_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 index
calls_oi_df = calls_oi_grouped.reset_index()
puts_oi_df = puts_oi_grouped.reset_index()

# Replace month numbers with month names
calls_oi_df['Expiration Month'] = calls_oi_df['Expiration Month'].apply(lambda x: calendar.month_name[x])
puts_oi_df['Expiration Month'] = puts_oi_df['Expiration Month'].apply(lambda x: calendar.month_name[x])
calls_oi_df
Expiration Monthvalue_usd
0February2534909426.324
1March2791923794.213
2April746759409.804
3June1703153232.984
4September480871248.568
5December327845484.001
# Add a new column to distinguish between calls and puts
calls_oi_df['type'] = 'calls'
puts_oi_df['type'] = 'puts'

# Concatenate the dataframes
df = pd.concat([calls_oi_df, puts_oi_df])
df = df.rename(columns={"value_usd": "Open Interest (USD)"})

# Plot the bars side by side
p = 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 billions
fmt = '${x:,.0f}B'
p.legend_.remove()

tick = mtick.FuncFormatter(lambda x, 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.