nautechsystems/nautilus_trader · error · anyhow::Error
Binance Spot does not support native GTD; set use_gtd=false…
Error message
Binance Spot does not support native GTD; set use_gtd=false and enable manage_gtd_expiry on the submitting strategy
What it means
Binance Spot does not support native GTD (Good-Til-Date) time-in-force. `time_in_force_to_binance_spot` rejects `TimeInForce::Gtd` when `use_gtd` is true, telling the caller to disable native GTD (`use_gtd=false`, so GTD is downgraded to GTC) and enable `manage_gtd_expiry` on the submitting strategy so expiry is enforced locally.
Solutions
- Set `use_gtd=false` on the Binance Spot exec client config so GTD orders are submitted as GTC with a warning
- Enable `manage_gtd_expiry` on the submitting strategy so it cancels the order at expiry locally
- Change the strategy to use `TimeInForce::Gtc` or `Ioc`/`Fok` directly instead of Gtd on Spot
- Route GTD-dependent strategies to Binance USDT-M Futures, which supports native GTD
Example fix
// before
ExecClientConfig { use_gtd: true, /* strategy submits TimeInForce::Gtd */ }
// after
ExecClientConfig { use_gtd: false }; // + strategy config: manage_gtd_expiry=True Defensive patterns
Strategy: validation
Validate before calling
fn validate_spot_tif(tif: TimeInForce, use_gtd: bool) -> Result<(), String> {
if tif == TimeInForce::Gtd && use_gtd {
return Err("Binance Spot needs use_gtd=false plus manage_gtd_expiry for GTD orders".into());
}
Ok(())
} Type guard
fn is_spot_supported_tif(tif: TimeInForce) -> bool {
matches!(tif, TimeInForce::Gtc | TimeInForce::Ioc | TimeInForce::Fok
| TimeInForce::Gtd /* only with use_gtd=false */)
} Try / catch
match exec_client.submit_order(order) {
Err(e) if e.to_string().contains("does not support native GTD") => {
log::warn!("resubmitting GTD order as GTC with local expiry management");
exec_client.set_use_gtd(false);
strategy.manage_gtd_expiry = true;
exec_client.submit_order(order)?;
}
other => other?,
} Prevention
- Set use_gtd=false in the Binance Spot exec client config when strategies use GTD
- Enable manage_gtd_expiry on any strategy that submits GTD orders
- Prefer GTC/IOC/FOK time-in-force for Spot strategies
- Avoid sharing strategy configs between Binance Futures and Spot without auditing time-in-force usage
When it happens
Trigger: Submitting, modifying, or building params for an order with `TimeInForce::Gtd` via `submit_order` / `modify_order` / `build_new_order_params` / `build_cancel_replace_params` while the exec client's `use_gtd` option is enabled (default true).
Common situations: Reusing a strategy written for Binance Futures (which supports native GTD) on Spot; leaving adapter `use_gtd` at its default while the strategy sets GTD expiry; porting crypto strategies that rely on exchange-side order expiry.
Related errors
- Binance Futures goodTillDate must be strictly greater than…
- Binance load_ids value
- Binance Spot market data mode SBE requires Ed25519 API…
- invalid Binance load_ids value
- Invalid price_match value
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8dbb3bab51665191.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/spot/enums.rs:141
///
/// # Errors
///
/// Returns an error if the time in force is not supported on Binance Spot.
pub fn time_in_force_to_binance_spot(
tif: TimeInForce,
use_gtd: bool,
) -> anyhow::Result<BinanceTimeInForce> {
match tif {
TimeInForce::Gtc => Ok(BinanceTimeInForce::Gtc),
TimeInForce::Ioc => Ok(BinanceTimeInForce::Ioc),
TimeInForce::Fok => Ok(BinanceTimeInForce::Fok),
TimeInForce::Gtd if !use_gtd => {
log::warn!(
"Binance Spot does not support GTD; submitting as GTC because use_gtd=false. Enable manage_gtd_expiry on the submitting strategy"
);
Ok(BinanceTimeInForce::Gtc)
}
TimeInForce::Gtd => anyhow::bail!(
"Binance Spot does not support native GTD; set use_gtd=false and enable manage_gtd_expiry on the submitting strategy"
),
_ => anyhow::bail!("Unsupported time in force for Binance Spot: {tif:?}"),
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
#[case(OrderType::Market, false, BinanceSpotOrderType::Market)]
#[case(OrderType::Limit, false, BinanceSpotOrderType::Limit)]
#[case(OrderType::Limit, true, BinanceSpotOrderType::LimitMaker)]
#[case(OrderType::StopMarket, false, BinanceSpotOrderType::StopLoss)]
#[case(OrderType::StopLimit, false, BinanceSpotOrderType::StopLossLimit)]View on GitHub (pinned to 18893faf8b)