nautechsystems/nautilus_trader · error · anyhow::Error

Order rejected: {reason}

Error message

Order rejected: {reason}

What it means

After placing an order, submit_order checks the returned BitMEX order's ord_status; if it is Rejected, the call bails with the venue's ord_rej_reason (or 'No reason provided'). This surfaces a BitMEX-side rejection synchronously to the caller.

Source

Thrown at crates/adapters/bitmex/src/http/client.rs:1777

        if !exec_inst.is_empty() {
            params.exec_inst(exec_inst);
        }

        if let Some(contingency_type) = contingency_type {
            let bitmex_contingency = BitmexContingencyType::try_from(contingency_type)?;
            params.contingency_type(bitmex_contingency);
        }

        let params = params.build().map_err(|e| anyhow::anyhow!(e))?;

        let order: BitmexOrder = self.inner.place_order_response(params).await?;

        if order.ord_status == Some(BitmexOrderStatus::Rejected) {
            let reason = order
                .ord_rej_reason
                .map_or_else(|| "No reason provided".to_string(), |r| r.to_string());
            anyhow::bail!("Order rejected: {reason}");
        }

        // Cache order type for future lookups (e.g., cancel responses missing ord_type)
        self.order_type_cache.insert(client_order_id, order_type);

        let instrument = self.instrument_from_cache(instrument_id.symbol.inner())?;
        let ts_init = self.generate_ts_init();

        parse_order_status_report(&order, &instrument, &self.order_type_cache, ts_init)
    }

    /// Cancel an order.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - Credentials are missing.
    /// - The request fails.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the reason embedded in the message and fix the offending order parameters
  2. Validate price/quantity against the instrument's size/price increments before submitting
  3. Confirm API key permissions and that the contract is active
  4. Check account balance/margin for the symbol

Example fix

// before
client.submit_order(... quantity: Quantity::from(0.00001) ...)
// after
client.submit_order(... quantity: instrument.min_quantity() ...)
Defensive patterns

Strategy: try-catch

Validate before calling

if let Some(instrument) = instrument_opt {
    if qty < instrument.min_quantity() || price < instrument.min_price() {
        return Err(anyhow::anyhow!("order violates instrument limits"));
    }
}

Try / catch

match client.submit_order(params).await {
    Ok(o) => o,
    Err(e) if e.to_string().starts_with("Order rejected:") => {
        let reason = e.to_string();
        log::error!("BitMEX rejected order: {reason}");
        // generate an OrderRejected event / halt strategy
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: place_order_response returns an order with ord_status=Some(Rejected) — e.g. invalid price/quantity, insufficient balance, market closed, testnet/live mismatch, or a rejected pegged/trailing parameter combination.

Common situations: Submitting below-minimum notional quantities; using stale instrument specs after BitMEX contract updates; trading while the API key lacks order permission; price outside the venue's limits.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/e2913a8a171483f1. Report an issue: GitHub.