nautechsystems/nautilus_trader · error

Strategy not registered: Portfolio not initialized

Error message

Strategy not registered: Portfolio not initialized

What it means

`portfolio_rc()` returns a clone of the strategy's shared `Rc<RefCell<Portfolio>>`. The portfolio handle is injected during strategy registration; if the strategy is unregistered the `Option` is `None` and the `.expect` panics with 'Strategy not registered: Portfolio not initialized'.

Source

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

    /// 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.
    ///
    /// # Panics
    ///
    /// Panics if the strategy has not been registered.
    fn portfolio_rc(&self) -> Rc<RefCell<Portfolio>> {
        self.strategy_core()
            .portfolio
            .as_ref()
            .expect("Strategy not registered: Portfolio not initialized")
            .clone()
    }
}

impl StrategyCore {
    /// Creates a new [`StrategyCore`] instance with correctness checking.
    ///
    /// # Errors
    ///
    /// Returns an error if the configured order ID tag contains the '-' strategy ID separator,
    /// or if composing it into the strategy ID does not produce a valid [`StrategyId`].
    pub fn new_checked(config: StrategyConfig) -> CorrectnessResult<Self> {
        if let Some(order_id_tag) = config.order_id_tag.as_deref() {
            check_order_id_tag(order_id_tag)?;
        }

        let configured_strategy_id = config.strategy_id;
        let configured_order_id_tag = normalize_order_id_tag(config.order_id_tag.as_deref());

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Move portfolio access into post-registration lifecycle handlers (`on_start` or later)
  2. Ensure the strategy is registered with a trader/kernel that injects the Portfolio
  3. For tests, construct via the provided harness that registers the strategy with a Portfolio

Example fix

// before: too early
fn new(...) -> Self { Self { net: self.portfolio_rc().borrow().net_position(instrument) } }
// after: query after registration
fn on_start(&mut self) {
    self.net = self.portfolio_rc().borrow().net_position(self.instrument_id);
}
Defensive patterns

Strategy: validation

Validate before calling

if core.portfolio.is_none() {
    return Err(MyError::StrategyNotRegistered(strategy_id));
}

Prevention

When it happens

Trigger: Calling `self.portfolio_rc()` before registration — accessing portfolio in the constructor, in `on_start` before the kernel injects dependencies, or in a standalone test instance.

Common situations: Caching portfolio references at construction; querying account/portfolio state too early in the lifecycle; running a strategy outside a full trading node (e.g. sandbox without portfolio wiring).

Related errors


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