nautechsystems/nautilus_trader · error · anyhow::Error

historical BinanceBar requests require LAST price type

Error message

historical BinanceBar requests require LAST price type

What it means

Binance klines are aggregated from last-trade prices only, so historical BinanceBar requests only support PriceType::Last. A requested BarType whose price type is Bid, Mid, or Mark is rejected because the venue cannot serve that aggregation.

Source

Thrown at crates/adapters/binance/src/spot/data.rs:2246

        });

        Ok(())
    }

    fn request_data(&self, request: RequestCustomData) -> anyhow::Result<()> {
        if request.data_type.type_name() != "BinanceBar" {
            log::warn!(
                "Unsupported custom data request: {}",
                request.data_type.type_name()
            );
            return Ok(());
        }
        let bar_type = parse_binance_bar_type(&request.data_type)?;
        anyhow::ensure!(
            bar_type.aggregation_source() == AggregationSource::External,
            "historical BinanceBar requests require EXTERNAL aggregation"
        );
        anyhow::ensure!(
            bar_type.spec().price_type == PriceType::Last,
            "historical BinanceBar requests require LAST price type"
        );
        anyhow::ensure!(
            bar_type.spec().is_time_aggregated(),
            "historical BinanceBar requests require time aggregation"
        );
        let http = self.http_client.clone();
        let sender = self.data_sender.clone();
        let request_id = request.request_id;
        let client_id = request.client_id;
        let data_type = request.data_type;
        let start = request.start;
        let end = request.end;
        let limit = request.limit.map(|value| value.get() as u32);
        let params = request.params;
        let clock = self.clock;
        let venue = self.venue();

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Use a LAST price type for BinanceBar requests, e.g. 'BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL'
  2. If you need BID/MID history, subscribe to book data and aggregate those bars yourself instead of requesting venue klines

Example fix

# before
bar_type = BarType.from_str("BTCUSDT.BINANCE-1-MINUTE-BID-EXTERNAL")

# after
bar_type = BarType.from_str("BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL")
Defensive patterns

Strategy: validation

Validate before calling

from nautilus_trader.model.data import BarType, PriceType

def is_last_price_bar(bar_type: BarType) -> bool:
    return bar_type.spec.price_type == PriceType.LAST

assert is_last_price_bar(bar_type), "BinanceBar history requires LAST price type"

Type guard

def is_last_price_bar(bar_type) -> bool:
    return bar_type.spec.price_type == PriceType.LAST

Prevention

When it happens

Trigger: request_data for BinanceBar with bar_type.spec().price_type != Last, e.g. 'BTCUSDT.BINANCE-1-MINUTE-BID-EXTERNAL' or a MID/Mark variant.

Common situations: Porting bar configurations from venues that offer bid/mid candles; reusing a strategy's signal BarType (often MID for FX habits) directly for crypto backfills.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/8c7c78368fbb0b73. Report an issue: GitHub.