nautechsystems/nautilus_trader · error · anyhow::Error

Binance Futures does not support GTD for order type {order_t

Error message

Binance Futures does not support GTD for order type {order_type:?}

What it means

When resolving the order lifetime for a native GTD (good-till-date) order, the Binance futures client only accepts Limit, StopLimit, and LimitIfTouched order types — the venue's goodTillDate applies to resting limit-family orders only. The guard fires when time_in_force is Gtd, the submitting strategy enabled manage_gtd_expiry (use_gtd=true), and the order type is anything else (Market, StopMarket, MarketIfTouched). With manage_gtd_expiry=false the client instead downgrades GTD to GTC with a warning, never reaching this error.

Source

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

) -> anyhow::Result<FuturesOrderLifetime> {
    if time_in_force != TimeInForce::Gtd {
        return Ok(FuturesOrderLifetime {
            time_in_force,
            good_till_date: None,
        });
    }

    if !use_gtd {
        log::warn!(
            "Binance Futures GTD submitted as GTC because use_gtd=false. Enable manage_gtd_expiry on the submitting strategy"
        );
        return Ok(FuturesOrderLifetime {
            time_in_force: TimeInForce::Gtc,
            good_till_date: None,
        });
    }

    anyhow::ensure!(
        matches!(
            order_type,
            OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched
        ),
        "Binance Futures does not support GTD for order type {order_type:?}"
    );
    anyhow::ensure!(!post_only, "Binance Futures GTD cannot be post-only");

    anyhow::ensure!(
        product_type == BinanceProductType::UsdM,
        "Binance {product_type:?} Futures does not support native GTD"
    );

    let expire_time = expire_time.context("Binance Futures GTD requires an expire_time")?;
    let expire_ns = expire_time.as_u64();
    anyhow::ensure!(
        expire_ns.is_multiple_of(NANOSECONDS_IN_SECOND),
        "Binance Futures goodTillDate requires whole-second precision"

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Submit GTD only with Limit, StopLimit, or LimitIfTouched orders
  2. Use Gtc for market-type orders (their lifetime is inherently immediate)
  3. Alternatively leave manage_gtd_expiry=false so GTD is downgraded to GTC with a warning instead of erroring

Example fix

// before
let order = Order::market(instrument_id, side, qty).time_in_force(TimeInForce::Gtd)
    .expire_time(expiry); // manage_gtd_expiry=true on the strategy

// after
let order = Order::market(instrument_id, side, qty).time_in_force(TimeInForce::Gtc);
// or keep Gtd but submit a Limit order instead of Market
Defensive patterns

Strategy: validation

Validate before calling

use nautilus_model::enums::{OrderType, TimeInForce};

if order.time_in_force() == TimeInForce::Gtd && strategy.manage_gtd_expiry {
    anyhow::ensure!(
        matches!(order.order_type(), OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched),
        "GTD unsupported for {}",
        order.order_type()
    );
}

Type guard

fn gtd_supported_for(order_type: OrderType) -> bool {
    matches!(order_type, OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched)
}

Prevention

When it happens

Trigger: Submitting a Market, StopMarket, or MarketIfTouched order with TimeInForce::Gtd and an expire_time set, while the submitting strategy has manage_gtd_expiry enabled.

Common situations: A generic execution algorithm that stamps Gtd plus an expiry onto every order regardless of type; strategies ported from venues that accept GTD on market-type orders.

Related errors


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