nautechsystems/nautilus_trader · error · anyhow::Error

Unsupported time in force: {time_in_force:?}

Error message

Unsupported time in force: {time_in_force:?}

What it means

compute_ws_time_in_force only recognizes Gtc, Ioc, Fok, and Gtd; any other TimeInForce variant hits the catch-all arm and bails. This catches TIF values with no Kraken WS mapping (e.g. Day, AtTheOpen, or other venue-specific variants).

Source

Thrown at crates/adapters/kraken/src/common/order_params.rs:234

    expire_time: Option<UnixNanos>,
) -> anyhow::Result<Option<KrakenTimeInForce>> {
    if !is_limit_order {
        return Ok(None);
    }

    match time_in_force {
        TimeInForce::Gtc => Ok(None),
        TimeInForce::Ioc => Ok(Some(KrakenTimeInForce::ImmediateOrCancel)),
        TimeInForce::Fok => {
            anyhow::bail!("FOK time in force is not supported on Kraken WS v2; use REST")
        }
        TimeInForce::Gtd => {
            expire_time.ok_or_else(|| {
                anyhow::anyhow!("GTD time in force requires expire_time parameter")
            })?;
            Ok(Some(KrakenTimeInForce::GoodTilDate))
        }
        _ => anyhow::bail!("Unsupported time in force: {time_in_force:?}"),
    }
}

#[cfg(test)]
mod tests {
    use nautilus_core::{UUID4, UnixNanos};
    use nautilus_model::identifiers::{
        ClientOrderId, InstrumentId, StrategyId, TraderId, VenueOrderId,
    };
    use rstest::rstest;
    use rust_decimal_macros::dec;

    use super::*;

    fn make_cancel_order(client_order_id: &str, venue_order_id: Option<&str>) -> CancelOrder {
        CancelOrder {
            trader_id: TraderId::from("TESTER-001"),
            client_id: None,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use Gtc, Ioc, or Gtd time in force for orders sent over Kraken WS.
  2. For Gtd, also ensure expire_time is set (otherwise a separate error fires).
  3. Audit the strategy/executor config so venue-specific TIF values are not sent to the Kraken adapter.

Example fix

// before
order_factory.limit(instrument_id, side, qty, price, TimeInForce::Day, None)
// after
order_factory.limit(instrument_id, side, qty, price, TimeInForce::Gtc, None)
Defensive patterns

Strategy: validation

Validate before calling

const WS_TIFS: &[TimeInForce] = &[TimeInForce::Gtc, TimeInForce::Ioc, TimeInForce::Fok, TimeInForce::Gtd];
if !WS_TIFS.contains(&order.time_in_force()) {
    // remap to Gtc or reject before Kraken WS submission
}

Prevention

When it happens

Trigger: Submitting a Kraken WS order whose time_in_force is a variant outside the handled set, such as TimeInForce::Day or another exchange-specific TIF carried over from another adapter.

Common situations: Strategies configured for equities/futures venues (Day orders, auction TIFs) reused against Kraken; also hit when new TimeInForce variants are added upstream before the Kraken adapter maps them.

Related errors


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