nautechsystems/nautilus_trader · error
Missing `limit_offset` for trailing stop limit calculation
Error message
Missing `limit_offset` for trailing stop limit calculation
What it means
For a `TrailingStopLimit` order with `TriggerType::LastPrice` or `MarkPrice`, the calculator needs a `limit_offset` to compute the new limit price from the last price. `OrderAny::limit_offset()` returned `None`, so the calculation aborts — a trailing-stop-limit order without a limit offset is incomplete and cannot be repriced correctly.
Source
Thrown at crates/execution/src/trailing.rs:128
anyhow::bail!("`TrailingOffsetType` {trailing_offset_type} not currently supported")
}
};
let value = match order_side {
OrderSide::Buy => basis + offset,
OrderSide::Sell => basis - offset,
};
Price::from_decimal_dp(value, price_increment.precision).map_err(Into::into)
};
match trigger_type {
TriggerType::LastPrice | TriggerType::MarkPrice => {
let last = last.ok_or(OrderError::InvalidStateTransition)?;
let cand_trigger = compute(trailing_offset, last)?;
new_trigger_price = maybe_move(&mut trigger_price, cand_trigger, better_trigger);
if order_type == OrderType::TrailingStopLimit {
let limit_offset = order.limit_offset().ok_or_else(|| {
anyhow::anyhow!("Missing `limit_offset` for trailing stop limit calculation")
})?;
let cand_limit = compute(limit_offset, last)?;
new_limit_price = maybe_move(&mut limit_price, cand_limit, better_limit);
}
}
TriggerType::Default | TriggerType::BidAsk | TriggerType::LastOrBidAsk => {
let (bid, ask) = (
bid.ok_or_else(|| anyhow::anyhow!("Bid required"))?,
ask.ok_or_else(|| anyhow::anyhow!("Ask required"))?,
);
let basis = match order_side {
OrderSide::Buy => ask,
OrderSide::Sell => bid,
};
let cand_trigger = compute(trailing_offset, basis)?;
new_trigger_price = maybe_move(&mut trigger_price, cand_trigger, better_trigger);
if order_type == OrderType::TrailingStopLimit {View on GitHub (pinned to 18893faf8b)
Solutions
- Set `limit_offset` on the TrailingStopLimit order at construction time (same unit semantics governed by `trailing_offset_type`).
- If the order should be a trailing stop market, change `order_type` to `TrailingStopMarket` so the limit-offset branch is not taken.
- Guard before calling: `if order.order_type() == OrderType::TrailingStopLimit && order.limit_offset().is_none() { ... }` and repair or reject the order.
Example fix
// before
let order = OrderAny::builder()
.order_type(OrderType::TrailingStopLimit)
.trailing_offset(Decimal::from(50))
.trailing_offset_type(TrailingOffsetType::Ticks)
.build()?;
// after
let order = OrderAny::builder()
.order_type(OrderType::TrailingStopLimit)
.trailing_offset(Decimal::from(50))
.limit_offset(Decimal::from(10))
.trailing_offset_type(TrailingOffsetType::Ticks)
.build()?; Defensive patterns
Strategy: validation
Validate before calling
fn ensure_limit_offset(order: &OrderAny) -> Result<(), String> {
if order.order_type() == OrderType::TrailingStopLimit && order.limit_offset().is_none() {
return Err(format!(
"TrailingStopLimit order {} is missing limit_offset",
order.client_order_id()
));
}
Ok(())
} Type guard
fn is_complete_trailing_stop_limit(order: &OrderAny) -> bool {
order.order_type() != OrderType::TrailingStopLimit || order.limit_offset().is_some()
} Prevention
- Treat `limit_offset` as mandatory whenever the order type is TrailingStopLimit.
- Centralize order construction in a factory that enforces the trailing-stop-limit field set.
- Add a unit test asserting TrailingStopLimit orders always carry limit_offset before reaching trailing_stop_calculate.
When it happens
Trigger: Calling `trailing_stop_calculate` (or `update_trailing_stop_order`) with `order_type == TrailingStopLimit`, `trigger_type` of `LastPrice`/`MarkPrice`, and a `last` price present, while the order has no `limit_offset` set.
Common situations: Building a TrailingStopLimit order and setting only `trailing_offset` but not `limit_offset`; a venue adapter or strategy template that populates trailing-stop-market fields but not limit fields; deserialized orders from schema versions without `limit_offset`.
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
- Missing `TrailingOffsetType` for trailing stop calculation
- callbackRate {rate}% out of Binance range [{min_rate}, {max_
- BitMEX only supports PRICE trailing offset type, was {offset
- Limit orders require a price
- Stop market orders require a trigger price
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3a12bcbd55751e44.
Report an issue: GitHub.