Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Nautechsystems Nautilus trader Data Event Handlers

From Leeroopedia
Revision as of 16:01, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Nautechsystems_Nautilus_trader_Data_Event_Handlers.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Field Value
sources https://github.com/nautechsystems/nautilus_trader , https://nautilustrader.io/docs/
domains algorithmic trading, event handling, pattern documentation, NautilusTrader
type Pattern Doc (user-defined overrides)
last_updated 2026-02-10 12:00 GMT

Overview

Concrete pattern for implementing data event handler methods that NautilusTrader invokes on a running strategy when subscribed market data arrives.

Description

NautilusTrader defines a set of data event handler methods on the Actor base class that strategies override to process incoming market data. These methods are not called by user code -- they are invoked by the framework's message bus when matching data events are published. The user's responsibility is to override these methods with custom trading logic.

The primary data event handlers are:

  • on_bar(self, bar: Bar): Called when a subscribed bar is received.
  • on_trade_tick(self, tick: TradeTick): Called when a subscribed trade tick is received.
  • on_quote_tick(self, tick: QuoteTick): Called when a subscribed quote tick is received.

Additional handlers exist for specialized data:

  • on_order_book(self, order_book: OrderBook): Called for order book snapshots.
  • on_order_book_deltas(self, deltas): Called for order book delta updates.
  • on_mark_price(self, mark_price: MarkPriceUpdate): Called for mark price updates.
  • on_index_price(self, index_price: IndexPriceUpdate): Called for index price updates.
  • on_funding_rate(self, funding_rate: FundingRateUpdate): Called for funding rate updates.
  • on_data(self, data): Called for generic/custom data types.

All handlers have a default no-op implementation in the base class (commented as "Optionally override in subclass"), so strategies need only override the handlers relevant to their data subscriptions.

Usage

Override these methods in your Strategy subclass to implement your trading logic. You must have an active subscription (via subscribe_bars, subscribe_trade_ticks, etc.) for the corresponding handler to be invoked.

Code Reference

Source Location

nautilus_trader/common/actor.pyx, lines 458-552.

Interface Specification

on_bar:

cpdef void on_bar(self, Bar bar):
    """
    Actions to be performed when running and receives a bar.

    Parameters
    ----------
    bar : Bar
        The bar received.
    """
    # Optionally override in subclass

on_trade_tick:

cpdef void on_trade_tick(self, TradeTick tick):
    """
    Actions to be performed when running and receives a trade tick.

    Parameters
    ----------
    tick : TradeTick
        The tick received.
    """
    # Optionally override in subclass

on_quote_tick:

cpdef void on_quote_tick(self, QuoteTick tick):
    """
    Actions to be performed when running and receives a quote tick.

    Parameters
    ----------
    tick : QuoteTick
        The tick received.
    """
    # Optionally override in subclass

Import

No separate import is needed. These methods are defined on Actor and inherited by Strategy. Override them in your subclass.

from nautilus_trader.trading.strategy import Strategy
from nautilus_trader.model.data import Bar, BarType, TradeTick, QuoteTick

I/O Contract

Inputs

Handler Parameter Type Description
on_bar bar Bar Aggregated OHLCV bar with open, high, low, close, volume, and timestamp fields.
on_trade_tick tick TradeTick Individual trade execution with price, size, aggressor side, and timestamp.
on_quote_tick tick QuoteTick Best bid/ask update with bid price, ask price, bid size, ask size, and timestamp.

Outputs

Output Type Description
None void Handlers return nothing. Side effects are produced by calling order submission methods, updating internal state, or logging.

Usage Examples

Bar-based moving average crossover strategy:

from nautilus_trader.trading.strategy import Strategy
from nautilus_trader.model.data import Bar, BarType
from nautilus_trader.indicators.average.ema import ExponentialMovingAverage


class EMACrossStrategy(Strategy):
    def __init__(self, config):
        super().__init__(config)
        self.fast_ema = ExponentialMovingAverage(config.fast_ema_period)
        self.slow_ema = ExponentialMovingAverage(config.slow_ema_period)

    def on_start(self):
        bar_type = BarType.from_str(f"{self.config.instrument_id}-1-MINUTE-LAST-EXTERNAL")
        self.subscribe_bars(bar_type)

    def on_bar(self, bar: Bar):
        self.fast_ema.handle_bar(bar)
        self.slow_ema.handle_bar(bar)

        if not self.fast_ema.initialized or not self.slow_ema.initialized:
            return  # Wait for indicators to warm up

        if self.fast_ema.value > self.slow_ema.value:
            if not self.portfolio.is_net_long(bar.bar_type.instrument_id):
                order = self.order_factory.market(
                    instrument_id=bar.bar_type.instrument_id,
                    order_side=OrderSide.BUY,
                    quantity=Quantity.from_str("100"),
                )
                self.submit_order(order)
        elif self.fast_ema.value < self.slow_ema.value:
            if not self.portfolio.is_net_short(bar.bar_type.instrument_id):
                self.close_all_positions(bar.bar_type.instrument_id)

Trade tick handler for volume analysis:

from nautilus_trader.model.data import TradeTick


class VolumeStrategy(Strategy):
    def __init__(self, config):
        super().__init__(config)
        self._cumulative_volume = 0.0
        self._tick_count = 0

    def on_start(self):
        instrument_id = InstrumentId.from_str(self.config.instrument_id)
        self.subscribe_trade_ticks(instrument_id)

    def on_trade_tick(self, tick: TradeTick):
        self._cumulative_volume += float(tick.size)
        self._tick_count += 1
        self.log.info(
            f"Trade: {tick.price} x {tick.size} | "
            f"Cumulative volume: {self._cumulative_volume}"
        )

Quote tick handler for spread monitoring:

from nautilus_trader.model.data import QuoteTick


class SpreadMonitorStrategy(Strategy):
    def on_start(self):
        instrument_id = InstrumentId.from_str("EURUSD.SIM")
        self.subscribe_quote_ticks(instrument_id)

    def on_quote_tick(self, tick: QuoteTick):
        spread = float(tick.ask_price) - float(tick.bid_price)
        self.log.info(
            f"Bid: {tick.bid_price} | Ask: {tick.ask_price} | Spread: {spread:.5f}"
        )

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment