nautechsystems/nautilus_trader · error
TrailingStopMarket requires trailing_offset_type
Error message
TrailingStopMarket requires trailing_offset_type
What it means
Along with trailing_offset, a TrailingStopMarket order on OKX requires trailing_offset_type, which tells the adapter how to interpret the offset (BasisPoints -> callback_ratio, price/other units -> callback_spread). Missing it means the adapter cannot choose the OKX parameter encoding, so submission fails.
Source
Thrown at crates/adapters/okx/src/execution.rs:893
let price = context.price;
let is_reduce_only = context.is_reduce_only;
let trailing_offset = order.trailing_offset();
let trailing_offset_type = order.trailing_offset_type();
let activation_price = order.activation_price();
let close_fraction = get_param_as_string(&cmd.params, "close_fraction");
let reduce_only = if close_fraction.is_some() {
Some(true)
} else {
Some(is_reduce_only)
};
let (callback_ratio, callback_spread) = if order_type == OrderType::TrailingStopMarket {
let offset = trailing_offset
.ok_or_else(|| anyhow::anyhow!("TrailingStopMarket requires trailing_offset"))?;
let offset_type = trailing_offset_type.ok_or_else(|| {
anyhow::anyhow!("TrailingStopMarket requires trailing_offset_type")
})?;
match offset_type {
TrailingOffsetType::BasisPoints => {
// Convert basis points to ratio (e.g., 100 bps = 0.01)
let ratio = offset / Decimal::from(10000);
(Some(ratio.to_string()), None)
}
TrailingOffsetType::Price => (None, Some(offset.to_string())),
_ => {
anyhow::bail!("Unsupported trailing_offset_type for OKX: {offset_type:?}");
}
}
} else {
(None, None)
};
self.ws_dispatch_state.track_order_context(context);View on GitHub (pinned to 18893faf8b)
Solutions
- Set trailing_offset_type (e.g. TrailingOffsetType::BasisPoints or Price) whenever trailing_offset is set for TrailingStopMarket.
- Use the order factory's trailing_stop_market constructor which takes both parameters.
- Add a pre-submit validation in strategy code for trailing orders.
- If the desired unit is percent/bps, remember the adapter converts (100 bps = 0.01 ratio).
Example fix
// before let cmd = ...TrailingStopMarket..., trailing_offset: Some(Decimal::from(50)), trailing_offset_type: None... // after let cmd = ...trailing_offset: Some(Decimal::from(50)), trailing_offset_type: Some(TrailingOffsetType::BasisPoints)...
Defensive patterns
Strategy: validation
Validate before calling
if order_type == OrderType::TrailingStopMarket && trailing_offset_type.is_none() {
return Err(anyhow::anyhow!(
"TrailingStopMarket requires trailing_offset_type"
));
} Type guard
fn has_offset_type(t: &TrailingOffsetType) -> bool { true } // prefer Option::is_some check Prevention
- Pair trailing_offset with trailing_offset_type at the strategy layer, never separately.
- Use the order factory constructor that accepts both parameters.
- Document the unit semantics (bps -> ratio, price -> spread) in strategy config.
When it happens
Trigger: submit_order -> submit_conditional_order with order_type == TrailingStopMarket and trailing_offset_type == None, even when trailing_offset is provided.
Common situations: Strategy sets the numeric offset but forgets the unit; porting from venues where the offset type is implicit; factory helpers that only set one of the two fields.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- TrailingStopMarket requires trailing_offset
- Market-if-touched orders require a trigger price
- Limit-if-touched orders require a trigger price
- Kraken Spot trailing stops do not support activation trigger
- Unsupported trailing_offset_type for OKX: {offset_type:?}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2fd093e2c54d32f4.
Report an issue: GitHub.