nautechsystems/nautilus_trader · error · anyhow::Error
Binance Futures GTD cannot be post-only
Error message
Binance Futures GTD cannot be post-only
What it means
The Binance futures native GTD path rejects post-only orders: a goodTillDate expiry combined with post_only is not a supported combination on the venue, so the lifetime resolution fails before submission. The guard runs after the order-type check and before the product-type check in the same function, and like the others only applies when manage_gtd_expiry (use_gtd) is enabled on the submitting strategy.
Source
Thrown at crates/adapters/binance/src/futures/execution.rs:1179
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"
);
let minimum_ns = ts_now
.as_u64()
.checked_add(BINANCE_GTD_MIN_LEAD_SECS * NANOSECONDS_IN_SECOND)
.context("Binance Futures GTD minimum timestamp overflow")?;
anyhow::ensure!(View on GitHub (pinned to a4b06ed870)
Solutions
- Disable post_only on GTD orders
- Drop the expiry (use plain Gtc post-only) if maker-only behavior matters more than the expiry
- Or disable manage_gtd_expiry so GTD downgrades to GTC post-only instead of erroring
Example fix
// before
let order = Order::limit(instrument_id, side, qty, price)
.time_in_force(TimeInForce::Gtd).expire_time(expiry).post_only(true);
// after
let order = Order::limit(instrument_id, side, qty, price)
.time_in_force(TimeInForce::Gtd).expire_time(expiry).post_only(false); Defensive patterns
Strategy: validation
Validate before calling
use nautilus_model::enums::TimeInForce;
if order.time_in_force() == TimeInForce::Gtd && strategy.manage_gtd_expiry {
anyhow::ensure!(!order.post_only(), "GTD + post_only rejected by Binance Futures");
} Type guard
fn gtd_post_only_ok(order: &OrderAny) -> bool {
!(order.time_in_force() == TimeInForce::Gtd && order.post_only())
} Prevention
- Keep quoting (post_only) and expiry (GTD) as separate order templates
- Assert TIF/post_only combinations in strategy unit tests before deployment
When it happens
Trigger: Submitting a Limit order with TimeInForce::Gtd, an expire_time, and post_only=true from a strategy with manage_gtd_expiry enabled — e.g. a market-making strategy that defaulted post_only on all quoting orders while also setting expiries.
Common situations: Market-making configs that globally enable post_only; strategies combining expiry management with maker-only quoting for the first time.
Related errors
- Binance Futures does not support GTD for order type {order_t
- Binance {product_type:?} Futures does not support native GTD
- Binance Futures goodTillDate requires whole-second precision
- Binance Futures goodTillDate must be strictly greater than c
- Binance Futures goodTillDate must be smaller than {BINANCE_G
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/c7dc82faff8bd6a3.
Report an issue: GitHub.