nautechsystems/nautilus_trader · error

Invalid `OrderType` {order_type} for protection price calcul

Error message

Invalid `OrderType` {order_type} for protection price calculation

What it means

`protection_price_calculate` computes a protection (slippage-bounded) price for Market and StopMarket orders only. Any other OrderType (Limit, StopLimit, etc.) cannot have a protection price applied, so it bails with 'Invalid `OrderType` {order_type} for protection price calculation'.

Source

Thrown at crates/execution/src/protection.rs:43

/// Uses integer arithmetic on raw price values to avoid floating-point precision issues.
///
/// # Returns
/// A calculated protection price.
///
/// # Errors
/// Returns an error if:
/// - the order type is invalid.
/// - best bid/ask is not provided when required for the order side.
pub fn protection_price_calculate(
    price_increment: Price,
    order: &OrderAny,
    protection_points: u32,
    bid: Option<Price>,
    ask: Option<Price>,
) -> anyhow::Result<Price> {
    let order_type = order.order_type();
    if !matches!(order_type, OrderType::Market | OrderType::StopMarket) {
        anyhow::bail!("Invalid `OrderType` {order_type} for protection price calculation");
    }

    let offset_raw = PriceRaw::from(protection_points) * price_increment.raw;

    let order_side = order.order_side();
    let protection_raw = match order_side {
        OrderSide::Buy => {
            let opposite = ask.ok_or_else(|| anyhow::anyhow!("Ask required"))?;
            opposite.raw + offset_raw
        }
        OrderSide::Sell => {
            let opposite = bid.ok_or_else(|| anyhow::anyhow!("Bid required"))?;
            opposite.raw - offset_raw
        }
    };

    Ok(Price::from_raw(protection_raw, price_increment.precision))
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Only invoke protection price calculation for Market or StopMarket orders
  2. Branch on order_type() before calling and skip/defer protection for other types
  3. Fix the upstream submission so the intended order type matches the protection config

Example fix

// before
let protected_px = protection_price_calculate(&order, points, bid, ask)?; // Limit order
// after
if matches!(order.order_type(), OrderType::Market | OrderType::StopMarket) {
    let protected_px = protection_price_calculate(&order, points, bid, ask)?;
} else {
    // use the order's explicit limit price instead
}
Defensive patterns

Strategy: type-guard

Validate before calling

if !matches!(order.order_type(), OrderType::Market | OrderType::StopMarket) {
    // skip protection-price logic; use the order's own limit price
}

Type guard

fn supports_protection(order: &OrderAny) -> bool {
    matches!(order.order_type(), OrderType::Market | OrderType::StopMarket)
}

Try / catch

match protection_price_calculate(&order, points, bid, ask) {
    Ok(px) => px,
    Err(e) if e.to_string().contains("Invalid `OrderType`") => order.display_px().unwrap_or(last_px),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `protection_price_calculate(order, protection_points, bid, ask)` with an order whose `order_type()` is Limit, StopLimit, or any non-market type; also reached by fill_market_order if the order mutated type mid-pipeline.

Common situations: Wiring protection-price logic into a generic fill handler that also receives Limit orders; venue emulation code applied to all order types instead of market-like ones; misconfigured strategy submitting StopLimit orders through a market-fill emulator.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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