A scale of 0.01 reads as cents when unit_of_measure is a physical unit, and as percent of par when it is a currency, as it is for treasuries.
Computing tick value and contract notional
Overview
The value of a tick and the notional value of a contract can be derived from the contract and tick size in the definition schema. E-mini S&P 500 futures are quoted in index points, crude oil in dollars per barrel, lean hogs in cents per pound, and corn in cents per bushel. In this example we will use the Historical client to derive this information from the definition schema and convert daily closes into contract values.
Definition schema
| Field | Description |
|---|---|
unit_of_measure |
The unit the contract is measured in, such as BBL for barrels or LBS for pounds. |
unit_of_measure_qty |
The contract size, in the unit_of_measure. |
min_price_increment |
The minimum tick size, in price units. |
min_price_increment_amount |
The value of one tick, with the display factor applied. |
display_factor |
The multiplier from the venue's display price to the conventional price. |
Three steps take you from these fields to a tick value and a contract value.
scale = (min_price_increment_amount / display_factor) / (min_price_increment * unit_of_measure_qty)
tick_value = min_price_increment * unit_of_measure_qty * scale
notional = close * unit_of_measure_qty * scale
scale is the multiplier that turns close * unit_of_measure_qty into the currency named by currency.
A value of 1 means the price is already in that currency's major unit per unit of measure, as for E-mini S&P 500 futures at 7740.00 index points with a contract size of 50, giving a notional of 387,000 USD.
A value of 0.01 means the price is in hundredths, as for lean hogs at 81.50 cents per pound with a contract size of 40,000 pounds, giving 32,600 USD.
Info
Fractionally quoted products
CME does not publish a usable min_price_increment_amount for the products it quotes in fractions.
Corn reports 1.0 against a real tick value of 12.50 USD, and the 10-year note reports 0.001 against 15.625 USD.
These products have fractional pricing, and they are quoted in hundredths:
grains are cents per bushel and treasuries are percent of par, so a scale of 0.01 applies to both.
Taking that value gives the correct tick value and notional for both.
All fractionally-priced products in CME are listed on CBOT (exchange=XCBT), but there are many non-fractionally priced future assets on CBOT.
Example
import math
import databento as db
# A mix of products quoted in the currency's major unit and in cents
symbols = ["ESU6", "CLV6", "GCZ6", "6EU6", "HEV6", "ZLZ6", "MZCZ6", "ZCZ6", "ZNZ6"]
dataset = "GLBX.MDP3"
date = "2026-08-19"
# Value when unset or null
UNSET = 255
def price_scale(
main_fraction,
min_price_increment,
min_price_increment_amount,
display_factor,
unit_of_measure_qty,
):
"""Return the multiplier from price * unit_of_measure_qty to the currency."""
# Fractionally quoted products are priced in hundredths
if main_fraction != UNSET:
return 0.01
tick_value = min_price_increment_amount / display_factor
# One tick moves the contract by one tick value
scale = tick_value / (min_price_increment * unit_of_measure_qty)
# A usable scale is a power of ten. Reject anything else
exponent = round(math.log10(scale))
if not math.isclose(scale, 10.0**exponent, rel_tol=1e-9):
return None
return 10.0**exponent
# First, create a historical client
client = db.Historical(key="YOUR_API_KEY")
# Next, retrieve the instrument definitions
definitions = client.timeseries.get_range(
dataset=dataset,
schema="definition",
symbols=symbols,
start=date,
).to_df()
# And extract the fields that describe the contract size and the tick
definitions = definitions.loc[definitions["instrument_class"] == db.InstrumentClass.FUTURE]
contracts = definitions.drop_duplicates("raw_symbol").set_index("instrument_id")[
[
"raw_symbol",
"unit_of_measure",
"unit_of_measure_qty",
"main_fraction",
"min_price_increment",
"min_price_increment_amount",
"display_factor",
]
]
# Then, request daily bars
bars = client.timeseries.get_range(
dataset=dataset,
schema="ohlcv-1d",
symbols=symbols,
start=date,
).to_df()
# And join the bars with the contract terms of each instrument
df = bars.join(contracts, on="instrument_id").sort_values("raw_symbol")
# Now, derive the price scale of each contract
df["scale"] = df.apply(
lambda row: price_scale(
row["main_fraction"],
row["min_price_increment"],
row["min_price_increment_amount"],
row["display_factor"],
row["unit_of_measure_qty"],
),
axis=1,
)
# Finally, convert one tick and each close price into currency
df["tick_value"] = df["min_price_increment"] * df["unit_of_measure_qty"] * df["scale"]
df["notional"] = df["close"] * df["unit_of_measure_qty"] * df["scale"]
print(
df[[
"raw_symbol",
"unit_of_measure",
"unit_of_measure_qty",
"close",
"tick_value",
"scale",
"notional",
]],
)
Result
raw_symbol unit_of_measure unit_of_measure_qty close tick_value scale notional
ts_event
2026-08-19 00:00:00+00:00 6EU6 EUR 125000.0 1.168450 6.250 1.00 146056.250
2026-08-19 00:00:00+00:00 CLV6 BBL 1000.0 84.300000 10.000 1.00 84300.000
2026-08-19 00:00:00+00:00 ESU6 IPNT 50.0 7740.000000 12.500 1.00 387000.000
2026-08-19 00:00:00+00:00 GCZ6 TRYOZ 100.0 4569.200000 10.000 1.00 456920.000
2026-08-19 00:00:00+00:00 HEV6 LBS 40000.0 81.500000 10.000 0.01 32600.000
2026-08-19 00:00:00+00:00 MZCZ6 BU 500.0 498.000000 2.500 0.01 2490.000
2026-08-19 00:00:00+00:00 ZCZ6 BU 5000.0 498.250000 12.500 0.01 24912.500
2026-08-19 00:00:00+00:00 ZLZ6 LBS 60000.0 69.860000 6.000 0.01 41916.000
2026-08-19 00:00:00+00:00 ZNZ6 USD 100000.0 108.578125 15.625 0.01 108578.125