nautechsystems/nautilus_trader · error · anyhow::Error

`close_position` is not supported for order type {order_type

Error message

`close_position` is not supported for order type {order_type:?} on Binance

What it means

The close_position parameter (closePosition=1) asks Binance Futures to close the entire position when the order triggers; the venue only accepts it on STOP_MARKET and MARKET_IF_TOUCHED orders. The adapter enforces this before submission and rejects any other order type (LIMIT, MARKET, STOP_LIMIT, TRAILING_STOP_MARKET) with this message.

Source

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

            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();

            if !matches!(
                order_type,
                OrderType::StopMarket | OrderType::MarketIfTouched
            ) {
                anyhow::bail!(
                    "`close_position` is not supported for order type {order_type:?} on Binance"
                );
            }

            if order.is_reduce_only() {
                anyhow::bail!("`close_position` cannot be combined with `reduce_only` on Binance");
            }
        }

        if let Some(pm_str) = cmd.params.as_ref().and_then(|p| p.get_str("price_match")) {
            BinancePriceMatch::from_param(pm_str)?;
            let order_type = order.order_type();
            anyhow::ensure!(
                !order.is_post_only(),
                "price_match cannot be combined with post-only orders"
            );
            anyhow::ensure!(
                order_type == OrderType::Limit,

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Use a STOP_MARKET or MARKET_IF_TOUCHED order (with a trigger price) when setting close_position=true
  2. Alternatively drop close_position and send a reduce-only order sized to the current position
  3. For immediate liquidation use a plain MARKET order with quantity equal to the position size

Example fix

// before — close_position on a LIMIT order (rejected locally)
// params: close_position = true; order_type = OrderType::Limit

// after — close_position only on trigger order types
// params: close_position = true; order_type = OrderType::StopMarket with trigger price set
Defensive patterns

Strategy: validation

Validate before calling

// Before submit_order() with close_position
let close_position = params.get_bool("close_position").unwrap_or(false);
if close_position {
    assert!(
        matches!(order.order_type(), OrderType::StopMarket | OrderType::MarketIfTouched),
        "close_position requires STOP_MARKET or MARKET_IF_TOUCHED"
    );
}

Type guard

fn close_position_combinable(order: &OrderAny, close_position: bool) -> bool {
    !close_position
        || matches!(order.order_type(), OrderType::StopMarket | OrderType::MarketIfTouched)
}

Try / catch

Handle the submit_order error (or resulting denied/rejected order event) by rebuilding the order as STOP_MARKET/MARKET_IF_TOUCHED or removing the close_position param, then resubmitting.

Prevention

When it happens

Trigger: SubmitOrder with params containing close_position=true on an order whose type is not StopMarket or MarketIfTouched.

Common situations: Close-all logic written for one order type and reused on another; porting from adapters or venues where close_position applies more broadly.

Related errors


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