{"record":{"id":"f98c5b6cb57bc4e1","repo":"nautechsystems/nautilus_trader","slug":"binance-spot-supports-l1-mbp-and-l2-mbp-order-book","errorCode":null,"errorMessage":"Binance Spot supports L1_MBP and L2_MBP order book subscriptions","messagePattern":"Binance Spot supports L1_MBP and L2_MBP order book subscriptions","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/spot/data.rs","lineNumber":1848,"sourceCode":"    fn subscribe_book_deltas(&mut self, cmd: SubscribeBookDeltas) -> anyhow::Result<()> {\n        if cmd.book_type == BookType::L1_MBP {\n            anyhow::ensure!(\n                cmd.depth.is_none_or(|depth| depth.get() == 1),\n                \"Binance Spot L1_MBP supports depth 1 only\"\n            );\n            anyhow::ensure!(\n                !self.book_subscriptions.contains_key(&cmd.instrument_id),\n                \"cannot subscribe L1_MBP and L2_MBP for the same Binance Spot instrument\"\n            );\n            self.l1_book_subscriptions.rcu(|subscriptions| {\n                *subscriptions.entry(cmd.instrument_id).or_insert(0) += 1;\n            });\n            self.subscribe_top_of_book(cmd.instrument_id);\n            return Ok(());\n        }\n\n        if cmd.book_type != BookType::L2_MBP {\n            anyhow::bail!(\"Binance Spot supports L1_MBP and L2_MBP order book subscriptions\");\n        }\n        anyhow::ensure!(\n            !self.l1_book_subscriptions.contains_key(&cmd.instrument_id),\n            \"cannot subscribe L1_MBP and L2_MBP for the same Binance Spot instrument\"\n        );\n\n        let instrument_id = cmd.instrument_id;\n        let ws = self.ws_client.clone();\n        let symbol_lower = instrument_id.symbol.as_str().to_lowercase();\n\n        if self.spot_market_data_mode == BinanceSpotMarketDataMode::Json && cmd.depth.is_some() {\n            // Explicit depth requests use partial-book streams. Full-depth JSON\n            // subscriptions fall through to the REST snapshot + @depth diff path.\n            let depth_level = match cmd.depth.map(|d| d.get()) {\n                Some(1..=5) => 5,\n                Some(6..=10) => 10,\n                _ => 20,\n            };","sourceCodeStart":1830,"sourceCodeEnd":1866,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/spot/data.rs#L1830-L1866","documentation":"`subscribe_book_deltas` for Binance Spot only supports depth-1 (L1_MBP, top-of-book) and full L2 depth (L2_MBP) order book subscriptions. Any other book type (e.g. L3_MBP or depth variants Spot does not offer) is rejected with this error before any subscription is made.","triggerScenarios":"Calling `subscribe_book_deltas` with a subscription command whose `book_type` is neither `BookType::L1_MBP` nor `BookType::L2_MBP`; also rejected if an L1 subscription already exists for the instrument and an L2 subscribe is requested (mutually exclusive per instrument).","commonSituations":"Porting a strategy configured for futures (which supports other depth modes) to Spot; a generic data-engine config requesting L3/diff depth on a Spot instrument; mixing L1 and L2 subscriptions for the same instrument in one strategy.","solutions":["Set the subscription book_type to `BookType::L2_MBP` (or L1_MBP) for Binance Spot instruments","Remove any existing L1_MBP subscription for the instrument before requesting L2_MBP, as they are mutually exclusive","Run the strategy against Binance USDT-M Futures instead if a deeper/other book type is required","Add an instrument/exchange guard in strategy config so non-Spot book types are only requested on supported venues"],"exampleFix":"// before\nsubscribe_book_deltas(instrument_id, BookType::L3_MBP);\n// after\nsubscribe_book_deltas(instrument_id, BookType::L2_MBP); // Spot supports L1_MBP/L2_MBP only","handlingStrategy":"validation","validationCode":"fn validate_spot_book_sub(book_type: BookType, instrument_id: InstrumentId,\n                           l1_subs: &HashSet<InstrumentId>) -> Result<(), String> {\n    match book_type {\n        BookType::L1_MBP | BookType::L2_MBP => {},\n        other => return Err(format!(\"{other:?} not supported on Binance Spot\")),\n    }\n    if book_type == BookType::L2_MBP && l1_subs.contains(&instrument_id) {\n        return Err(format!(\"L1 already subscribed for {instrument_id}; unsubscribe first\"));\n    }\n    Ok(())\n}","typeGuard":"fn is_spot_supported_book_type(bt: BookType) -> bool {\n    matches!(bt, BookType::L1_MBP | BookType::L2_MBP)\n}","tryCatchPattern":"match data_engine.subscribe_book_deltas(cmd).await {\n    Err(e) if e.to_string().contains(\"L1_MBP and L2_MBP\") => {\n        log::warn!(\"falling back to L2_MBP for {instrument_id}\");\n        data_engine.subscribe_book_deltas(cmd.with_book_type(BookType::L2_MBP)).await?;\n    }\n    other => other?,\n}","preventionTips":["Restrict order book subscriptions to L1_MBP/L2_MBP when targeting Binance Spot","Do not mix L1 and L2 subscriptions for the same instrument","Keep venue-specific subscription configs separate per exchange (Spot vs Futures)","Centralize subscription building so book_type can be validated in one place"],"tags":["rust","orderbook","subscription","binance","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}