Plugins
The nautilus-plugin crate defines the artifact contract for NautilusTrader plug-ins. A plug-in is an
independently compiled Rust cdylib. It identifies itself with a versioned manifest and exchanges values
across a C-ABI boundary.
The crate covers artifact identity and boundary primitives only. It does not load, register, or run plug-ins. The loading host is an internal Nautilus deployment detail outside this repository.
The plug-in ABI is early alpha and the contract is unstable. Pin plug-in builds to the matching
nautilus-plugin version.
Artifact contract
A plug-in is a Rust cdylib that exports a single entry symbol, nautilus_plugin_init. The
nautilus_plugin! macro generates that symbol together with the static manifest carrying the build
identity:
nautilus_plugin::nautilus_plugin! {
name: "example-plugin",
vendor: "Nautech",
version: env!("CARGO_PKG_VERSION"),
}name and version are required, vendor defaults to an empty string. Invoke the macro once per
artifact at module scope, set crate-type = ["cdylib"] in the artifact's Cargo.toml, and depend on
the matching nautilus-plugin version.
Manifest compatibility
nautilus_plugin_init takes an opaque host pointer. It returns a PluginManifest in process-lifetime
storage. If the host pointer is null or the call panics, it returns null. PluginManifest::validate checks
the invariants a host relies on before registration. It reports each structural problem it finds and fails
when:
abi_versiondoes not equalNAUTILUS_PLUGIN_ABI_VERSION, orbuild_id.schema_versiondoes not equalPLUGIN_BUILD_ID_VERSION.plugin_nameorplugin_versionis empty.- Any manifest string is malformed: a null pointer with non-zero length, or bytes that are not valid UTF-8.
build_id.precision_modeorbuild_id.fixed_precisiondiffers from the host build.
Precision is validated because it changes model type layout across the boundary. The remaining build
identity fields (nautilus-plugin version, rustc version, target triple, and build profile) are
diagnostic.
Boundary rules
Only the #[repr(C)] types in nautilus_plugin::boundary, and #[repr(C)] types built from them, may appear
in a signature that crosses the boundary. String, Vec, and Box<dyn Trait> rely on Rust's unstable ABI
and must never cross it. Panics must not unwind across the boundary either. The generated entry symbol catches
them and returns null.
Under the current ABI, plug-ins are not unloaded, so manifest storage stays valid for the life of the process.
See the crate docs for the boundary and manifest types.
Python Adapter Interface
Use this guide to implement a custom live adapter in a separate Python package. That package can have its own Rust/PyO3 extension. This guide covers the...
Data Testing Spec
Use this test matrix to validate adapter data functionality with the Rust DataTester actor. Python exposes it as a built-in actor configured through...