nautechsystems/nautilus_trader · error
quantity `{}` rounds to 0 ticks at size_precision {}
Error message
quantity `{}` rounds to 0 ticks at size_precision {} What it means
The order quantity converted to integer Lighter base-amount ticks is zero because quantity_to_ticks floors the quantity using the instrument's size_precision. Lighter only accepts discrete tick amounts, so a sub-minimum quantity is rejected up front rather than sending an invalid order.
Source
Thrown at crates/adapters/lighter/src/execution.rs:1604
let order_kind = nautilus_to_lighter_order_type(order.order_type())?;
let tif = nautilus_to_lighter_tif(
order.order_type(),
order.time_in_force(),
order.is_post_only(),
)?;
let now_ms = (self.clock.get_time_ns().as_u64() / 1_000_000) as i64;
let order_expiry = order_expiry_for(
order.order_type(),
&order.time_in_force(),
order.expire_time(),
now_ms,
)?;
let base_amount = quantity_to_ticks(&order.quantity(), instrument.size_precision())?;
// `quantity_to_ticks` floors sub-precision quantities to 0.
anyhow::ensure!(
base_amount > 0,
"quantity `{}` rounds to 0 ticks at size_precision {}",
order.quantity(),
instrument.size_precision(),
);
let price_precision = instrument.price_precision();
let is_buy = matches!(order.order_side(), OrderSide::Buy);
// Lighter requires `price` on market-style orders as the worst
// acceptable cap; derive it from far-side quote or trigger.
let price_ticks = match order.order_type() {
OrderType::Market => {
let quote = self
.core
.cache()
.quote(&instrument_id)
.copied()
.ok_or_else(|| {View on GitHub (pinned to 18893faf8b)
Solutions
- Increase the order quantity to at least one size tick for the instrument.
- Check the instrument's size_precision/size_increment and enforce a minimum-size check before submitting.
- Skip or accumulate dust amounts until they exceed one tick.
- Verify the instrument definition loaded matches the venue's actual precision.
Example fix
// before let qty = Quantity::from_decimal(dec!(0.0004)); let order = order_factory.limit(instrument_id, Side::Buy, qty, price); // after let min_qty = Quantity::new(1.0, instrument.size_precision()); anyhow::ensure!(order.quantity() >= min_qty, "qty below one tick"); let order = order_factory.limit(instrument_id, Side::Buy, order.quantity(), price);
Defensive patterns
Strategy: validation
Validate before calling
// Rust let ticks = qty.as_decimal() / dec!(10).powi(instrument.size_precision() as i64); anyhow::ensure!(ticks >= dec!(1), "quantity below one size tick");
Try / catch
if quantity_to_ticks(&qty, instrument.size_precision()).unwrap_or(0) == 0 {
log::warn!("skipping sub-tick quantity {qty}");
return Ok(());
} Prevention
- Enforce a per-instrument minimum quantity in position-sizing code
- Accumulate dust rather than submitting sub-tick orders
- Verify size_precision in the loaded instrument definition
When it happens
Trigger: submit_order/submit_order_list with a quantity smaller than one tick at the instrument's size_precision (e.g. qty 0.0004 when size_precision allows only 0.001 steps).
Common situations: Position-sizing math producing tiny fractions; Decimal division rounding down; using an instrument definition with coarser precision than the strategy assumes; leftover-dust sells.
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
- Order quantity {quantity} is not exactly representable in {d
- quantity size={} cannot be represented with precision={}
- invalid {name} quantity: {e}
- size decimals {decimals} exceeds maximum {MAX_DECIMALS}
- size precision {precision} exceeds maximum {MAX_DECIMALS}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d0ca1551dd0f02ac.
Report an issue: GitHub.