nautechsystems/nautilus_trader · error
Unsupported bar aggregation for Binance: {agg:?}
Error message
Unsupported bar aggregation for Binance: {agg:?} What it means
Thrown by bar_spec_to_binance_interval when the BarSpecification's aggregation method is not one Binance klines can represent. Binance only serves time-based klines (Second, Minute, Hour, Day, Week, Month with fixed steps), so non-time aggregations such as TICK, VOLUME, DOLLAR, VALUE, or sub-second units cannot be mapped and the conversion fails fast.
Source
Thrown at crates/adapters/binance/src/common/parse.rs:1469
6 => BinanceKlineInterval::Hour6,
8 => BinanceKlineInterval::Hour8,
12 => BinanceKlineInterval::Hour12,
_ => anyhow::bail!("Unsupported hour interval: {step}h"),
},
BarAggregation::Day => match step {
1 => BinanceKlineInterval::Day1,
3 => BinanceKlineInterval::Day3,
_ => anyhow::bail!("Unsupported day interval: {step}d"),
},
BarAggregation::Week => match step {
1 => BinanceKlineInterval::Week1,
_ => anyhow::bail!("Unsupported week interval: {step}w"),
},
BarAggregation::Month => match step {
1 => BinanceKlineInterval::Month1,
_ => anyhow::bail!("Unsupported month interval: {step}M"),
},
agg => anyhow::bail!("Unsupported bar aggregation for Binance: {agg:?}"),
};
Ok(interval)
}
pub(crate) fn quote_to_l1_deltas(quote: QuoteTick, sequence: u64) -> OrderBookDeltas {
let bid_action = if quote.bid_size.is_zero() {
BookAction::Delete
} else {
BookAction::Update
};
let ask_action = if quote.ask_size.is_zero() {
BookAction::Delete
} else {
BookAction::Update
};
let bid = OrderBookDelta::new(
quote.instrument_id,View on GitHub (pinned to a4b06ed870)
Solutions
- Switch to a time-based aggregation Binance supports, e.g. '1-SECOND-LAST-INTERNAL' or '1-MINUTE-LAST-INTERNAL'.
- For TICK/VOLUME/DOLLAR bars, subscribe to the exchange's trade/quote/ticker streams and build the bars yourself (custom data engine or an Actor that aggregates).
- Validate every BarType against the supported set in bar_spec_to_binance_interval before starting the node.
Example fix
# before
bar_type = BarType.from_str('BTCUSDT.BINANCE-100-TICK-LAST-INTERNAL')
# after (aggregate locally from trades if you need tick bars)
bar_type = BarType.from_str('BTCUSDT.BINANCE-1-SECOND-LAST-INTERNAL')
client.subscribe_bars(BarSubscription(bar_type)) Defensive patterns
Strategy: validation
Validate before calling
TIME_BASED = ('SECOND', 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH')
def is_time_based(bar_spec) -> bool:
return bar_spec.aggregation_string in TIME_BASED
assert is_time_based(bar_type.spec), 'Binance klines require time-based aggregation' Type guard
def supports_binance_klines(bar_type) -> bool:
return bar_type.spec.aggregation_string in (
'SECOND', 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH'
) Prevention
- Never route TICK/VOLUME/DOLLAR/VALUE or sub-second BarTypes to Binance clients.
- Build non-time bars locally from trade ticks via a custom Actor.
- Log the BarType string in strategy config at startup to catch copy-paste mistakes.
When it happens
Trigger: Subscribing to or requesting bars with a BarType like 'BTCUSDT.BINANCE-100-TICK-LAST-INTERNAL', '-5000-DOLLAR-', '-100-VOLUME-', or '-1-MILLISECOND-' through the Binance data client; the same path is hit by request_bars for historical data.
Common situations: Strategies written against the backtest engine or venues that synthesize tick/dollar/volume bars, then pointed at the live Binance adapter; copying a BarType string from a different adapter's docs; sub-second bars expected because Nautilus supports them in backtests.
Related errors
- Unsupported month interval: {step}M
- historical BinanceBar requests require EXTERNAL aggregation
- historical BinanceBar requests require time aggregation
- Binance historical bars require EXTERNAL aggregation
- Only EXTERNAL aggregation is supported
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/bf798cb2276e08c7.
Report an issue: GitHub.