nautechsystems/nautilus_trader · error · anyhow::Error

Only EXTERNAL aggregation is supported

Error message

Only EXTERNAL aggregation is supported

What it means

OKX HTTP client request for historical bars (candles) requires the bar_type's aggregation source to be EXTERNAL, meaning the raw OKX candles are used directly rather than internally aggregated ticks. Internal (self-aggregated) bar sources are not implemented in this adapter, so the request is rejected with anyhow::ensure! before any HTTP call.

Source

Thrown at crates/adapters/okx/src/http/client.rs:3544

        &self,
        bar_type: BarType,
        start: Option<Timestamp>,
        mut end: Option<Timestamp>,
        limit: Option<u32>,
    ) -> anyhow::Result<Vec<Bar>> {
        const HISTORY_SPLIT_DAYS: i64 = 100;
        const MAX_PAGES_SOFT: usize = 500;

        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        enum Mode {
            Latest,
            Backward,
            Range,
        }

        let limit = if limit == Some(0) { None } else { limit };

        anyhow::ensure!(
            bar_type.aggregation_source() == AggregationSource::External,
            "Only EXTERNAL aggregation is supported"
        );

        if let (Some(s), Some(e)) = (start, end) {
            anyhow::ensure!(s < e, "Invalid time range: start={s:?} end={e:?}");
        }

        let now = self.inner.clock.get_time_ns().to_datetime_utc();

        if let Some(s) = start
            && s > now
        {
            return Ok(Vec::new());
        }

        if let Some(e) = end
            && e > now

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a BarType created with AggregationSource::External
  2. Configure the strategy's bar types to use external aggregation for the OKX adapter
  3. If internal aggregation is required, subscribe to raw external bars via OKX and aggregate them in a separate aggregator component

Example fix

// before
let bar_type = BarType::new(instrument_id, bar_spec, AggregationSource::Internal);
// after
let bar_type = BarType::new(instrument_id, bar_spec, AggregationSource::External);
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_external(bar_type: &BarType) -> Result<(), String> {
    if bar_type.aggregation_source() == AggregationSource::External { Ok(()) }
    else { Err(format!("bar_type {} must use EXTERNAL aggregation for OKX", bar_type)) }
}

Type guard

fn is_external(bar_type: &BarType) -> bool {
    bar_type.aggregation_source() == AggregationSource::External
}

Prevention

When it happens

Trigger: Calling request_bars / historical candle fetch with a BarType whose AggregationSource is Internal, e.g. a bar type constructed via BarType::new(instrument_id, spec, AggregationSource::Internal).

Common situations: Configuring a strategy with internally aggregated bars and passing them to the OKX data client; copying bar_type definitions from another adapter that supports internal aggregation; default aggregation source left at Internal when building the BarType.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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