nautechsystems/nautilus_trader · critical

`handle_delta` {IMPL_ERR} `{}`

Error message

`handle_delta` {IMPL_ERR} `{}`

What it means

This panic comes from the default implementation of `Indicator::handle_delta` in crates/indicators/src/indicator.rs. The default is intentionally a `panic!` placeholder: an indicator that receives an `OrderBookDelta` but does not override `handle_delta` signals a programming error, since the indicator was never designed to consume that data type. IMPL_ERR expands to "is not implemented for", so the message reads "`handle_delta` is not implemented for `<indicator name>`".

Source

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

use std::fmt::Debug;

use nautilus_model::{
    data::{Bar, OrderBookDelta, OrderBookDeltas, OrderBookDepth10, QuoteTick, TradeTick},
    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
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Do not feed OrderBookDelta data to this indicator; route quote ticks (handle_quote) or trade ticks (handle_trade) instead.
  2. If the indicator must consume deltas, override `fn handle_delta(&mut self, delta: &OrderBookDelta)` in your Indicator impl with real logic.
  3. Check the indicator name in the panic message to identify which component was mis-subscribed, and fix the subscription/data-type wiring.

Example fix

// before
struct MyMA;
impl Indicator for MyMA { /* no handle_delta override, but receives deltas */ }

// after
impl Indicator for MyMA {
    fn handle_delta(&mut self, delta: &OrderBookDelta) {
        // convert delta to a mid/price update and feed internal state
    }
}
// or: unsubscribe MyMA from the delta stream and subscribe it to quotes
Defensive patterns

Strategy: type-guard

Validate before calling

// route by capability before dispatch
if let Some(_delta) = data.as_order_book_delta() {
    assert!(indicator_supports_deltas(&indicator), "{} does not handle deltas", indicator.name());
}

Type guard

fn supports_deltas<I: Indicator>(ind: &I) -> bool { /* true only for impls overriding handle_delta; track via a capability flag */ false }

Try / catch

// panics cannot be caught idiomatically in Rust; ensure the call site never invokes handle_delta on non-delta indicators
if indicator_is_delta_capable(ind) { ind.handle_delta(delta); }

Prevention

When it happens

Trigger: Calling `handle_delta(&OrderBookDelta)` on any custom or built-in indicator whose trait impl does not override `handle_delta`. For example, feeding a book-delta stream into a moving-average indicator that only implements `handle_quote`/`handle_trade`, or a data pipeline that routes `OrderBookDelta` events to all subscribed indicators indiscriminately.

Common situations: Subscribing an indicator to the wrong data type (L2/L3 delta stream instead of quotes or trades); wiring an actor/data engine to pass book events to a generic indicator list; writing a custom Indicator impl and forgetting to override `handle_delta` while the engine still dispatches deltas.

Related errors


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