This article builds off Futures: Introduction and introduces additional concepts to get started with options on futures. If you're new to Databento, see the Quickstart guide.
Options on futures: Introduction
Info
Overview
In this example, we'll demonstrate:
- Using instrument definitions to get symbols, strike prices, and expirations.
- Using parent instrument symbology to fetch an option chain.
Finding an options on futures dataset
Several futures exchanges also provide options on futures. You can follow the
Futures: Introduction guide to get the
dataset ID of such an exchange. For this example, we'll use the CME Globex MDP 3.0
dataset, whose dataset ID is GLBX.MDP3
.
Using instrument definitions to get symbols, strike prices, and expirations
A full list of instrument definitions can be fetched with the definition
schema and
passing in symbols='ALL_SYMBOLS'
to the timeseries.get_range
method.
import databento as db
# Create a historical client
client = db.Historical("YOUR_API_KEY")
# Request definition data
data = client.timeseries.get_range(
dataset="GLBX.MDP3",
schema="definition",
symbols="ALL_SYMBOLS",
start="2023-08-25",
limit=10000,
)
# Convert to DataFrame
df = data.to_df()
print(df[["raw_symbol", "strike_price", "expiration"]])
raw_symbol strike_price expiration
ts_recv
2023-08-25 00:00:00+00:00 OZSH4 C1520 1520.00 2024-02-23 19:20:00+00:00
2023-08-25 00:00:00+00:00 MEOF4-MEOK4 NaN 2024-01-31 19:30:00+00:00
2023-08-25 00:00:00+00:00 LOX4 P250 2.50 2024-10-17 18:30:00+00:00
2023-08-25 00:00:00+00:00 AHMG4 NaN 2024-02-01 04:59:00+00:00
2023-08-25 00:00:00+00:00 OBK4 C29300 2.93 2024-04-25 18:30:00+00:00
... ... ... ...
2023-08-25 00:00:00+00:00 L0BZ3 C-0070 -7.00 2023-12-01 19:00:00+00:00
2023-08-25 00:00:00+00:00 OZNV3 C1135 113.50 2023-09-22 21:00:00+00:00
2023-08-25 00:00:00+00:00 R2AU3 P1970 1970.00 2023-09-11 20:00:00+00:00
2023-08-25 00:00:00+00:00 G1MV3 P2100 2100.00 2023-10-02 17:30:00+00:00
2023-08-25 00:00:00+00:00 CHIG5-WDCG5 NaN 2025-02-24 20:00:00+00:00
[10000 rows x 3 columns]
Note that we used a timeseries method here and the results are indexed in time. These are called point-in-time instrument definitions. Many data providers treat instrument listings and definitions as a static table, so this may initially feel unintuitive if you're new to this approach. However, for options, this is important as new instruments are added intraday as the underlying moves, and knowing the strike prices of these instruments may result in lookahead effects.
Using parent symbology to fetch an option chain
Working with individual raw symbols can be tedious. Many users find it easier to specify the underlying's symbol and fetch all option symbols for that underlying in an option chain at once.
This can be done using our parent symbology
by passing in stype_in="parent"
to your request. For example, we can print all
tick-by-tick trades of quarterly options on ES for a given time range as follows:
import databento as db
# Create a historical client
client = db.Historical("YOUR_API_KEY")
# Request trades data
data = client.timeseries.get_range(
dataset="GLBX.MDP3",
schema="trades",
stype_in="parent",
symbols=["ES.OPT"],
start="2023-08-25T12:00",
end="2023-08-25T13:00",
)
# Convert to DataFrame
df = data.to_df()
print(df[["symbol", "price"]].tail(10))
symbol price
ts_recv
2023-08-25 12:58:44.446885515+00:00 ESU3 P4390 53.25
2023-08-25 12:58:44.447489339+00:00 ESU3 P4410 61.50
2023-08-25 12:58:58.034159513+00:00 ESU3 C4460 30.50
2023-08-25 12:58:58.052849806+00:00 ESU3 P4390 53.25
2023-08-25 12:59:16.789312686+00:00 ESU3 C4500 17.25
2023-08-25 12:59:27.661545003+00:00 ESU3 C4420 49.00
2023-08-25 12:59:28.337200208+00:00 ESU3 P4410 61.50
2023-08-25 12:59:30.609532264+00:00 ESU3 C4460 30.50
2023-08-25 12:59:50.095229136+00:00 ESU3 C4440 39.25
2023-08-25 12:59:50.141519076+00:00 ESU3 P4380 49.25
Special conventions for options on futures on Databento
Most of the conventions for futures will also apply to options on futures.
- Empty levels and null prices. Many option contracts are illiquid and may have an
empty book, especially at the start of day. Empty levels will have null prices and
zero depth. We represent null prices with type max, e.g. 2^63 - 1, as a sentinel value.
Our client libraries will generally replace these sentinel values with a more idiomatic
null representation—for example, if you pass
price_type="float"
(default) in to the DBNStore.to_df method of the Python client, these sentinel values will be replaced withNaN
in the resulting DataFrame. - Intraday listings. Our instrument definitions are timestamped on both historical and live data. This point-in-time treatment is especially useful if you intend to subscribe to and trade new strikes as they get listed; to backtest this, and to avoid lookahead effects of knowing the underlying's future price changes.
See also