Support

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
Info

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.

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