nautechsystems/nautilus_trader · critical

`handle_deltas` {IMPL_ERR} `{}`

Error message

`handle_deltas` {IMPL_ERR} `{}`

What it means

Default `Indicator::handle_deltas` panics when an indicator receives a batch of `OrderBookDeltas` without overriding this method. Like the singular variant, this default body is a deliberate guard: batched delta input means the indicator must implement book-delta processing, and its absence is a wiring/implementation bug rather than a recoverable runtime condition. The message renders as "`handle_deltas` is not implemented for `<indicator name>`".

Source

Thrown at crates/indicators/src/indicator.rs:40

    orderbook::OrderBook,
};

const IMPL_ERR: &str = "is not implemented for";

#[allow(unused_variables)]
pub trait Indicator {
    fn name(&self) -> String;

    fn has_inputs(&self) -> bool;

    fn initialized(&self) -> bool;

    fn handle_delta(&mut self, delta: &OrderBookDelta) {
        panic!("`handle_delta` {IMPL_ERR} `{}`", self.name());
    }

    fn handle_deltas(&mut self, deltas: &OrderBookDeltas) {
        panic!("`handle_deltas` {IMPL_ERR} `{}`", self.name());
    }

    fn handle_depth(&mut self, depth: &OrderBookDepth10) {
        panic!("`handle_depth` {IMPL_ERR} `{}`", self.name());
    }

    fn handle_book(&mut self, book: &OrderBook) {
        panic!("`handle_book_mbo` {IMPL_ERR} `{}`", self.name());
    }

    /// Updates the indicator with the given quote tick.
    ///
    /// # Errors
    ///
    /// Returns an error if the configured price type cannot be extracted from the quote.
    fn handle_quote(&mut self, quote: &QuoteTick) -> anyhow::Result<()> {
        anyhow::bail!("`handle_quote_tick` {IMPL_ERR} `{}`", self.name());
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Override `handle_deltas` in the indicator impl (a common pattern is iterating and delegating each delta to `handle_delta`).
  2. If the indicator is not delta-based, stop subscribing it to OrderBookDeltas streams and feed the appropriate data type.
  3. Default-implement the plural method yourself in a wrapper or adapter so batch input is expanded into single-delta calls.

Example fix

// before
impl Indicator for MyIndicator { /* handle_delta only */ }

// after
impl Indicator for MyIndicator {
    fn handle_deltas(&mut self, deltas: &OrderBookDeltas) {
        for delta in deltas.deltas() {
            self.handle_delta(delta);
        }
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// before replaying batches, verify capability
if !indicator_supports_batch_deltas(&ind) { skip_or_convert(&ind, deltas); }

Type guard

fn handles_batch_deltas(ind: &dyn Indicator) -> bool { ind.as_any().is::<DeltaCapableMarker>() }

Try / catch

// no catch for panics; guard the call: if batch_capable(ind) { ind.handle_deltas(deltas); } else { for d in deltas.deltas() { ind.handle_delta(d); } }

Prevention

When it happens

Trigger: Calling `handle_deltas(&OrderBookDeltas)` on an indicator impl that only overrides `handle_delta` (or neither), e.g. replaying a recorded delta batch through a quote-based indicator, or a data engine that delivers delta batches to all subscribed indicators.

Common situations: Backtesting/replaying historical L2 delta batches into indicators built for quotes; batch-processing pipelines that group deltas and call the plural method; custom indicator authors forgetting the plural override even though they implemented the singular one.

Related errors


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