nautechsystems/nautilus_trader · error · anyhow::Error
Spot ticker requires a BINANCE instrument
Error message
Spot ticker requires a BINANCE instrument
What it means
For a BinanceSpotTicker custom data subscription, the DataType metadata must include an instrument_id whose venue equals the data client's venue (BINANCE for Spot). Any other venue in the metadata (a typo, another exchange, or a synthetic venue) is rejected by this check.
Source
Thrown at crates/adapters/binance/src/spot/data.rs:1773
fn is_disconnected(&self) -> bool {
!self.is_connected()
}
fn subscribe(&mut self, cmd: SubscribeCustomData) -> anyhow::Result<()> {
if cmd.data_type.type_name() != "BinanceSpotTicker" {
log::warn!(
"Unsupported custom data subscription: {}",
cmd.data_type.type_name()
);
return Ok(());
}
anyhow::ensure!(
self.spot_market_data_mode == BinanceSpotMarketDataMode::Json,
"Binance Spot 24-hour ticker custom data requires JSON market-data mode"
);
let instrument_id = Self::required_instrument_id_metadata(&cmd.data_type)?;
anyhow::ensure!(
instrument_id.venue == self.venue(),
"Spot ticker requires a BINANCE instrument"
);
let should_subscribe = {
let previous = self
.ticker_refs
.load()
.get(&instrument_id)
.copied()
.unwrap_or(0);
self.ticker_refs
.rcu(|refs| *refs.entry(instrument_id).or_insert(0) += 1);
previous == 0
};
if should_subscribe {
let ws = self.ws_client.clone();
let stream = format!("{}@ticker", instrument_id.symbol.as_str().to_lowercase());View on GitHub (pinned to a4b06ed870)
Solutions
- Set the DataType metadata instrument_id to a BINANCE-venue instrument, e.g. 'BTCUSDT.BINANCE'
- If routing between venues, verify the venue suffix is derived from the target adapter before constructing the custom data type
Example fix
# before
data_type = DataType(
name="BinanceSpotTicker",
metadata={"instrument_id": "BTCUSDT.BYBIT"}, # wrong venue
)
# after
from nautilus_trader.model.identifiers import InstrumentId
data_type = DataType(
name="BinanceSpotTicker",
metadata={"instrument_id": str(InstrumentId.from_str("BTCUSDT.BINANCE"))},
) Defensive patterns
Strategy: type-guard
Validate before calling
from nautilus_trader.model.identifiers import InstrumentId
def is_binance_instrument(instrument_id: str) -> bool:
return InstrumentId.from_str(instrument_id).venue == "BINANCE" Type guard
def is_binance_instrument(instrument_id: str) -> bool:
from nautilus_trader.model.identifiers import InstrumentId
try:
return InstrumentId.from_str(instrument_id).venue == "BINANCE"
except ValueError:
return False Prevention
- Derive instrument IDs from the adapter's instrument provider instead of hand-building strings
- In multi-venue setups, assert the venue suffix matches the target adapter before subscribing
When it happens
Trigger: Subscribing to BinanceSpotTicker custom data whose instrument_id metadata reads e.g. 'BTCUSDT.BYBIT' or 'BTCUSDT.BINANCE_SPOT' instead of a BINANCE-venue instrument ID.
Common situations: Copy-pasting subscription setup from another adapter; constructing the DataType metadata manually with a wrong venue string; multi-venue routing code applying the wrong venue suffix.
Related errors
- invalid Binance load_ids value {raw:?}: {e}
- custom data request requires `instrument_id` metadata
- Binance Spot L1_MBP supports depth 1 only
- Binance Spot supports L1_MBP and L2_MBP order book subscript
- historical BinanceBar requests require EXTERNAL aggregation
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/dbbf7a67dab73246.
Report an issue: GitHub.