NAUTILUS / RUST source 3eb18933
Pages

Rust edition: this page follows the live DeepWiki structure but treats the current Rust crates as implementation authority. Non-Rust surfaces are identified at their boundary and are not presented as Rust APIs.

Plugin System

Relevant Rust source files

  • crates/plugin/src/lib.rs
  • crates/plugin/src/manifest.rs
  • crates/plugin/src/host.rs
  • crates/plugin/src/boundary.rs

The NautilusTrader plugin system, implemented in the nautilus-plugin crate, provides a mechanism for loading separately compiled Rust shared libraries (cdylib) at runtime during LiveNode startup This system enables extending the platform's functionality—specifically custom data types, actors, and strategies—without requiring a full recompilation of the core trading engine

Core Architecture

The system operates across a C-ABI boundary to ensure compatibility between the host process (the LiveNode) and the external plugin libraries This is necessary because Rust's default #[repr(Rust)] layout is unstable across different compilations

Plugin Traits

Plugins implement specific traits that define their behavior. The nautilus-plugin crate provides macro-generated glue to adapt these traits to the C-ABI

Trait Purpose Key Callbacks
PluginCustomData Defines custom data types for persistence and streaming from_json, to_json, ts_event
PluginActor Defines a custom component with lifecycle hooks on_start, on_data, on_stop
PluginStrategy Defines a trading strategy using the HostVTable for commands on_bar, on_order_event, on_data

The nautilus_plugin! Macro

The nautilus_plugin! macro is the primary entry point for plugin authors It handles:

  • Generation of the extern "C" entry symbol nautilus_plugin_init
  • Construction of the #[repr(C)]``PluginManifest
  • Registration of the plugin components within the static manifest structure

Implementation Details

Plugin Manifest and ABI Versioning

Every plugin returns a 'static PluginManifest The host validates this manifest before registration:

  • ABI Version: Must match NAUTILUS_PLUGIN_ABI_VERSION (currently 1) The host rejects manifest ABI mismatches to prevent crashes
  • Build ID: Contains the nautilus-plugin version, Rust compiler version, and target triple
  • Precision Mode: The host validates that the plugin's fixed_precision matches the host's (e.g., standard vs high-precision) to ensure memory layout compatibility for model types

C-ABI Boundary Handling

Because many Nautilus types (like OrderBook or InstrumentAny) contain heap-allocated Rust collections, they cannot be #[repr(C)] The system uses Handles and Boundary Logic to pass these across the boundary:

  • Handles: Opaque #[repr(C)] wrappers that box the internal type for the duration of a callback
  • Thunks: Macro-generated extern "C" functions that dereference handles and provide a borrowed Rust reference (&T) to the user's trait implementation
  • Panic Guards: Every thunk uses a panic guard to catch unwinding panics and convert them into error codes, preventing undefined behavior at the FFI boundary

Host Interaction (HostVTable)

The host provides a HostVTable to the plugin during initialization This table contains function pointers for re-entrant calls:

  • Logging: log function for the plugin to write to the host's log system
  • Clock: Access to the system time
  • Trading Commands: Strategies use this to call commands which the host routes back into the core engines

System Component Interaction

The following diagrams illustrate the relationship between the plugin system and the core Nautilus components.

Natural Language to Code Entity Space: Plugin Initialization

Plugin loading is an explicit sequence: PluginHost loads the library, resolves nautilus_plugin_init, validates ABI and fixed-precision compatibility from PluginManifest, then exposes registration through PluginContext.

Entity Mapping: Plugin to Core

The C ABI boundary exposes stable manifest, version, precision, component and callback contracts. Host internals wrap those contracts in safe Rust ownership; plugin implementation details remain outside the kernel.

Platform and Build Requirements

The plugin system is primarily designed for Linux production environments

Shared Library Formats

Plugins use the platform-native dynamic library format:

  • Linux: lib<name>.so
  • macOS: lib<name>.dylib
  • Windows: <name>.dll

Identifier Interning

Nautilus uses Ustr for fast string identifiers. Since each cdylib has its own global string cache, the boundary logic re-interns identifiers (e.g., InstrumentId, ClientOrderId) when crossing the boundary to ensure pointer equality works correctly within each side