nautechsystems/nautilus_trader · error

Signed limit order share quantity {signed_base_qty} cannot b

Error message

Signed limit order share quantity {signed_base_qty} cannot be represented exactly at instrument size precision {}

What it means

Raised via anyhow::ensure! in `prepare_limit_order_submission` when the signed share quantity decoded from the venue amounts is not exactly representable at the instrument's size_precision — i.e. `Quantity::from_decimal_dp` produced a value that differs from the raw signed decimal. The adapter refuses to submit an order whose reported fill quantity could differ from what was signed, preventing silent rounding drift between the venue amounts and Nautilus quantity tracking.

Source

Thrown at crates/adapters/polymarket/src/execution/submitter.rs:480

                request.price.as_decimal(),
                request.quantity.as_decimal(),
                order_type,
                &expiration,
                request.neg_risk,
                request.tick_decimals,
            )
        }
        .map_err(|e| anyhow::anyhow!("{e}"))?;

        let signed_base_qty = signed_base_quantity(order.maker_amount, order.taker_amount, side);
        let expected_base_qty =
            Quantity::from_decimal_dp(signed_base_qty, request.size_precision).map_err(|e| {
                anyhow::anyhow!(
                    "Signed limit order share quantity {signed_base_qty} is invalid at instrument size precision {}: {e}",
                    request.size_precision,
                )
            })?;
        anyhow::ensure!(
            expected_base_qty.as_decimal() == signed_base_qty,
            "Signed limit order share quantity {signed_base_qty} cannot be represented exactly at instrument size precision {}",
            request.size_precision,
        );

        let expected_venue_order_id = self
            .order_builder
            .expected_order_id(&order, request.neg_risk)?;

        Ok(SignedLimitOrderSubmission {
            order,
            order_type,
            post_only: request.post_only,
            expected_venue_order_id,
            expected_base_qty,
        })
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Align size_precision in the instrument definition with the decimals the builder rounds shares to
  2. Round the requested order size to size_precision before submission
  3. Re-fetch current market metadata if the venue changed its tick/size granularity

Example fix

// before
let qty = Quantity::from_decimal_dp(dec!(0.123), 2); // 0.123 != 0.12 -> error
// after: round the order size first
let qty = Quantity::from_decimal_dp(dec!(0.12), 2);
Defensive patterns

Strategy: validation

Validate before calling

if Quantity::from_decimal_dp(signed_qty, size_precision).map(|q| q.as_decimal()) != Ok(signed_qty) {
    return Err(anyhow!("qty {signed_qty} not exact at precision {size_precision}"));
}

Try / catch

if let Err(e) = prepare_limit_order_submission(&req).await {
    if e.to_string().contains("cannot be represented exactly") {
        // round the requested size to size_precision and retry once
    }
}

Prevention

When it happens

Trigger: Builder rounding leaves the signed base quantity with more decimal places than size_precision (e.g. signed qty 0.123 shares on an instrument with size_precision 2); size precision misconfigured relative to the builder's rounding step.

Common situations: Trading instruments whose size_precision in config doesn't match the venue's real tick/size granularity; custom sizing engines producing odd share amounts; tick-size changes on Polymarket markets altering rounding behavior.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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