nautechsystems/nautilus_trader · error · anyhow::Error
historical BinanceBar requests require time aggregation
Error message
historical BinanceBar requests require time aggregation
What it means
The Binance Spot data client only serves historical bars that Binance actually provides: exchange-native klines, which exist solely for time-based intervals. Before dispatching a BinanceBar custom-data request it parses the bar_type from the DataType metadata and calls BarSpecification::is_time_aggregated(), rejecting threshold-driven aggregations (TICK, VOLUME, VALUE and their imbalance variants) because no Binance endpoint can return such history.
Source
Thrown at crates/adapters/binance/src/spot/data.rs:2250
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();
let start_nanos = datetime_to_unix_nanos(start);
let end_nanos = datetime_to_unix_nanos(end);
get_runtime().spawn(async move {View on GitHub (pinned to a4b06ed870)
Solutions
- Use a time-based aggregation that maps to a Binance kline interval (SECOND/MINUTE/HOUR/DAY), e.g. 'BTCUSDT_BINANCE-1-MINUTE-LAST-EXTERNAL'
- If you need tick/volume/value bars, subscribe to TradeTicks or QuoteTicks and aggregate locally with an INTERNAL bar type
- Pre-validate bar_type.spec().is_time_aggregated() in your own code before issuing the request
Example fix
// before
let bar_type = BarType::from_str("BTCUSDT_BINANCE-10000-TICK-LAST-EXTERNAL")?;
client.request_bars(...)?; // -> requires time aggregation
// after: kline interval Binance actually serves
let bar_type = BarType::from_str("BTCUSDT_BINANCE-1-MINUTE-LAST-EXTERNAL")?; Defensive patterns
Strategy: validation
Validate before calling
fn ensure_binance_requestable(bar_type: &BarType) -> anyhow::Result<()> {
anyhow::ensure!(
bar_type.spec().is_time_aggregated(),
"bar type {bar_type} is not time-aggregated; Binance only serves klines"
);
Ok(())
}
// call before request_bars / BinanceBar custom data requests Type guard
fn is_time_aggregated_bar(bar_type: &BarType) -> bool {
bar_type.spec().is_time_aggregated()
} Prevention
- Define bar type strings once as consts and lint them against the venue's kline intervals
- Treat TICK/VOLUME/VALUE aggregations as locally-computed only; never request their history from Binance
- Validate the full triple (time-aggregated, LAST, EXTERNAL) in one helper at strategy start
When it happens
Trigger: Issuing a BinanceBar custom-data / request_bars call whose bar_type metadata is a non-time spec, e.g. 'BTCUSDT_BINANCE-10000-TICK-LAST-EXTERNAL' or 'ETHUSDT_BINANCE-500-VOLUME-LAST-EXTERNAL'. The ensure! at spot/data.rs:2250 fires synchronously, before any HTTP request is spawned.
Common situations: Porting a strategy from a venue that serves tick-bar or volume-bar history; reusing a BarType string that was built for Nautilus's internal aggregator; generating bar specs programmatically without filtering BarAggregation variants.
Related errors
- Binance historical bars require time aggregation
- historical BinanceBar requests require EXTERNAL aggregation
- historical BinanceBar requests require LAST price type
- Binance historical bars require EXTERNAL aggregation
- Binance historical bars require LAST price type
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/90f26a953c0220aa.
Report an issue: GitHub.