nautechsystems/nautilus_trader · error

`close_position` is not supported for order type

Error message

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

What it means

Binance's `closePosition` parameter is only valid for order types that can close a whole position with a trigger: `StopMarket` and `MarketIfTouched`. When `close_position=true` is set in params and the order type is anything else (Limit, Market, StopLimit, LimitIfTouched, etc.), validation rejects the request before it reaches the venue.

Solutions

  1. Use `OrderType::StopMarket` or `OrderType::MarketIfTouched` when `close_position=true` is set.
  2. Remove the `close_position` param and use a normal reduce-only order for other order types.
  3. For stop-limit style exits, drop close_position and instead set `reduce_only=true` with an explicit quantity.

Example fix

// before
let order = factory.stop_limit(...); // + params close_position=true
// after
let order = factory.stop_market(...); // params close_position=true, reduce_only=true
Defensive patterns

Strategy: validation

Validate before calling

fn check_close_position_type(order: &OrderAny, params: &Option<NautilusParams>) -> Result<(), String> {
    let close = params.as_ref()
        .and_then(|p| p.get_bool("close_position"))
        .unwrap_or(false);
    if close && !matches!(order.order_type(), OrderType::StopMarket | OrderType::MarketIfTouched) {
        return Err(format!("close_position unsupported for {:?}", order.order_type()));
    }
    Ok(())
}

Type guard

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

Try / catch

match client.submit_order(cmd).await {
    Err(e) if e.to_string().contains("not supported for order type") => {
        // switch to StopMarket/MarketIfTouched or drop close_position
    }
    other => other?,
}

Prevention

When it happens

Trigger: Submitting an order with `params.close_position=true` and an `order_type()` of `Limit`, `Market`, `StopLimit`, or `LimitIfTouched` on a BinanceFuturesExecutionClient.

Common situations: Attaching `close_position` to a generic order builder whose type was later changed; trying to close a position with a stop-limit (Binance requires STOP_MARKET or TAKE_PROFIT_MARKET semantics); template reuse across order types.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

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

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

    if close_position {
        let order_type = order.order_type();
        anyhow::ensure!(
            order.is_reduce_only(),
            "`close_position` requires `reduce_only=true` on the Nautilus order"
        );
        anyhow::ensure!(
            matches!(
                order_type,
                OrderType::StopMarket | OrderType::MarketIfTouched
            ),
            "`close_position` is not supported for order type {order_type:?} on Binance"
        );
    }

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

View on GitHub (pinned to 18893faf8b)