nautechsystems/nautilus_trader · error

Unsupported order type for Betfair: {other:?}

Error message

Unsupported order type for Betfair: {other:?}

What it means

The Betfair place-instruction builder handles only OrderType::Limit and OrderType::Market; every other Nautilus order type (stop-market, stop-limit, trailing-stop, market-to-limit, ...) falls into the 'other' arm and bails. Betfair's API has no equivalent native stop order types, so these are hard local rejections before any request is sent.

Source

Thrown at crates/adapters/betfair/src/execution.rs:1852

                if order.time_in_force() != TimeInForce::AtTheClose {
                    anyhow::bail!(
                        "Market orders on Betfair are only supported with AtTheClose \
                         time in force (BSP MarketOnClose)"
                    );
                }
                PlaceInstruction {
                    order_type: BetfairOrderType::MarketOnClose,
                    selection_id,
                    handicap: handicap_opt,
                    side,
                    limit_order: None,
                    limit_on_close_order: None,
                    market_on_close_order: Some(MarketOnCloseOrder { liability: size }),
                    customer_order_ref,
                }
            }
            other => {
                anyhow::bail!("Unsupported order type for Betfair: {other:?}");
            }
        };

        let market_version = self.get_market_version(&instrument_id);

        let params = PlaceOrdersParams {
            market_id,
            instructions: vec![instruction],
            customer_ref: None,
            market_version,
            customer_strategy_ref: None,
        };

        let client_order_id = order.client_order_id();
        let strategy_id = order.strategy_id();

        log::debug!("OrderSubmitted client_order_id={client_order_id}");
        self.emitter.emit_order_submitted(&order);

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Remove or convert stop/trailing orders for Betfair instruments — manage exits in strategy logic with cancel/replace on price updates.
  2. Gate order creation by venue support before submitting.
  3. Use Limit orders with the TIF-to-persistence mapping (LAPSE/PERSIST/MARKET_ON_CLOSE) to express Betfair-native behavior.

Example fix

// before
let stop = factory.stop_market(instrument_id, side, qty, trigger_price).build()?;
engine.submit_order(&stop); // Betfair: unsupported

// after
if instrument_id.venue() == &VENUE_BETFAIR {
    // manage exit in strategy: cancel/replace limit as price moves
} else {
    let stop = factory.stop_market(instrument_id, side, qty, trigger_price).build()?;
    engine.submit_order(&stop);
}
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_supported_betfair_order_type(order_type: OrderType) -> bool {
    matches!(order_type, OrderType::Limit | OrderType::Market)
}

Type guard

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

Prevention

When it happens

Trigger: Calling submit_order with a stop or trailing order (e.g. factory.stop_market(...)) on a BETFAIR instrument; the match at execution.rs:1852 hits the catch-all arm.

Common situations: Shared strategies with bracket/stop-loss legs; risk-management code attaching stop orders to entries; backtests pass because the simulated venue accepts the types that live Betfair rejects.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/84beea390d5df5eb. Report an issue: GitHub.