nautechsystems/nautilus_trader · error

Strategy not registered: OrderFactory not initialized

Error message

Strategy not registered: OrderFactory not initialized

What it means

`order_factory()` on the Strategy trait returns a `RefMut` to the strategy's `OrderFactory`. The factory is only populated when the strategy has been registered with a trading node/kernel; before registration the `Option` is `None`, and the `.expect` panics with 'Strategy not registered: OrderFactory not initialized'. This is a lifecycle misuse error, not a runtime failure.

Source

Thrown at crates/trading/src/strategy/core.rs:116

/// as `order()` and `portfolio()`, because native borrows, `Rc<RefCell<_>>`, and
/// core references do not cross those boundaries.
pub trait StrategyNative {
    /// Returns the strategy core.
    fn strategy_core(&self) -> &StrategyCore;

    /// Returns the mutable strategy core.
    fn strategy_core_mut(&mut self) -> &mut StrategyCore;

    /// Returns a mutable borrow of the order factory.
    ///
    /// # Panics
    ///
    /// Panics if the strategy has not been registered.
    fn order_factory(&mut self) -> RefMut<'_, OrderFactory> {
        self.strategy_core_mut()
            .order_factory
            .as_ref()
            .expect("Strategy not registered: OrderFactory not initialized")
            .borrow_mut()
    }

    /// Returns a clone of the reference-counted order factory.
    ///
    /// # Panics
    ///
    /// Panics if the strategy has not been registered.
    fn order_factory_rc(&self) -> Rc<RefCell<OrderFactory>> {
        self.strategy_core()
            .order_factory
            .as_ref()
            .expect("Strategy not registered: OrderFactory not initialized")
            .clone()
    }

    /// Returns a clone of the reference-counted portfolio.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Defer any order-factory use until after registration — do work in `on_start`/event handlers, never in the constructor
  2. Ensure the strategy is actually registered with a trader/node (`strategy.register(...)` or adding it to the kernel) before running it
  3. In tests, use the test harness/builder that registers the strategy and injects an OrderFactory

Example fix

// before: panics — factory not yet injected
impl MyStrategy {
    fn new(...) -> Self { Self { cache: self.order_factory().make_cache() } }
}
// after: initialize lazily on start, after registration
fn on_start(&mut self) {
    self.cache = self.order_factory().make_cache();
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard before touching the factory (if you have access to the core's Option)
if core.order_factory.is_none() {
    return Err(MyError::StrategyNotRegistered(strategy_id));
}

Prevention

When it happens

Trigger: Calling `self.order_factory()` from within strategy lifecycle methods that run before registration completes — typically the constructor, `on_start` before the kernel wires dependencies, or any code path that touches the strategy before `Strategy::register`/trader registration.

Common situations: Creating an OrderFactory-dependent state in the strategy's constructor; submitting orders in `on_start` before registration; unit-testing a strategy in isolation without a trading kernel; spawning the strategy without attaching it to a node.

Related errors


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