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.

Workflow:Nautechsystems Nautilus trader Strategy development

From Leeroopedia


Knowledge Sources
Domains Algorithmic_Trading, Strategy_Development, Quantitative_Finance
Last Updated 2026-02-10 09:00 GMT

Overview

End-to-end process for developing a custom trading strategy in NautilusTrader by inheriting from the Strategy base class and implementing the event-driven lifecycle hooks.

Description

This workflow covers the complete procedure for authoring a trading strategy within the NautilusTrader framework. Strategies are Python classes that inherit from the Strategy base class and implement event handler methods (on_start, on_bar, on_trade_tick, on_quote_tick, on_order_filled, on_position_opened, on_position_closed, on_stop). The strategy communicates with the platform through a well-defined API for data subscriptions, order submission, position management, indicator registration, and portfolio queries. The same strategy code runs identically in backtesting, sandbox (paper trading), and live environments.

Usage

Execute this workflow when you want to implement a new trading strategy for the NautilusTrader platform. This applies whether you are building a simple moving average crossover, a complex multi-instrument arbitrage system, an order book market maker, or any other algorithmic trading strategy. The workflow produces a reusable strategy class and configuration that can be deployed in any NautilusTrader runtime context.

Execution Steps

Step 1: Define Strategy Configuration

Create a StrategyConfig subclass that declares all configurable parameters for the strategy. This includes the instrument ID, bar type specification, trade sizing parameters, indicator periods, and any strategy-specific settings. The configuration class supports serialization for reproducible experiment tracking and factory-based instantiation.

Key considerations:

  • Inherit from StrategyConfig and use standard Python type annotations
  • Include instrument_id as an InstrumentId for instrument binding
  • Define bar_type as a string that will be parsed into a BarType
  • All parameters should have sensible defaults where possible
  • The config is hashable and JSON-serializable for experiment tracking

Step 2: Implement the Strategy Class

Create a class inheriting from Strategy. In the constructor, parse the configuration and initialize instance variables for indicators, state tracking, and instrument references. Register indicators so the platform automatically updates them with incoming data.

Key considerations:

  • Call super().__init__(config) in the constructor
  • Create indicator instances (EMA, RSI, Bollinger Bands, etc.) in the constructor
  • Use self.register_indicator_for_bars(bar_type, indicator) for automatic updates
  • Initialize order tracking variables and position state flags

Step 3: Implement on_start Lifecycle Hook

Implement the on_start() method, which executes when the strategy is started by the trader. Subscribe to the data feeds needed by the strategy (bars, ticks, order book data). Load the instrument definition from the cache for price/quantity precision. Set up any timers for periodic logic.

Key considerations:

  • Use self.subscribe_bars(bar_type) for bar data
  • Use self.subscribe_trade_ticks(instrument_id) for trade data
  • Use self.subscribe_quote_ticks(instrument_id) for quote data
  • Use self.subscribe_order_book_deltas(instrument_id) for order book data
  • Retrieve the instrument via self.cache.instrument(instrument_id)
  • Use self.clock.set_timer() for time-based periodic actions

Step 4: Implement Data Event Handlers

Implement the core trading logic in the data event handlers. The on_bar() method receives each new bar and is the primary location for signal generation. Compute indicators, evaluate entry/exit conditions, and submit orders when signals trigger. Additional handlers (on_trade_tick, on_quote_tick, on_order_book_delta) provide finer-grained data access.

Key considerations:

  • Check indicator readiness before trading (e.g., enough bars for EMA warmup)
  • Use self.portfolio.is_flat(instrument_id) to check current position state
  • Use self.order_factory.market() or self.order_factory.limit() to create orders
  • Submit orders via self.submit_order(order)
  • Use self.submit_order_list() for bracket orders (entry + stop loss + take profit)
  • Access current positions via self.cache.positions_open()

Step 5: Implement Order and Position Event Handlers

Implement handlers for order lifecycle and position events. The on_order_filled() method fires when an order receives a fill. The on_position_opened(), on_position_changed(), and on_position_closed() methods track position state transitions. These handlers enable reactive logic such as trailing stop adjustments, scale-in/scale-out, and risk management actions.

Key considerations:

  • on_order_filled receives an OrderFilled event with fill price, quantity, and commission
  • on_position_opened fires when a new position is established
  • on_position_closed fires when a position is fully closed, providing realized PnL
  • Use these handlers for position management logic separate from signal generation

Step 6: Implement on_stop Lifecycle Hook

Implement the on_stop() method to handle strategy shutdown. Cancel all open orders and optionally close all open positions. Clean up any resources, timers, or external connections. This method is called during both backtest completion and live trading shutdown.

Key considerations:

  • Use self.cancel_all_orders(instrument_id) to cancel pending orders
  • Use self.close_all_positions(instrument_id) to flatten positions
  • Unsubscribe from data feeds if needed
  • Cancel any active timers

Step 7: Validate with Backtest

Test the strategy by running it through the BacktestEngine with historical data. Verify correct behavior including order submission, fill handling, position tracking, indicator calculations, and edge cases. Review the generated reports and performance statistics to validate the strategy logic before considering live deployment.

Key considerations:

  • Start with a small dataset to verify basic correctness
  • Check order fill reports for expected entry/exit behavior
  • Verify position reports match expected trade count and direction
  • Run acceptance tests comparing results across multiple data sets
  • Use DEBUG logging to trace event flow through the strategy

Execution Diagram

GitHub URL

Workflow Repository