nautechsystems/nautilus_trader · error · anyhow::Error
GTD STOP_LIMIT requires expire_time
Error message
GTD STOP_LIMIT requires expire_time
What it means
For a Good-Til-Date (GTD) STOP_LIMIT order, Coinbase's StopLimitGtd configuration requires an expiration timestamp. When time_in_force is GTD, the adapter reads the order's expire_time; if it is absent it cannot build the GTD order and raises this error. Other TIFs (e.g. GTC) do not need it.
Source
Thrown at crates/adapters/coinbase/src/http/client.rs:1703
let stop_price = trigger
.ok_or_else(|| anyhow::anyhow!("STOP_LIMIT order requires trigger_price"))?;
let direction = match side {
OrderSide::Buy => CoinbaseStopDirection::StopUp,
OrderSide::Sell => CoinbaseStopDirection::StopDown,
};
match time_in_force {
TimeInForce::Gtc => Ok(OrderConfiguration::StopLimitGtc(StopLimitGtc {
stop_limit_stop_limit_gtc: StopLimitGtcParams {
base_size: qty,
limit_price,
stop_price,
stop_direction: direction,
},
})),
TimeInForce::Gtd => {
let expire = expire_time
.ok_or_else(|| anyhow::anyhow!("GTD STOP_LIMIT requires expire_time"))?;
Ok(OrderConfiguration::StopLimitGtd(StopLimitGtd {
stop_limit_stop_limit_gtd: StopLimitGtdParams {
base_size: qty,
limit_price,
stop_price,
stop_direction: direction,
end_time: format_rfc3339_from_nanos(expire)?,
},
}))
}
_ => anyhow::bail!("Unsupported TIF {time_in_force} for STOP_LIMIT on Coinbase"),
}
}
other => anyhow::bail!("Unsupported order type for Coinbase: {other}"),
}
}
#[cfg(test)]View on GitHub (pinned to 18893faf8b)
Solutions
- Set expire_time (UTC datetime) on the order when using GTD, e.g. factory time_in_force=GTD with expire_time parameter.
- Use TimeInForce::Gtc instead if the order should not expire.
- Ensure the expire_time is in the future and formatted per the adapter's expectations (nanosecond timestamp).
Example fix
// before
let order = factory.stop_limit(..., time_in_force=TimeInForce.Gtd, expire_time=None);
// after
let order = factory.stop_limit(
...,
time_in_force=TimeInForce.Gtd,
expire_time=UnixNanos::from(u64::try_from(expiry_ts_nanos)?), // required for GTD
); Defensive patterns
Strategy: validation
Validate before calling
fn ensure_gtd_expiry(order: &OrderRequest) -> Result<(), String> {
if order.time_in_force == TimeInForce::Gtd && order.expire_time.is_none() {
return Err(format!("{}: GTD requires expire_time", order.client_order_id));
}
Ok(())
}
ensure_gtd_expiry(&req)?; Type guard
fn has_expiry(o: &OrderRequest) -> bool { o.time_in_force != TimeInForce::Gtd || o.expire_time.is_some() } Prevention
- Compute expire_time from strategy logic at order creation time, never later.
- Default to GTC when no expiry is needed.
- Keep a TIF-to-required-fields map in your order-construction layer.
When it happens
Trigger: Submitting OrderType::StopLimit with TimeInForce::Gtd while the order's expire_time/ts_init-derived expiry is None; constructing a GTD stop-limit order without an expiry argument; leaving expire_time unset when copying a GTC order and switching TIF to GTD.
Common situations: Changing an order's TIF from GTC to GTD without adding an expiry; time-based strategy logic computing expiry after order creation but before it is attached; factory calls that default expire_time to None.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- unsupported time in force for Derive: {other:?}
- FOK time in force only supported for LIMIT orders on Kraken
- Unsupported time in force: {time_in_force:?}
- Lighter market orders support only TimeInForce::Gtc or TimeI
- GTD time in force requires expire_time parameter
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7bedc41b474ca22c.
Report an issue: GitHub.