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
- Remove or convert stop/trailing orders for Betfair instruments — manage exits in strategy logic with cancel/replace on price updates.
- Gate order creation by venue support before submitting.
- 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
- Centralize order creation per venue and reject stop/trailing types for BETFAIR at build time.
- Implement exits with strategy-driven cancel/replace of limit orders instead of stop orders.
- Add a checklist assertion in integration tests that only Limit/Market orders reach the Betfair client.
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
- Limit order missing price
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
- pandas is required for visualization; install it with `pip i
- {name} must not be None
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/84beea390d5df5eb.
Report an issue: GitHub.