Skip to content

Data Contracts

Column-list constants and validators defining the DataFrame contracts at package boundaries (replaces the old Pydantic models.py). Validators check that the required columns are present and that the events and trades columns have the dtypes in EVENT_DTYPES and TRADE_DTYPES; extra columns are allowed.

validate_events_df

validate_events_df(df: DataFrame) -> None

Raise :class:ConfigError unless df has all :data:EVENT_COLUMNS, each column named in :data:EVENT_DTYPES with its dtype.

validate_trades_df

validate_trades_df(df: DataFrame) -> None

Raise :class:ConfigError unless df has all :data:TRADE_COLUMNS, each column named in :data:TRADE_DTYPES with its dtype.

validate_depth_df

validate_depth_df(df: DataFrame) -> None

Raise :class:ConfigError unless df has all :data:DEPTH_COLUMNS.

EVENT_DTYPES module-attribute

EVENT_DTYPES: dict[str, str | CategoricalDtype] = {
    "event_id": "int64",
    "id": "int64",
    "timestamp": UTC_NS_DTYPE,
    "exchange_timestamp": UTC_NS_DTYPE,
    "price": "int64",
    "volume": "int64",
    "direction": BOOK_SIDE_DTYPE,
    "action": ACTION_DTYPE,
    "fill": "int64",
    "type": ORDER_TYPE_DTYPE,
    "original_number": "int64",
    "raw_event_type": "object",
}

Dtype of each column of the events table: :data:EVENT_COLUMNS plus the provenance columns every loader carries. Prices are integer ticks and sizes integer lots.

TRADE_DTYPES module-attribute

TRADE_DTYPES: dict[str, str | CategoricalDtype] = {
    "timestamp": UTC_NS_DTYPE,
    "price": "int64",
    "volume": "int64",
    "direction": TRADE_SIDE_DTYPE,
    "maker_event_id": "Int64",
    "taker_event_id": "Int64",
    "maker": "object",
    "taker": "object",
    "maker_og": "Int64",
    "taker_og": "Int64",
}

Dtype of each column of the trades table: :data:TRADE_COLUMNS plus the maker and taker provenance columns. direction is null on an L2 feed until trade signing fills it.

cast_events

cast_events(df: DataFrame) -> pd.DataFrame

Return the events frame df cast through :data:EVENT_DTYPES.

Every event loader builds its output through this. Text order ids (UUIDs, say) stay text, as object; any other id column is cast to int64.

MAYBE_BAD_BOOK_ATTR module-attribute

MAYBE_BAD_BOOK_ATTR: str = 'maybe_bad_book_records'

Events attrs key for the count of records the venue flagged as coming after a gap it could not repair, so the book may be wrong from there on.

Databento sets the flag F_MAYBE_BAD_BOOK on such records; :class:~ob_analytics.databento.DatabentoLoader puts the count here, and :func:~ob_analytics.analytics.data_quality_summary reads it. A frame without the key comes from a source that does not flag such records, so the count was not checked.