nautechsystems/nautilus_trader · error · anyhow::Error

invalid quantity size={size}: {e}

Error message

invalid quantity size={size}: {e}

What it means

`checked_quantity` converts a raw `f64` size into a domain `Quantity` with the given precision. The error is thrown when `Quantity::new_checked` rejects the value (e.g. negative, NaN, or exceeding valid range) — the raw size and underlying error are included in the message.

Source

Thrown at crates/adapters/interactive_brokers/src/data/parse.rs:32

// -------------------------------------------------------------------------------------------------

//! Parsing utilities for converting Interactive Brokers data to Nautilus types.

use ibapi::contracts::{OptionComputation, tick_types::TickType};
use nautilus_core::UnixNanos;
use nautilus_model::{
    data::{
        Bar, BarType, IndexPriceUpdate, QuoteTick, TradeTick, greeks::OptionGreekValues,
        option_chain::OptionGreeks,
    },
    enums::{AggressorSide, BookAction, GreeksConvention},
    identifiers::{InstrumentId, TradeId},
    types::{Price, Quantity},
};

fn checked_quantity(size: f64, precision: u8) -> anyhow::Result<Quantity> {
    let quantity = Quantity::new_checked(size, precision)
        .map_err(|e| anyhow::anyhow!("invalid quantity size={size}: {e}"))?;
    let tolerance = 10_f64.powi(-i32::from(precision)) * 1e-9;
    if (quantity.as_f64() - size).abs() > tolerance {
        anyhow::bail!(
            "quantity size={} cannot be represented with precision={}",
            size,
            precision
        );
    }
    Ok(quantity)
}

/// Parse IB tick price and size data into a QuoteTick.
///
/// This builds a quote from individual tick updates. You typically need to accumulate
/// bid/ask prices and sizes from multiple tick updates before creating a QuoteTick.
///
/// # Errors
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the raw IB message and log `size` when this fires; identify whether the exchange sent NaN or an invalid sentinel.
  2. Skip/ignore ticks with non-positive or NaN sizes before parsing instead of propagating the error.
  3. Verify the instrument definition's size precision matches the IB contract's min tick/size; adjust instrument configuration if too restrictive.
  4. Handle IB pre-open/auction states in client code where sizes may be placeholders.

Example fix

// before
let quantity = checked_quantity(size, precision)?;
// after
if !size.is_finite() || size <= 0.0 {
    return Ok(None); // skip invalid sizes from IB
}
let quantity = checked_quantity(size, precision)?;
Defensive patterns

Strategy: validation

Validate before calling

fn valid_size(size: f64) -> bool {
    size.is_finite() && size > 0.0
}

Type guard

fn is_representable(size: f64, precision: u8) -> bool {
    size.is_finite() && size >= 0.0 && (size * 10f64.powi(i32::from(precision))).fract() == 0.0
}

Try / catch

match checked_quantity(size, precision) {
    Ok(q) => q,
    Err(e) if e.to_string().starts_with("invalid quantity") => {
        log::debug!("dropping tick with invalid size {size}");
        return Ok(None);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `parse_quote_tick` or `parse_trade_tick` receiving a size field from IB that is NaN, negative, zero-negatives (-0.0 edge), or otherwise rejected by `Quantity::new_checked` for the configured precision.

Common situations: IB streaming a bid/ask size of 0 sentinel values or NaN during auction/pre-open states; instrument configured with a precision that cannot represent the reported size; malformed historical data rows.

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