nautechsystems/nautilus_trader · error

Polymarket collateral-sized limit BUY derives a zero share q

Error message

Polymarket collateral-sized limit BUY derives a zero share quantity

What it means

For a collateral-sized limit BUY, the share quantity is derived as the collateral divided by the price, quantized at LOT_SIZE_SCALE. If that quotient truncates to zero (taker_amount <= 0), the builder throws: it cannot express an order that buys at least one tick-sized share unit with the given collateral.

Source

Thrown at crates/adapters/polymarket/src/execution/order_builder.rs:168

        price: Decimal,
        amount: Decimal,
        expiration: &str,
        neg_risk: bool,
        tick_decimals: u32,
    ) -> anyhow::Result<PolymarketOrder> {
        anyhow::ensure!(
            price > Decimal::ZERO,
            "Polymarket collateral-sized limit BUY price must be positive"
        );

        let (maker_amount, taker_amount) =
            compute_quote_buy_maker_taker_amounts(price, amount, tick_decimals);
        anyhow::ensure!(
            maker_amount > Decimal::ZERO,
            "Polymarket collateral-sized limit BUY amount {} pUSD truncates to zero at {LOT_SIZE_SCALE} decimal places",
            amount.normalize(),
        );
        anyhow::ensure!(
            taker_amount > Decimal::ZERO,
            "Polymarket collateral-sized limit BUY derives a zero share quantity"
        );
        anyhow::ensure!(
            taker_amount * price == maker_amount,
            "Polymarket collateral-sized limit BUY amount {} pUSD cannot preserve limit price {} after venue quantization",
            amount.normalize(),
            price.normalize(),
        );

        self.build_and_sign(
            token_id,
            PolymarketOrderSide::Buy,
            maker_amount,
            taker_amount,
            expiration,
            neg_risk,
        )

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Raise the BUY collateral amount so amount/price is at least one quantized share unit at LOT_SIZE_SCALE.
  2. Verify tick_decimals/LOT_SIZE_SCALE passed to compute_quote_buy_maker_taker_amounts match the venue market's actual tick size.
  3. Skip submitting the order when the derived quantity is below the venue minimum and log it instead of erroring.

Example fix

// before
let amount = Decimal::new(1, 2); // 0.01 pUSD, yields zero shares at price 0.99
builder.build_limit_order_from_collateral(&order, price, amount, tick_decimals)?;
// after
let amount = price * min_share_quantity; // ensure amount/price >= 1 quantized unit
builder.build_limit_order_from_collateral(&order, price, amount, tick_decimals)?;
Defensive patterns

Strategy: validation

Validate before calling

let derived_shares = (amount / price).round_dp(lot_size_scale);
if derived_shares <= Decimal::ZERO { return Err("collateral too small for one share unit at this price".into()); }

Type guard

fn yields_positive_shares(amount: Decimal, price: Decimal, dp: u32) -> bool {
    price > Decimal::ZERO && (amount / price).round_dp(dp) > Decimal::ZERO
}

Prevention

When it happens

Trigger: build_limit_order_from_collateral with an amount/price ratio below one LOT_SIZE_SCALE unit — e.g. 0.05 pUSD at price 0.99 when quantities are quantized to fine decimals, or any amount smaller than price * minimum share increment.

Common situations: Very small capital allocations per order; a price close to 1.0 (high-probability markets) shrinking the derived share quantity; a misconfigured LOT_SIZE_SCALE/tick_decimals making the minimum tradable quantity larger than expected.

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/a2043ed4fd2849a2. Report an issue: GitHub.