nautechsystems/nautilus_trader · error · anyhow::Error

Binance only supports TrailingOffsetType::BasisPoints, recei

Error message

Binance only supports TrailingOffsetType::BasisPoints, received {offset_type:?}

What it means

Binance Futures TRAILING_STOP_MARKET orders express the trailing distance only as a callback rate in basis points (the callbackRate parameter). Before submission the adapter inspects the cached order and rejects it locally if trailing_offset_type is anything other than TrailingOffsetType::BasisPoints (e.g. Price or Percent), so no invalid request reaches the venue.

Source

Thrown at crates/adapters/binance/src/futures/execution.rs:2528

        self.core.set_disconnected();
        log::info!("Stopped: client_id={}", self.core.client_id);
        Ok(())
    }

    fn submit_order(&self, cmd: SubmitOrder) -> anyhow::Result<()> {
        let order = self.core.cache().try_order_owned(&cmd.client_order_id)?;

        if order.is_closed() {
            let client_order_id = order.client_order_id();
            log::warn!("Cannot submit closed order {client_order_id}");
            return Ok(());
        }

        // Validate before submission (Initialized -> Denied is valid,
        // but Submitted -> Denied is not, so validate before emitting OrderSubmitted)
        if let Some(offset_type) = order.trailing_offset_type() {
            if offset_type != TrailingOffsetType::BasisPoints {
                anyhow::bail!(
                    "Binance only supports TrailingOffsetType::BasisPoints, received {offset_type:?}"
                );
            }

            if let Some(offset) = order.trailing_offset() {
                trailing_offset_to_callback_rate(offset)?;
            }
        }

        let close_position = cmd
            .params
            .as_ref()
            .and_then(|p| p.get_bool("close_position"))
            .unwrap_or(false);

        if close_position {
            let order_type = order.order_type();

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Build trailing orders with TrailingOffsetType::BasisPoints and a trailing_offset in basis points (e.g. 100 = 1%)
  2. Convert a desired absolute-price or percent offset into basis points before creating the order
  3. If true price-based trailing is required, emulate it strategy-side by moving STOP_MARKET trigger prices instead

Example fix

// before — trailing offset expressed as an absolute price
// TrailingStopMarketOrder::new(..., TrailingOffsetType::Price, trailing_offset: dec!(150), ...)

// after — Binance accepts basis-point callback rates only (100 bp = 1%)
// TrailingStopMarketOrder::new(..., TrailingOffsetType::BasisPoints, trailing_offset: dec!(100), ...)
Defensive patterns

Strategy: validation

Validate before calling

// Guard before submit_order()
if matches!(order.order_type(), OrderType::TrailingStopMarket | OrderType::TrailingStopLimit) {
    if let Some(t) = order.trailing_offset_type() {
        assert_eq!(t, TrailingOffsetType::BasisPoints, "Binance supports basis-point trailing only");
    }
}

Type guard

fn trailing_supported_on_binance(order: &OrderAny) -> bool {
    order
        .trailing_offset_type()
        .is_none_or(|t| t == TrailingOffsetType::BasisPoints)
}

Try / catch

Subscribe to order denied/rejected events: this validation denies the order before submission; log the order's trailing_offset_type and fix the order factory configuration.

Prevention

When it happens

Trigger: A strategy submits a trailing stop market (or trailing stop limit) order built with trailing_offset_type = TrailingOffsetType::Price or TrailingOffsetType::Percent to the Binance Futures execution client.

Common situations: Strategies ported from venues that support price/percent trailing offsets; order templates reused across adapters; manually specifying TrailingOffsetType when porting strategy code.

Related errors


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