These three fields carry venue-specific meanings. This example applies to GLBX.MDP3, and other datasets may populate them differently, so check the venue documentation before reusing this logic elsewhere.
Displaying fractional prices
Overview
CME quotes its grain and treasury products in fractions rather than decimals.
A 10-year treasury note trading at 108.578125 is quoted as 108'185, i.e. 108 37⁄64,
and corn trading at 498.25 is quoted as 498'2, i.e. 498 2⁄8.
In this example we will use the Historical client
to retrieve instrument definitions and daily bars for several of these products,
then render each close price the way the exchange does.
Definition schema
The definition schema describes the convention with three fields, which CME documents under fractional pricing.
| Field | Description |
|---|---|
main_fraction |
The denominator of the main fraction. 255 when unused. |
sub_fraction |
The denominator of a fraction of one unit of the main fraction. 255 when unused. |
price_display_format |
The number of digits printed to the right of the tick mark. |
sub_fraction subdivides one unit of the main fraction, so the product of the two fields give the finest fraction the venue displays.
For example, a main_fraction of 32 with a sub_fraction of 2 displays halves of a 32nd, or 64ths.
When sub_fraction is unset, the main fraction is the finest unit.
| Product | main_fraction |
sub_fraction |
price_display_format |
Decimal price | Quoted | Interpretation |
|---|---|---|---|---|---|---|
Corn (ZCZ6) |
8 | unset | 1 | 498.25 | 498'2 |
498 2⁄8 |
30-year bond (ZBZ6) |
32 | unset | 2 | 109.5625 | 109'18 |
109 18⁄32 |
10-year note (ZNZ6) |
32 | 2 | 3 | 108.578125 | 108'185 |
108 18⁄32 plus half a 32nd, or 108 37⁄64 |
2-year note (ZTZ6) |
32 | 8 | 3 | 102.9453125 | 102'302 |
102 30⁄32 plus a quarter of a 32nd, or 102 242⁄256 |
price_display_format is the total number of digits printed after the tick mark ('), including one digit for the subdivision when sub_fraction is set.
The last digit is a decimal rendering of the subdivision rather than its numerator, which is why half of a 32nd prints as 5 in 108'185.
That digit is truncated rather than rounded, so a price of 102.9609375, which is 102 and 30 6⁄8 32nds, renders as 102'307 and not 102'308.
The finest displayed fraction can be finer than the instrument's tick.
Corn futures have a min_price_increment of 0.25, or two eighths, so only even digits appear in their final position.
Products quoted in decimals, such as E-mini S&P 500 futures, leave all three fields unset.
Info
Example
import databento as db
# The instruments to display. ESU6 is included to show a decimal-quoted product
symbols = ["ZCZ6", "ZBZ6", "ZNZ6", "ZTZ6", "ESU6"]
dataset = "GLBX.MDP3"
date = "2026-08-19"
# Value when unset or null
UNSET = 255
def display_price(price, main_fraction, sub_fraction, price_display_format):
"""Render a price in the venue's own quoting convention, such as 108'185."""
if main_fraction == UNSET or price_display_format == UNSET:
return f"{price:g}"
whole = int(price)
# The number of main fractions, such as 32nds, in the remainder. Fractional
# prices land on a power-of-two grid, so this arithmetic is exact
ticks = (price - whole) * main_fraction
main = int(ticks)
if sub_fraction == UNSET:
return f"{whole}'{main:0{price_display_format}d}"
# The last digit is the single-digit decimal of the leftover fraction of one main
# fraction, so a half prints as 5 and three quarters as 7
digits = max(price_display_format - 1, 0)
leftover = int((ticks - main) * 10)
return f"{whole}'{main:0{digits}d}{leftover}"
# First, create a historical client
client = db.Historical(key="YOUR_API_KEY")
# Next, retrieve the instrument definitions
definitions_data = client.timeseries.get_range(
dataset=dataset,
schema="definition",
symbols=symbols,
start=date,
)
# And extract the three fields that describe the display convention
definitions_df = definitions_data.to_df()
definitions_df = definitions_df.loc[definitions_df["instrument_class"] == db.InstrumentClass.FUTURE, :]
conventions = definitions_df.drop_duplicates("raw_symbol").set_index("instrument_id")[
["raw_symbol", "main_fraction", "sub_fraction", "price_display_format"]
]
# Then, request daily bars
ohlcv_data = client.timeseries.get_range(
dataset=dataset,
schema="ohlcv-1d",
symbols=symbols,
start=date,
)
# And join the bars with the display convention of each instrument
df = ohlcv_data.to_df().join(conventions, on="instrument_id").sort_values("raw_symbol")
# Finally, render each closing price in the venue's convention
df["decimal_close"] = df["close"]
df["display_close"] = df.apply(
lambda row: display_price(
row["close"],
row["main_fraction"],
row["sub_fraction"],
row["price_display_format"],
),
axis=1,
)
print(
df[[
"raw_symbol",
"decimal_close",
"main_fraction",
"sub_fraction",
"price_display_format",
"display_close",
]],
)
Result
raw_symbol decimal_close main_fraction sub_fraction price_display_format display_close
ts_event
2026-08-19 00:00:00+00:00 ESU6 7740.000000 255 255 255 7740
2026-08-19 00:00:00+00:00 ZBZ6 109.562500 32 255 2 109'18
2026-08-19 00:00:00+00:00 ZCZ6 498.250000 8 255 1 498'2
2026-08-19 00:00:00+00:00 ZNZ6 108.578125 32 2 3 108'185
2026-08-19 00:00:00+00:00 ZTZ6 102.945312 32 8 3 102'302