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
- Change the subscription request to use `BookType::L2_MBP` for OKX instruments.
- If your strategy needs L3 data, use a different venue/data source; OKX does not provide MBO feeds.
- 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
- Always use BookType::L2_MBP for OKX order book subscriptions.
- Centralize venue capability checks in strategy config validation.
- Read the adapter docs table of supported book types per venue before configuring.
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
- Trigger/conditional orders ({order_type:?}) are not supporte
- Trigger/conditional orders ({order_type:?}) are not supporte
- No mark price returned from OKX
- No price limit returned from OKX
- Empty bids array for {instrument_id}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a458fd2b581b1b55.
Report an issue: GitHub.