nautechsystems/nautilus_trader · error
historical BinanceBar requests require EXTERNAL aggregation
Error message
historical BinanceBar requests require EXTERNAL aggregation
What it means
The custom `BinanceBar` historical request path only fetches exchange-native klines. After parsing the bar type from the data type metadata, it requires `AggregationSource::External`; INTERNAL (client-aggregated) bar types are rejected because no Binance endpoint can serve bars the client itself aggregates.
Source
Thrown at crates/adapters/binance/src/futures/data.rs:2632
}
Err(e) => log::error!("Instrument request failed: {e:?}"),
}
});
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);View on GitHub (pinned to a4b06ed870)
Solutions
- Request with an EXTERNAL bar type, e.g. `BTCUSDT-PERP.BINANCE-1-MINUTE-LAST-EXTERNAL`
- If you need INTERNAL bars, subscribe to the EXTERNAL bars or trades and aggregate locally instead of requesting history for the INTERNAL type
Example fix
# before
bar_type = BarType.from_str('BTCUSDT-PERP.BINANCE-1-MINUTE-LAST-INTERNAL')
actor.request_custom_data(DataType(BinanceBar, {'bar_type': str(bar_type)}), ...)
# after
bar_type = BarType.from_str('BTCUSDT-PERP.BINANCE-1-MINUTE-LAST-EXTERNAL')
actor.request_custom_data(DataType(BinanceBar, {'bar_type': str(bar_type)}), ...) 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(bar_type):
raise ValueError(f'{bar_type} is INTERNAL; Binance serves EXTERNAL bars only — request the matching -EXTERNAL type') Type guard
def is_requestable_binance_bar(bar_type) -> bool:
return (
bar_type.aggregation_source == AggregationSource.EXTERNAL
and bar_type.spec.price_type == PriceType.LAST
and bar_type.spec.aggregation in (BarAggregation.SECOND, BarAggregation.MINUTE, BarAggregation.HOUR, BarAggregation.DAY)
) Try / catch
try:
actor.request_custom_data(data_type, ...)
except Exception as e:
if 'require EXTERNAL aggregation' in str(e):
raise ValueError('Swap the bar type to its -EXTERNAL form before requesting BinanceBar history') from e
raise Prevention
- Keep two distinct bar types per strategy: the EXTERNAL type for backfill, the INTERNAL one for live aggregation
- Validate bar type strings end in -LAST-EXTERNAL-<time step> before any Binance history request
When it happens
Trigger: `request_data`/`RequestCustomData` with data type name `BinanceBar` whose parsed BarType ends in `-INTERNAL`, e.g. `BTCUSDT-PERP.BINANCE-1-MINUTE-LAST-INTERNAL`.
Common situations: Requesting history for a bar type the strategy also uses for internal tick aggregation; config templates defaulting to INTERNAL aggregation; assuming request_bars fills any registered bar type.
Related errors
- historical BinanceBar requests require time aggregation
- Binance historical bars require EXTERNAL 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/5e00c6bf2f379e41.
Report an issue: GitHub.