nautechsystems/nautilus_trader · error

OKX only supports L2_MBP order book deltas

Error message

OKX only supports L2_MBP order book deltas

What it means

The OKX data client's `subscribe_book_deltas` only supports level-2 market-by-price order book subscriptions. OKX pushes L2 deltas via its `books` channels; any other book type (e.g. L3_MBO) has no corresponding OKX channel, so the adapter rejects the subscription up front with `anyhow::bail!`. Fix the subscription request to use `BookType::L2_MBP`.

Source

Thrown at crates/adapters/okx/src/data.rs:1845

        // Instead, subscribe to the instrument type if not already subscribed
        let instrument_id = cmd.instrument_id;
        let ws = self.public_ws()?.clone();

        self.spawn_ws(
            async move {
                ws.subscribe_instrument(instrument_id)
                    .await
                    .context("instrument type subscription")?;
                Ok(())
            },
            "subscribe_instrument",
        );
        Ok(())
    }

    fn subscribe_book_deltas(&mut self, cmd: SubscribeBookDeltas) -> anyhow::Result<()> {
        if cmd.book_type != BookType::L2_MBP {
            anyhow::bail!("OKX only supports L2_MBP order book deltas");
        }

        if is_okx_spread_symbol(cmd.instrument_id.symbol.as_str()) {
            // Spreads have no incremental book channel; sprd-books5 pushes a full
            // 5-level snapshot, emitted as F_SNAPSHOT deltas to feed the book.
            let instrument_id = cmd.instrument_id;
            let ws = self.business_ws()?.clone();
            let book_channels = Arc::clone(&self.book_channels);
            let book_sync = self.book_sync.clone();
            self.spawn_ws(
                async move {
                    ws.subscribe_spread_book(instrument_id)
                        .await
                        .context("spread book subscription")?;
                    book_channels.insert(instrument_id, OKXBookChannel::SprdBooks5);
                    book_sync.record_subscription(instrument_id, Instant::now());
                    Ok(())
                },

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change the subscription request to use `BookType::L2_MBP` for OKX instruments.
  2. If your strategy needs L3 data, use a different venue/data source; OKX does not provide MBO feeds.
  3. Add a pre-subscription check on `book_type` in strategy config validation to fail fast with a clear message.

Example fix

// before
let cmd = SubscribeBookDeltas::new(instrument_id, BookType::L3_MBO, ...);
data_engine.execute(cmd)?;
// after
let cmd = SubscribeBookDeltas::new(instrument_id, BookType::L2_MBP, ...);
data_engine.execute(cmd)?;
Defensive patterns

Strategy: validation

Validate before calling

if book_type != BookType::L2_MBP {
    return Err(anyhow::anyhow!("OKX requires BookType::L2_MBP for book deltas"));
}
client.subscribe_book_deltas(cmd)?;

Prevention

When it happens

Trigger: Calling `subscribe_book_deltas` with a `SubscribeBookDeltas` command whose `cmd.book_type` is anything other than `BookType::L2_MBP` (e.g. `L3_MBO`), either directly via a data command or through a config/request that sets a non-L2 book type for an OKX instrument.

Common situations: Configuring an order book subscription with `book_type = L3_MBO` copied from another venue adapter (some venues support MBO, OKX does not); generic strategy code that requests the deepest book type available without checking venue support; migrating a strategy from a L3-capable adapter to OKX.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a458fd2b581b1b55. Report an issue: GitHub.