nautechsystems/nautilus_trader · error
Binance only supports TrailingOffsetType::BasisPoints…
Error message
Binance only supports TrailingOffsetType::BasisPoints, received {offset_type:?} What it means
Binance USDT-M futures trailing-stop orders only support callback rates expressed in basis points. During order validation in `validate_order`, if the Nautilus order carries a `trailing_offset_type` other than `TrailingOffsetType::BasisPoints`, the adapter rejects the submission with `anyhow::ensure!`. The offset must also be convertible to a valid Binance callback rate via `trailing_offset_to_callback_rate`.
Solutions
- Change the order's trailing offset type to `TrailingOffsetType::BasisPoints` and express the offset in basis points (e.g. 50 bps = 0.5%).
- Build trailing-stop orders per venue instead of reusing one order definition across venues.
- Convert a price-based offset to basis points relative to the trigger/current price before submitting to Binance.
- Verify with `trailing_offset_to_callback_rate` semantics that the basis-point offset falls within Binance's allowed callback-rate range.
Example fix
// before
let order = OrderFactory::trailing_stop_market(...,
TrailingOffset::Price(Price::from("100.0")),
TrailingOffsetType::Price);
// after
let order = OrderFactory::trailing_stop_market(...,
TrailingOffset::BasisPoints(50),
TrailingOffsetType::BasisPoints); Defensive patterns
Strategy: validation
Validate before calling
fn can_submit_trailing(order: &OrderAny) -> Result<(), String> {
match order.trailing_offset_type() {
Some(t) if t == TrailingOffsetType::BasisPoints => Ok(()),
Some(t) => Err(format!("Binance needs BasisPoints trailing offset, got {t:?}")),
None => Ok(()), // not a trailing order
}
} Type guard
fn is_binance_trailing(order: &OrderAny) -> bool {
matches!(order.trailing_offset_type(), Some(TrailingOffsetType::BasisPoints) | None)
} Try / catch
match client.submit_order(cmd).await {
Err(e) if e.to_string().contains("TrailingOffsetType") => {
// reconfigure order to BasisPoints and resubmit
}
other => other?,
} Prevention
- Configure trailing offsets per venue; Binance futures only accepts basis points.
- Centralize order construction so offset type is set from venue capability config.
- Unit-test adapter validation with a fake SubmitOrder before live routing.
When it happens
Trigger: Submitting a `SubmitOrder` command for a trailing-stop/trailing-stop-market order to a BinanceFuturesExecutionClient where `order.trailing_offset_type()` is `Price`, `BasisPoints` is not set, or any variant other than `BasisPoints` (e.g. a trailing order built with a price-based offset for another venue and reused for Binance).
Common situations: Reusing a trailing-stop order definition written for a venue that supports price-based trailing offsets (e.g. Bybit/FTX-style absolute offsets) on Binance; routing a multi-venue strategy without per-venue offset configuration; mistakenly passing `trailing_offset_type=TrailingOffsetType::Price` with an absolute offset value.
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
- Algo order type requires a trigger price
- callbackRate % out of Binance range [ , ]
- `close_position` cannot be combined with `reduce_only` on…
- `close_position` is not supported for order type
- `close_position` requires `reduce_only=true` on the…
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/95bd4e457d475b59.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/futures/execution.rs:3640
}
}
}
}
Ok(())
});
Ok(())
}
}
fn validate_order(
client: &BinanceFuturesExecutionClient,
cmd: &SubmitOrder,
order: &OrderAny,
) -> anyhow::Result<ValidatedOrder> {
if let Some(offset_type) = order.trailing_offset_type() {
anyhow::ensure!(
offset_type == TrailingOffsetType::BasisPoints,
"Binance only supports TrailingOffsetType::BasisPoints, received {offset_type:?}"
);
if let Some(offset) = order.trailing_offset() {
trailing_offset_to_callback_rate(offset)?;
}
}
let close_position = cmd
.params
.as_ref()
.and_then(|params| params.get_bool(PARAMS_CLOSE_POSITION))
.unwrap_or(false);
if close_position {
let order_type = order.order_type();
anyhow::ensure!(View on GitHub (pinned to 18893faf8b)