nautechsystems/nautilus_trader · critical

`handle_trade_tick` is not implemented for `{}`

Error message

`handle_trade_tick` is not implemented for `{}`

What it means

Default `Indicator::handle_trade` panics when an indicator receives a `TradeTick` without overriding `handle_trade`. The default body is a guard panic with the message "`handle_trade_tick` is not implemented for `<indicator name>`" (the panic text uses the label handle_trade_tick). Trade-tick input requires the indicator to implement trade processing; hitting the default means a type/wiring mismatch.

Source

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

    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());
    }

    fn handle_trade(&mut self, trade: &TradeTick) {
        panic!("`handle_trade_tick` {IMPL_ERR} `{}`", self.name());
    }

    fn handle_bar(&mut self, bar: &Bar) {
        panic!("`handle_bar` {IMPL_ERR} `{}`", self.name());
    }

    fn reset(&mut self);
}

pub trait MovingAverage: Indicator {
    fn value(&self) -> f64;
    fn count(&self) -> usize;
    fn update_raw(&mut self, value: f64);
}

impl Debug for dyn Indicator + Send {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        // Implement custom formatting for the Indicator trait object

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Override `fn handle_trade(&mut self, trade: &TradeTick)` in the indicator impl to consume trade ticks.
  2. Unsubscribe the indicator from trade ticks and subscribe it to the data type it implements (quotes or bars).
  3. Use a trade-capable indicator (e.g. one keyed off trade price) if your data source only emits trades.

Example fix

// before
impl Indicator for QuoteBasedMA { /* only handle_quote */ }

// after
impl Indicator for QuoteBasedMA {
    fn handle_trade(&mut self, trade: &TradeTick) {
        // feed trade.price into the average
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// before subscribing
assert!(ind.accepts(DataType::TradeTick), "{} has no handle_trade impl", ind.name());

Try / catch

// guard: if trade_capable(ind) { ind.handle_trade(trade); } else if quote_capable(ind) { /* skip or synthesize quote */ }

Prevention

When it happens

Trigger: Calling `handle_trade(&TradeTick)` on an indicator that only implements `handle_quote` (e.g. a quote-based average like a bid/ask indicator) or `handle_bar` — typically because the data engine dispatches every trade tick to all subscribed indicators.

Common situations: Quote-based indicators subscribed to a trade stream by mistake; custom indicators where handle_trade was left to the default; replaying tick datasets containing trades into quote-only indicators.

Related errors


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