nautechsystems/nautilus_trader · error

Order type {order_type:?} requires a trigger price

Error message

Order type {order_type:?} requires a trigger price

What it means

Local pre-flight validation in the futures HTTP client's order submission path: STOP_MARKET, STOP_LIMIT, TRAILING_STOP_MARKET, MARKET_IF_TOUCHED and LIMIT_IF_TOUCHED orders all require a stop/trigger price on Binance Futures. If trigger_price is None for one of these types, the request is rejected before any HTTP call is made.

Source

Thrown at crates/adapters/binance/src/futures/http/client.rs:2073

        let binance_side = BinanceSide::try_from(order_side)?;
        let binance_order_type = order_type_to_binance_futures(order_type)?;
        let binance_tif = if post_only {
            BinanceTimeInForce::Gtx
        } else {
            BinanceTimeInForce::try_from(time_in_force)?
        };

        let requires_trigger_price = matches!(
            order_type,
            OrderType::StopMarket
                | OrderType::StopLimit
                | OrderType::TrailingStopMarket
                | OrderType::MarketIfTouched
                | OrderType::LimitIfTouched
        );

        if requires_trigger_price && trigger_price.is_none() {
            anyhow::bail!("Order type {order_type:?} requires a trigger price");
        }

        // MARKET and STOP_MARKET orders don't accept timeInForce
        let requires_time_in_force = matches!(
            order_type,
            OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched
        );

        let qty_str = quantity.to_string();
        let price_str = if price_match.is_some() {
            None
        } else {
            price.map(|p| p.to_string())
        };
        let stop_price_str = trigger_price.map(|p| p.to_string());
        let client_id_str = encode_broker_id(&client_order_id, BINANCE_NAUTILUS_FUTURES_BROKER_ID);

        let params = BinanceNewOrderParams {

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Provide the trigger (stop) price when creating stop-family orders
  2. For TRAILING_STOP_MARKET note this check still requires a trigger price even though the offset uses callback rate
  3. Add a pre-submit assertion in strategy code for stop-family orders

Example fix

// before — stop order without a trigger
// StopMarketOrder::new(..., trigger_price: None, ...)

// after — supply the trigger price
// StopMarketOrder::new(..., trigger_price: Some(price), ...)
Defensive patterns

Strategy: validation

Validate before calling

// Before submit_order()
let needs_trigger = matches!(
    order.order_type(),
    OrderType::StopMarket | OrderType::StopLimit | OrderType::TrailingStopMarket
        | OrderType::MarketIfTouched | OrderType::LimitIfTouched
);
assert!(!needs_trigger || order.trigger_price().is_some(), "trigger price required");

Type guard

fn requires_trigger_price(order_type: OrderType) -> bool {
    matches!(
        order_type,
        OrderType::StopMarket | OrderType::StopLimit | OrderType::TrailingStopMarket
            | OrderType::MarketIfTouched | OrderType::LimitIfTouched
    )
}

Try / catch

On this local rejection, create the order again with a trigger price set and resubmit; nothing reached the venue so the retry is safe.

Prevention

When it happens

Trigger: submit_order (HTTP path) for one of those order types with no trigger price supplied — e.g. a strategy built a stop order without a trigger or a factory call omitted the trigger argument.

Common situations: Factory misuse; strategies ported from venues where triggers are optional; optional-argument mistakes in order builders; config-driven order templates missing the trigger field.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/dd49705ee3d9f372. Report an issue: GitHub.