nautechsystems/nautilus_trader · error · anyhow::Error
Binance historical bars require EXTERNAL aggregation
Error message
Binance historical bars require EXTERNAL aggregation
What it means
The standard historical-bars request path (`request_bars`) requires the requested BarType to use `AggregationSource::External`, i.e. exchange-native bars. INTERNAL (client-aggregated) bar types are rejected before the fetch is spawned, because Binance kline endpoints can only return bars the exchange itself computed.
Source
Thrown at crates/adapters/binance/src/futures/data.rs:3002
});
Ok(())
}
fn request_bars(&self, request: RequestBars) -> anyhow::Result<()> {
let http = self.http_client.clone();
let sender = self.data_sender.clone();
let bar_type = request.bar_type;
let start = request.start;
let end = request.end;
let limit = request.limit.map(|n| n.get() as u32);
let request_id = request.request_id;
let client_id = request.client_id.unwrap_or(self.client_id);
let params = request.params;
let clock = self.clock;
let start_nanos = datetime_to_unix_nanos(start);
let end_nanos = datetime_to_unix_nanos(end);
anyhow::ensure!(
bar_type.aggregation_source() == AggregationSource::External,
"Binance historical bars require EXTERNAL aggregation"
);
anyhow::ensure!(
bar_type.spec().price_type == PriceType::Last,
"Binance historical bars require LAST price type"
);
anyhow::ensure!(
bar_type.spec().is_time_aggregated(),
"Binance historical bars require time aggregation"
);
get_runtime().spawn(async move {
let result = http.request_bars(bar_type, start, end, limit).await;
match result.context("failed to request bars from Binance Futures") {
Ok(bars) => {
let response = DataResponse::Bars(BarsResponse::new(View on GitHub (pinned to a4b06ed870)
Solutions
- Request the matching EXTERNAL bar type, e.g. `BTCUSDT-PERP.BINANCE-5-MINUTE-LAST-EXTERNAL`
- Backfill INTERNAL bars by fetching trades/EXTERNAL bars and feeding them through the local aggregator instead of requesting history for the INTERNAL type
Example fix
# before
bar_type = BarType.from_str('BTCUSDT-PERP.BINANCE-5-MINUTE-LAST-INTERNAL')
actor.request_bars(bar_type, start=start_ts)
# after
bar_type = BarType.from_str('BTCUSDT-PERP.BINANCE-5-MINUTE-LAST-EXTERNAL')
actor.request_bars(bar_type, start=start_ts) Defensive patterns
Strategy: validation
Validate before calling
from nautilus_trader.model.enums import AggregationSource
def is_requestable_binance_bar(bar_type) -> bool:
return bar_type.aggregation_source == AggregationSource.EXTERNAL
if not is_requestable_binance_bar(request_bar_type):
raise ValueError(f'{request_bar_type} is INTERNAL; request the matching -EXTERNAL bar type for Binance history') Type guard
def is_external_bar(bar_type) -> bool:
return bar_type.aggregation_source == AggregationSource.EXTERNAL Try / catch
try:
actor.request_bars(bar_type, start=start_ts, end=end_ts)
except Exception as e:
if 'require EXTERNAL aggregation' in str(e):
external = BarType.from_str(str(bar_type).rsplit('-', 1)[0] + '-EXTERNAL')
actor.request_bars(external, start=start_ts, end=end_ts)
else:
raise Prevention
- Backfill only EXTERNAL bar types; warm INTERNAL bars by replaying trades/EXTERNAL bars through the local aggregator
- Add a startup assertion that every bar type used for requests ends in -EXTERNAL
When it happens
Trigger: `request_bars` with a BarType ending in `-INTERNAL`, e.g. `BTCUSDT-PERP.BINANCE-5-MINUTE-LAST-INTERNAL` — typically a bar type registered for client-side aggregation from ticks that is then also used for a history backfill request.
Common situations: Strategy registers INTERNAL bars (e.g. aggregated from trades) and then attempts to backfill the same bar type before live data arrives; config defaults producing INTERNAL bar types; porting workflows from venues that serve arbitrary aggregations.
Related errors
- historical BinanceBar requests require EXTERNAL aggregation
- historical BinanceBar requests require time aggregation
- historical BinanceBar requests require LAST price type
- Binance historical bars require LAST price type
- Only EXTERNAL aggregation is supported
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/ba6786af40d1aded.
Report an issue: GitHub.