nautechsystems/nautilus_trader · error

Algo order type requires a trigger price

Error message

Algo order type {order_type:?} requires a trigger price

What it means

Algo-style order types on Binance futures (`StopMarket`, `StopLimit`, `MarketIfTouched`, `LimitIfTouched`) are trigger-based and require a `stopPrice`/trigger price. The HTTP client builds the order request and, when `requires_trigger_price` is true but `trigger_price` is `None`, `anyhow::ensure!` fails with this message.

Solutions

  1. Provide a `Price` for `trigger_price` when submitting StopMarket/StopLimit/MarketIfTouched/LimitIfTouched orders.
  2. Verify upstream parsing so the trigger price is not dropped/None (e.g. missing column in config/backtest data).
  3. If a non-trigger order was intended, use `Market` or `Limit` instead.
  4. Run the caller-side validation that mirrors this check before submission.

Example fix

// before
client.submit_order(symbol, side, OrderType::StopMarket, qty, None /* trigger */)
// after
client.submit_order(symbol, side, OrderType::StopMarket, qty, Some(Price::from("42000.0")))
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_trigger(order_type: OrderType, trigger: Option<Price>) -> Result<(), String> {
    let requires = matches!(order_type,
        OrderType::StopMarket | OrderType::StopLimit
        | OrderType::MarketIfTouched | OrderType::LimitIfTouched);
    if requires && trigger.is_none() {
        return Err(format!("{order_type:?} requires a trigger price"));
    }
    Ok(())
}

Type guard

fn requires_trigger(t: OrderType) -> bool {
    matches!(t, OrderType::StopMarket | OrderType::StopLimit
        | OrderType::MarketIfTouched | OrderType::LimitIfTouched)
}

Try / catch

match client.submit_order(...).await {
    Err(e) if e.to_string().contains("requires a trigger price") => {
        // supply trigger price or downgrade to Market/Limit and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling the futures HTTP order-submission path with `order_type` in {StopMarket, StopLimit, MarketIfTouched, LimitIfTouched} and `trigger_price: None` — e.g. an execution layer that omitted the trigger for a conditional order, or a None propagated from an optional price field.

Common situations: Order built via a factory without trigger price then cast to a stop type; migrating code from plain Market to StopMarket without adding a trigger; deserialized order definitions with missing trigger fields.

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/80fedba265c99071. Report an issue: GitHub.

Appendix: source

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

        callback_rate: Option<String>,
        working_type: Option<BinanceWorkingType>,
        good_till_date: Option<i64>,
    ) -> anyhow::Result<OrderStatusReport> {
        let (symbol, price_precision, size_precision) =
            self.cached_precisions_by_id(instrument_id)?;

        let binance_side = BinanceSide::try_from(order_side)?;
        let binance_order_type = order_type_to_binance_futures(order_type)?;
        let binance_tif = BinanceTimeInForce::try_from(time_in_force)?;

        let requires_trigger_price = matches!(
            order_type,
            OrderType::StopMarket
                | OrderType::StopLimit
                | OrderType::MarketIfTouched
                | OrderType::LimitIfTouched
        );
        anyhow::ensure!(
            !requires_trigger_price || trigger_price.is_some(),
            "Algo order type {order_type:?} requires a trigger price"
        );

        // Limit orders require time in force
        let requires_time_in_force =
            matches!(order_type, OrderType::StopLimit | OrderType::LimitIfTouched);

        let price_str = price.map(|p| p.to_string());
        let trigger_price_str = if matches!(order_type, OrderType::TrailingStopMarket) {
            None
        } else {
            trigger_price.map(|p| p.to_string())
        };
        let reduce_only = reduce_only_param(reduce_only, position_side);
        let client_id_str = encode_broker_id(&client_order_id, BINANCE_NAUTILUS_FUTURES_BROKER_ID);

        // closePosition is mutually exclusive with quantity and reduceOnly

View on GitHub (pinned to 18893faf8b)