Skip to content

core.instruments

Tick size, tick value and contract specifications — the numbers that convert a price move into dollars.

instruments

Instrument specifications: tick economics, venue, session class, cap weight.

The runtime source of truth for tick size/value is the SDK ContractModel; the built-in SPECS table is the offline reference (and consistency check) for the products commonly traded on Topstep. point_value is always derived as tick_value / tick_size and the triple is asserted consistent on load.

Position caps count micro-units: a mini counts 10, a micro counts 1 (Topstep's 10:1 ratio), so cap math is pure integer arithmetic.

SPECS module-attribute

SPECS: dict[str, InstrumentSpec] = {sym: _spec(sym, venue, sess, tick, value, micro=micro, expect_point=point) for sym, venue, sess, tick, value, micro, point in _TABLE}

Venue

Bases: StrEnum

Exchange within CME Group (matters for calendars and fees).

CME class-attribute instance-attribute

CME = 'CME'

CBOT class-attribute instance-attribute

CBOT = 'CBOT'

NYMEX class-attribute instance-attribute

NYMEX = 'NYMEX'

COMEX class-attribute instance-attribute

COMEX = 'COMEX'

SessionClass

Bases: StrEnum

Asset-class RTH template (ET). Globex hours are shared by all.

EQUITY class-attribute instance-attribute

EQUITY = 'EQUITY'

ENERGY class-attribute instance-attribute

ENERGY = 'ENERGY'

GOLD class-attribute instance-attribute

GOLD = 'GOLD'

SILVER class-attribute instance-attribute

SILVER = 'SILVER'

InstrumentSpec

Bases: Struct

Frozen per-product economics and session metadata.

cap_units is the product's weight toward Topstep's position cap in micro-units (mini=10, micro=1).

symbol instance-attribute

symbol: str

venue instance-attribute

venue: Venue

session_class instance-attribute

session_class: SessionClass

tick_size instance-attribute

tick_size: Decimal

tick_value instance-attribute

tick_value: Decimal

is_micro instance-attribute

is_micro: bool

point_value property

point_value: Decimal

Dollars per full 1.00 price move (= tick_value / tick_size).

cap_units property

cap_units: int

Weight toward the position cap in micro-units (mini=10, micro=1).

symbol_of_contract_id

symbol_of_contract_id(contract_id: str) -> str

Extract the product symbol from a gateway contract id.

"CON.F.US.MNQ.U26" -> "MNQ"; a bare symbol passes through unchanged.

Source code in src/topstep_backtest/core/instruments.py
def symbol_of_contract_id(contract_id: str) -> str:
    """Extract the product symbol from a gateway contract id.

    ``"CON.F.US.MNQ.U26"`` -> ``"MNQ"``; a bare symbol passes through unchanged.
    """
    parts = contract_id.split(".")
    if len(parts) >= 4 and parts[0] == "CON":
        return parts[3]
    if len(parts) == 3 and parts[0] == "F":  # symbol_id form "F.US.MNQ"
        return parts[2]
    return contract_id

spec_for_symbol

spec_for_symbol(symbol: str) -> InstrumentSpec

Look up the built-in spec for a product symbol (raises KeyError if unknown).

Source code in src/topstep_backtest/core/instruments.py
def spec_for_symbol(symbol: str) -> InstrumentSpec:
    """Look up the built-in spec for a product symbol (raises KeyError if unknown)."""
    return SPECS[symbol]

spec_for_contract

spec_for_contract(contract: ContractModel) -> InstrumentSpec

Build a spec from a live SDK ContractModel, validated against the table.

The contract's tick_size/tick_value are authoritative; if the symbol is in SPECS the values must agree (a mismatch means the reference table is stale and must be corrected — a silent override would corrupt P&L).

Source code in src/topstep_backtest/core/instruments.py
def spec_for_contract(contract: ContractModel) -> InstrumentSpec:
    """Build a spec from a live SDK ``ContractModel``, validated against the table.

    The contract's ``tick_size``/``tick_value`` are authoritative; if the symbol
    is in ``SPECS`` the values must agree (a mismatch means the reference table
    is stale and must be corrected — a silent override would corrupt P&L).
    """
    symbol = symbol_of_contract_id(contract.symbol_id or contract.id)
    reference = SPECS.get(symbol)
    if reference is not None:
        if (contract.tick_size, contract.tick_value) != (
            reference.tick_size,
            reference.tick_value,
        ):
            raise ValueError(
                f"{symbol}: gateway tick economics ({contract.tick_size}, {contract.tick_value})"
                f" disagree with reference table ({reference.tick_size}, {reference.tick_value})"
            )
        return reference
    # Unknown product: trust the gateway's tick economics, default conservative
    # metadata, and treat it as a mini (cap-weight 10) so position caps are
    # never accidentally loosened for an unrecognized symbol.
    return InstrumentSpec(
        symbol=symbol,
        venue=Venue.CME,
        session_class=SessionClass.EQUITY,
        tick_size=contract.tick_size,
        tick_value=contract.tick_value,
        is_micro=False,
    )