nautechsystems/nautilus_trader · error

unsupported time in force for Derive: {other:?}

Error message

unsupported time in force for Derive: {other:?}

What it means

This error is raised by `time_in_force_to_derive` when a Nautilus `TimeInForce` value cannot be mapped to a Derive time-in-force. Derive only supports GTC, IOC, and FOK; post-only orders additionally must use GTC. Any other variant (e.g. GTD, DAY, AT_THE_OPEN) falls into the catch-all `other` arm and is rejected.

Source

Thrown at crates/adapters/derive/src/common/parse.rs:198

/// Maps a Nautilus time-in-force flag to the Derive TIF.
///
/// # Errors
///
/// Returns an error for time-in-force flags Derive does not accept.
pub fn time_in_force_to_derive(
    tif: TimeInForce,
    post_only: bool,
) -> anyhow::Result<DeriveTimeInForce> {
    match tif {
        TimeInForce::Gtc if post_only => Ok(DeriveTimeInForce::PostOnly),
        TimeInForce::Ioc | TimeInForce::Fok if post_only => anyhow::bail!(
            "post-only Derive orders only support GTC time in force; received {tif:?}"
        ),
        TimeInForce::Gtc => Ok(DeriveTimeInForce::Gtc),
        TimeInForce::Ioc => Ok(DeriveTimeInForce::Ioc),
        TimeInForce::Fok => Ok(DeriveTimeInForce::Fok),
        other => anyhow::bail!("unsupported time in force for Derive: {other:?}"),
    }
}

/// Maps a Derive order side back to Nautilus.
#[must_use]
pub fn derive_order_side_to_nautilus(side: DeriveOrderSide) -> OrderSide {
    match side {
        DeriveOrderSide::Buy => OrderSide::Buy,
        DeriveOrderSide::Sell => OrderSide::Sell,
    }
}

/// Maps a Derive order type back to Nautilus.
///
/// Unmodeled venue order types decode as [`DeriveOrderType::Unknown`] and map
/// to [`OrderType::Limit`] so the order stays visible to reconciliation.
#[must_use]
pub fn derive_order_type_to_nautilus(order_type: DeriveOrderType) -> OrderType {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change the order's time_in_force to Gtc, Ioc, or Fok before submitting to Derive.
  2. If an expiry is required, emulate GTD by cancelling the order client-side at expiry instead of using TimeInForce::Gtd.
  3. Run validate_order_support before submission to fail fast with the same check.
  4. Check post_only orders are explicitly Gtc (Ioc/Fok + post_only are rejected separately).

Example fix

// before
let order = builder.time_in_force(TimeInForce::Gtd(expiry)).build();
// after
let order = builder.time_in_force(TimeInForce::Gtc).build();
Defensive patterns

Strategy: validation

Validate before calling

fn derive_supported_tif(tif: &TimeInForce, post_only: bool) -> Result<(), String> {
    match tif {
        TimeInForce::Gtc => Ok(()),
        TimeInForce::Ioc | TimeInForce::Fok if !post_only => Ok(()),
        _ => Err(format!("{tif:?} not supported by Derive")),
    }
}

Try / catch

match time_in_force_to_derive(tif, post_only) {
    Ok(dtif) => submit(dtif),
    Err(e) => { log::warn!("falling back to GTC: {e}"); submit_gtc(); }
}

Prevention

When it happens

Trigger: Passing a TimeInForce other than Gtc/Ioc/Fok to order_to_derive_payload, trigger_order_to_derive_payload, order_replace_to_derive_payload, or validate_order_support. Note that Ioc/Fok combined with post_only fail earlier with a different message; this error fires only for genuinely unmapped variants (e.g. TimeInForce::Gtd or Day).

Common situations: Configuring orders with GTD expiry (common for futures strategies) and submitting them through the Derive adapter; using default time-in-force settings from another adapter that Derive does not support; porting order templates across venues.

Related errors


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