nautechsystems/nautilus_trader · error

derived market price `{widened}` rounds to 0 ticks at precis

Error message

derived market price `{widened}` rounds to 0 ticks at precision {price_precision} (slippage_bps={slippage_bps}); reduce slippage or increase price precision

What it means

For MARKET/STOP_MARKET/MARKET_IF_TOUCHED orders the adapter derives a worst-acceptable price from a base price widened by slippage_bps, rounded at the instrument's price_precision. Lighter rejects price=0 (venue error 21702), so if the derived price rounds down to 0 ticks this error is raised to prevent the submit.

Source

Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:2166

    let widened = if is_buy {
        base * (Decimal::ONE + slippage)
    } else {
        base * (Decimal::ONE - slippage)
    };

    let scale = Decimal::from(10_i64.pow(u32::from(price_precision)));
    let scaled = widened * scale;
    let rounded = if is_buy {
        scaled.ceil()
    } else {
        scaled.floor()
    };
    let value = decimal_trunc_to_i64(rounded).with_context(|| {
        format!("derived market price `{widened}` overflows i64 at precision {price_precision}",)
    })?;

    // Lighter rejects `price = 0` as `21702 invalid price`.
    anyhow::ensure!(
        value > 0,
        "derived market price `{widened}` rounds to 0 ticks at precision {price_precision} (slippage_bps={slippage_bps}); reduce slippage or increase price precision",
    );
    u32::try_from(value).with_context(|| {
        format!("derived market price `{widened}` overflows u32 at precision {price_precision}",)
    })
}

#[cfg(test)]
mod tests {
    use std::str::FromStr;

    use nautilus_core::UUID4;
    use nautilus_model::{
        enums::{AccountType, LiquiditySide, OrderSide, OrderStatus, OrderType, PositionSide},
        identifiers::{AccountId, StrategyId, TradeId},
        orders::Order,
        reports::FillReport,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Increase the instrument's price_precision configuration so the price has at least 1 tick
  2. Reduce slippage_bps for sell-side widening
  3. Verify the base price is correct; a near-zero price may indicate a bad data feed

Example fix

// before
// price_precision = 2, price = 0.0000004 -> derived price rounds to 0
// after: configure instrument with higher price precision
let price_precision = 8; // 0.0000004 -> 0 ticks at 2dp, valid at 8dp
Defensive patterns

Strategy: validation

Validate before calling

let widened = derive_worst_price(base, slippage_bps, side);
let ticks = (widened * Decimal::from(10u32.pow(price_precision))).trunc();
anyhow::ensure!(ticks > Decimal::ZERO, "derived price rounds to 0 ticks");

Try / catch

match derive_market_price(...) {
    Err(e) if e.to_string().contains("rounds to 0 ticks") => {
        // raise price_precision or reject the market order
    }
    r => r?,
}

Prevention

When it happens

Trigger: A very small base price (low-priced asset) with a price_precision that makes one tick larger than the widened price — e.g. price 0.0000001 with price_precision 2 and any positive slippage widening direction rounding to 0.

Common situations: Trading micro-cap tokens whose price is below one tick at the configured precision; misconfigured instrument precision; excessive slippage_bps applied to sells pushing price toward zero then rounding to 0.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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