Skip to content

L2 (price-level) depth

Price-level (L2 / market-by-price) components: the depth loader, trade reader, CSV writer, and DepthCsvSource. For the guide, see Process L2 feeds.

A price-level feed carries [price, quantity] levels and diffs with no order IDs, so the loader yields the depth frame directly and the pipeline skips the per-order stages (see Level).

L2DepthLoader

L2DepthLoader(
    config: PipelineConfig | None = None,
    *,
    venue: str | None = None,
    symbol: str | None = None,
)

Load a price-level depth stream into the canonical depth frame.

Satisfies the :class:~ob_analytics.protocols.DepthSource protocol.

Parameters:

Name Type Description Default
config PipelineConfig

Pipeline configuration. price_divisor scales the raw feed price to the quote currency and tick_size quantises it to integer ticks; volume_decimals rounds size; timestamp_unit interprets integer-epoch timestamps.

None
venue str

Optional instrument identity. When either is supplied, the loaded depth frame gains per-row venue / symbol columns. A generic price-level CSV carries no venue of its own, so venue is left NA unless supplied. Both None (the default) leaves the frame untagged.

None
symbol str

Optional instrument identity. When either is supplied, the loaded depth frame gains per-row venue / symbol columns. A generic price-level CSV carries no venue of its own, so venue is left NA unless supplied. Both None (the default) leaves the frame untagged.

None

load

load(source: str | Path) -> pd.DataFrame

Read source and return a canonical depth DataFrame.

Parameters:

Name Type Description Default
source str or Path

The L2 CSV file, or a directory containing depth.csv.

required

Returns:

Type Description
DataFrame

Columns timestamp, price, volume (absolute level size), direction (categorical bid/ask), sorted by timestamp — a :func:~ob_analytics.schemas.validate_depth_df frame.

L2TradeReader

L2TradeReader(config: PipelineConfig | None = None)

Read raw trade prints from a companion trades.csv.

Projects each print into the canonical trades schema. Price-level feeds have no order IDs, so maker / taker (and their event-id / og columns) are left unset. direction (the taker's aggressor side) is taken from a native side column when present; otherwise it is left unlabelled and the pipeline classifies it (Lee–Ready against the reconstructed BBO — see :meth:~ob_analytics.pipeline.Pipeline._ensure_trade_signs).

Trades are optional for an L2 run: a missing / empty trades.csv yields an empty trades frame (depth analytics still run).

Satisfies the :class:~ob_analytics.protocols.TradeSource protocol.

DepthCsvWriter

DepthCsvWriter(config: PipelineConfig | None = None)

Write a depth frame (and trades) back to the L2 CSV schema.

Round-trips :class:L2DepthLoader / :class:L2TradeReader: writes depth.csv (and a companion trades.csv when trades are supplied) into the dest directory.

Satisfies the :class:~ob_analytics.protocols.DataWriter protocol.

write

write(
    data: dict[str, DataFrame],
    dest: str | Path,
    **kwargs: Any,
) -> Path

Write data['depth'] (and optional data['trades']) to dest.

Parameters:

Name Type Description Default
data dict of str to DataFrame

Must contain a "depth" key (the canonical depth frame). An optional "trades" key triggers a companion trades.csv.

required
dest str or Path

Output directory.

required

Returns:

Type Description
Path

The written depth.csv path.

DepthCsvSource dataclass

DepthCsvSource(
    name: str = "depth_csv",
    level: Level = Level.L2,
    feed_type: FeedType = FeedType.MATCHED_BOOK,
    settings: SourceSettings = SourceSettings(),
)

The canonical L2 (price-level) CSV source — offline depth replay.

Declares :attr:~ob_analytics.protocols.Level.L2, so :class:~ob_analytics.pipeline.Pipeline takes the price-level path: depth in, per-order stages skipped. The shared entry point the aggregated venue connectors (Binance, Kalshi, Polymarket) narrow to domain modelling on top of, and the offline replay target for a live L2 capture (e.g. the depth.csv a :class:~ob_analytics.live.ccxt_source.CcxtSource writes).

Conforms structurally to :class:~ob_analytics.protocols.OfflineSource — no inheritance required.