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

Historical BinanceBar requests must use the LAST (trade) price type, since Binance klines are built from trades. Other price types (MID, BID, ASK) have no Binance REST kline equivalent, so the request is rejected after the aggregation-source check.

Solutions

  1. Set the bar spec price type to PriceType::Last for historical BinanceBar requests
  2. Use a different data request (e.g. quotes/ticks) if bid/ask-based history is needed
  3. Separate live bar configs (any price type, internal) from historical request configs (LAST, external)

Example fix

// before
BarSpecification::new(1, BarAggregation::Minute, PriceType::Bid)
// after
BarSpecification::new(1, BarAggregation::Minute, PriceType::Last)
Defensive patterns

Strategy: validation

Validate before calling

fn can_request_binance_bar_history(bar_type: &BarType) -> bool {
    bar_type.spec().price_type == PriceType::Last
}

Type guard

fn is_last_price_bar(bt: &BarType) -> bool {
    bt.spec().price_type == PriceType::Last
}

Try / catch

match client.request_data(request) {
    Err(e) if e.to_string().contains("LAST price type") => {
        let last_bar = rebuild_bar_type(request.bar_type, PriceType::Last);
        client.request_data(request.with_bar_type(last_bar))?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Sending RequestCustomData for "BinanceBar" where bar_type.spec().price_type is not PriceType::Last (e.g. Bid or Ask bars).

Common situations: Strategies using bid/ask bars live attempting the same bar type for backfill; generic historical-request code that forwards the strategy's configured price type; copying spot configs where quote-side bars exist.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/futures/data.rs:2682

        Ok(())
    }

    /// Requests Binance futures custom data.
    ///
    /// Spawned fetch failures are logged and no response is emitted, matching
    /// the existing request-path behavior for other Binance adapter requests.
    fn request_data(&self, request: RequestCustomData) -> anyhow::Result<()> {
        let data_type = request.data_type.clone();
        let data_type_name = data_type.type_name().to_string();

        if data_type_name == "BinanceBar" {
            let bar_type = parse_binance_bar_type(&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 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();
            let start_nanos = datetime_to_unix_nanos(start);

View on GitHub (pinned to 18893faf8b)