nautechsystems/nautilus_trader · error

Trigger price not set

Error message

Trigger price not set

What it means

OrderTestBuilder::get_trigger_price unwraps Option<Price> set via .trigger_price(...). build() for trigger-based order types (StopMarket, StopLimit, TrailingStop*) panics with 'Trigger price not set' when absent.

Source

Thrown at crates/model/src/orders/builder.rs:206

    // ----------- Price ----------
    pub fn price(&mut self, price: Price) -> &mut Self {
        self.price = Some(price);
        self
    }

    fn get_price(&self) -> Price {
        self.price.expect("Price not set")
    }

    // ----------- TriggerPrice ----------
    pub fn trigger_price(&mut self, trigger_price: Price) -> &mut Self {
        self.trigger_price = Some(trigger_price);
        self
    }

    fn get_trigger_price(&self) -> Price {
        self.trigger_price.expect("Trigger price not set")
    }

    // ----------- ActivationPrice ----------
    pub fn activation_price(&mut self, activation_price: Price) -> &mut Self {
        self.activation_price = Some(activation_price);
        self
    }

    fn get_activation_price(&self) -> Option<Price> {
        self.activation_price
    }

    // ----------- TriggerType ----------
    pub fn trigger_type(&mut self, trigger_type: TriggerType) -> &mut Self {
        self.trigger_type = Some(trigger_type);
        self
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Add .trigger_price(Price::from(...)) to the builder chain before build().
  2. Only omit trigger_price for non-trigger order types.
  3. Match trigger_price to the instrument's price precision to avoid later validation failures.

Example fix

// before
let order = OrderTestBuilder::new(OrderType::StopMarket).instrument_id(id).quantity(qty).build();
// after
let order = OrderTestBuilder::new(OrderType::StopMarket)
    .instrument_id(id)
    .quantity(qty)
    .trigger_price(Price::from("49500.00"))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if matches!(order_type, OrderType::StopMarket | OrderType::StopLimit | OrderType::TrailingStopMarket | OrderType::TrailingStopLimit) {
    assert!(trigger_price.is_some(), "trigger_price required for {:?}", order_type);
}
builder.trigger_price(trigger_price.unwrap()).build();

Type guard

fn order_type_needs_trigger(t: OrderType) -> bool {
    matches!(t, OrderType::StopMarket | OrderType::StopLimit | OrderType::TrailingStopMarket | OrderType::TrailingStopLimit)
}

Try / catch

// validate trigger presence for trigger-based types before build
assert!(trigger_price.is_some() || !order_type_needs_trigger(order_type));

Prevention

When it happens

Trigger: Building a stop/trailing order type via OrderTestBuilder without chaining .trigger_price(Price) before build().

Common situations: Adding stop-order coverage to an existing limit-order test and forgetting the trigger_price line, or a data-driven test missing the trigger field for the stop variants.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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