nautechsystems/nautilus_trader · error · anyhow::Error
AX does not support reduce-only orders
Error message
AX does not support reduce-only orders
What it means
validate_order_instructions bails immediately when the order carries reduce_only=true: AX's order encoding has no reduce-only flag, so the instruction cannot be represented. It is checked both at submit validation (from the live order) and at order-init validation (OrderInitialized event), so reduce-only orders are denied before submission and never reach the venue. The adapter intentionally fails loudly instead of silently dropping the semantics, which would risk over-closing or flipping positions.
Source
Thrown at crates/adapters/architect_ax/src/execution.rs:1919
Ok(())
}
fn validate_order_init_instructions(order_init: &OrderInitialized) -> anyhow::Result<()> {
validate_order_instructions(
order_init.reduce_only,
order_init.quote_quantity,
order_init.display_qty.is_some(),
)
}
fn validate_order_instructions(
reduce_only: bool,
quote_quantity: bool,
has_display_qty: bool,
) -> anyhow::Result<()> {
if reduce_only {
anyhow::bail!("AX does not support reduce-only orders");
}
if quote_quantity {
anyhow::bail!(
"Architect AX adapter cannot encode quote_quantity; submit a base quantity instead"
);
}
if has_display_qty {
anyhow::bail!("Architect AX adapter cannot encode display_qty iceberg instructions");
}
Ok(())
}
// The AX HTTP API documents only a bare 400 with no error schema, so no venue
// failure can be allowlisted as an unambiguous rejection; those arrive via the
// orders WS `Rejected` and `CancelRejected` events instead. AX therefore neverView on GitHub (pinned to a4b06ed870)
Solutions
- Submit the exit order with reduce_only unset (false) and size it exactly to the open position
- Track netting positions yourself (AX is Netting/Margin in this adapter) and only send the delta you intend
- Add a pre-submit assertion so reduce-only never reaches the AX client
Example fix
// before
let exit = factory.market(id, opposite_side, qty)
.reduce_only(true); // -> AX does not support reduce-only orders
// after
let exit = factory.market(id, opposite_side, position_qty_open);
// exact size, no flag Defensive patterns
Strategy: validation
Validate before calling
fn ax_instructions_ok(reduce_only: bool, quote_qty: bool, display_qty: bool) -> bool {
!reduce_only && !quote_qty && !display_qty
}
debug_assert!(ax_instructions_ok(
order.is_reduce_only(),
order.is_quote_quantity(),
order.display_qty().is_some(),
)); Prevention
- Keep a venue-capability table in your strategy layer (reduce_only=false for AX)
- Size exits to the exact open position instead of relying on reduce-only semantics
- Write a pre-submit lint that scans outgoing orders for reduce_only/quote_quantity/display_qty on AX instruments
When it happens
Trigger: factory.market/limit(...).reduce_only(true); strategies with 'close position' helpers that set reduce_only to avoid over-filling; ported code from futures venues (Binance, Bybit) where reduce-only is native.
Common situations: Position-management code written for CEX futures adapters; risk frameworks that always flag exit orders as reduce-only.
Related errors
- Unsupported order type: {:?}, the Architect AX adapter accep
- Unsupported time in force: {:?}, AX supports GTC, IOC, and D
- Architect AX adapter cannot encode quote_quantity; submit a
- Architect AX adapter cannot encode display_qty iceberg instr
- `close_position` cannot be combined with `reduce_only` on Bi
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/a0a6f776f653ec0c.
Report an issue: GitHub.