{"record":{"id":"b409a7b2cfb08b7b","repo":"nautechsystems/nautilus_trader","slug":"quantity-size-cannot-be-represented-with-precis","errorCode":null,"errorMessage":"quantity size={} cannot be represented with precision={}","messagePattern":"quantity size=(.+?) cannot be represented with precision=(.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/interactive_brokers/src/data/parse.rs","lineNumber":35,"sourceCode":"\nuse ibapi::contracts::{OptionComputation, tick_types::TickType};\nuse nautilus_core::UnixNanos;\nuse nautilus_model::{\n    data::{\n        Bar, BarType, IndexPriceUpdate, QuoteTick, TradeTick, greeks::OptionGreekValues,\n        option_chain::OptionGreeks,\n    },\n    enums::{AggressorSide, BookAction, GreeksConvention},\n    identifiers::{InstrumentId, TradeId},\n    types::{Price, Quantity},\n};\n\nfn checked_quantity(size: f64, precision: u8) -> anyhow::Result<Quantity> {\n    let quantity = Quantity::new_checked(size, precision)\n        .map_err(|e| anyhow::anyhow!(\"invalid quantity size={size}: {e}\"))?;\n    let tolerance = 10_f64.powi(-i32::from(precision)) * 1e-9;\n    if (quantity.as_f64() - size).abs() > tolerance {\n        anyhow::bail!(\n            \"quantity size={} cannot be represented with precision={}\",\n            size,\n            precision\n        );\n    }\n    Ok(quantity)\n}\n\n/// Parse IB tick price and size data into a QuoteTick.\n///\n/// This builds a quote from individual tick updates. You typically need to accumulate\n/// bid/ask prices and sizes from multiple tick updates before creating a QuoteTick.\n///\n/// # Errors\n///\n/// Returns an error if price or size conversion fails.\n#[allow(clippy::too_many_arguments)]\npub fn parse_quote_tick(","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/interactive_brokers/src/data/parse.rs#L17-L53","documentation":"checked_quantity validates that an f64 size from IB can be exactly represented as a domain Quantity at the given precision. Quantity::new_checked rounds to precision; if the rounded value differs from the original size beyond a tiny tolerance, this error is bailed to avoid silently distorting order/tick quantities.","triggerScenarios":"parse_quote_tick or parse_trade_tick passes a size like 0.1234567 to checked_quantity with a small precision (e.g. 2 or 3), so rounding changes the value more than the tolerance; also triggered by NaN/inf-ish or absurdly large f64 sizes.","commonSituations":"Crypto/forex instruments with sub-tick sizes exceeding the configured precision; precision derived from the instrument definition not matching IB-reported sizes; wrong precision passed by the caller.","solutions":["Increase the precision argument to match the instrument's allowed quantity precision","Verify the instrument definition in the cache has correct quantity precision","Sanitize/round the size at the source (IB) before parsing","Reject or rescale the tick if the size is genuinely finer-grained than the instrument supports"],"exampleFix":"// before\nlet qty = checked_quantity(size, 2)?;\n// after\nlet qty = checked_quantity(size, instrument.precision() /* e.g. 6 */)?;","handlingStrategy":"validation","validationCode":"fn is_representable(size: f64, precision: u8) -> bool {\n    let rounded = round_to_precision(size, precision);\n    (rounded - size).abs() <= 10f64.powi(-i32::from(precision)) * 1e-9\n}\n// guard: if !is_representable(size, precision) { return Err(...); }","typeGuard":"fn valid_quantity(size: f64, precision: u8) -> Option<f64> {\n    if !size.is_finite() { return None; }\n    let tol = 10f64.powi(-i32::from(precision)) * 1e-9;\n    ((size.round() - size).abs() <= tol).then_some(size)\n}","tryCatchPattern":"match checked_quantity(size, precision) {\n    Ok(q) => q,\n    Err(e) => { warn!(\"skipping tick with unusable size: {e}\"); return Ok(()); }\n}","preventionTips":["Derive precision from the instrument definition, not hardcoded values","Match instrument quantity precision to the venue's tick size","Sanitize IB-reported sizes (reject NaN/inf) before parsing","Unit-test parsing with sizes at the edge of the configured precision"],"tags":["quantity","precision","parsing","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}