{"record":{"id":"20cb37e14d9b14fc","repo":"nautechsystems/nautilus_trader","slug":"failed-to-convert-quote-to-base-quantity-for-ord-i","errorCode":null,"errorMessage":"Failed to convert quote-to-base quantity for ord_id={}, sz={sz}, price={price}, quantity_dec={quantity_dec}: {e}","messagePattern":"Failed to convert quote-to-base quantity for ord_id=(.+?), sz=(.+?), price=(.+?), quantity_dec=(.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/common/parse.rs","lineNumber":770,"sourceCode":"        // Convert quote quantity to base: quantity_base = sz_quote / price\n        let quantity_base = if let (Some(sz), Some(price)) = (sz_quote_dec, conversion_price_dec) {\n            if price.is_zero() {\n                log::warn!(\n                    \"Cannot convert quote quantity with zero price: ord_id={}, sz={}, using sz as-is\",\n                    order.ord_id.as_str(),\n                    order.sz\n                );\n                Quantity::from_str(&order.sz).map_err(|e| {\n                    anyhow::anyhow!(\n                        \"Failed to parse fallback quantity for ord_id={}, sz='{}': {e}\",\n                        order.ord_id.as_str(),\n                        order.sz\n                    )\n                })?\n            } else {\n                let quantity_dec = sz / price;\n                Quantity::from_decimal_dp(quantity_dec, size_precision).map_err(|e| {\n                    anyhow::anyhow!(\n                        \"Failed to convert quote-to-base quantity for ord_id={}, sz={sz}, price={price}, quantity_dec={quantity_dec}: {e}\",\n                        order.ord_id.as_str()\n                    )\n                })?\n            }\n        } else {\n            log::warn!(\n                \"Cannot convert quote quantity to base without price, using raw sz: \\\n                 ord_id={}, sz={}, px='{}', avg_px='{}'\",\n                order.ord_id.as_str(),\n                order.sz,\n                order.px,\n                order.avg_px\n            );\n            Quantity::from_str(&order.sz).map_err(|e| {\n                anyhow::anyhow!(\n                    \"Failed to parse fallback quantity for ord_id={}, sz='{}': {e}\",\n                    order.ord_id.as_str(),","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/common/parse.rs#L752-L788","documentation":"For quote-currency orders with a valid non-zero price, parse_order_status_report converts sz (quote ccy) to base quantity as sz / price and rounds it to the instrument's size precision via Quantity::from_decimal_dp. This error is raised when that conversion or rounding fails (e.g. result is negative, zero-precision violation, or exceeds Quantity bounds).","triggerScenarios":"A quote-quantity order where sz/price yields a value that cannot be represented as a Quantity at the given size_precision: negative sz, price so small that the quotient overflows, or more decimals than size_precision allows without valid rounding.","commonSituations":"Wrong instrument definition (size_precision too small for OKX lot sizes); tiny dust orders producing sub-precision quantities; corrupted price or sz values from OKX; using the wrong instrument_id mapping so precision mismatches.","solutions":["Verify the instrument definition's size_precision matches the OKX instrument's lot size (lotSz)","Log sz, price and the computed quantity_dec to check which bound was violated","Reject/handle dust orders whose converted base quantity is below min size precision","Upgrade or patch the adapter if OKX instruments require finer precision than configured"],"exampleFix":"// before\nlet report = parse_order_status_report(&order, &instrument, ...)?;\n// after\nassert_eq!(instrument.size_precision as u32, okx_lot_sz_dec.fract_digits(), \"size_precision must match OKX lotSz\");\nlet report = parse_order_status_report(&order, &instrument, ...)?;","handlingStrategy":"validation","validationCode":"let sz = Decimal::from_str(&order.sz)?;\nlet price = Decimal::from_str(&order.px)?;\nlet qty = sz / price;\nif qty < Decimal::ZERO || qty.mantissa().unsigned_abs() > u64::MAX as u128 { /* reject before calling */ }","typeGuard":"fn converts_to_quantity(sz: Decimal, price: Decimal, precision: u8) -> bool {\n    price > Decimal::ZERO && Quantity::from_decimal_dp(sz / price, precision).is_ok()\n}","tryCatchPattern":"match parse_order_status_report(&order, &instrument, ts_init) {\n    Ok(r) => handle(r),\n    Err(e) if e.to_string().contains(\"quote-to-base quantity\") => log::warn!(\"conversion failed for {}: {e}\", order.ord_id),\n    Err(e) => return Err(e),\n}","preventionTips":["Match size_precision to OKX lotSz for every instrument","Reject dust orders whose converted quantity is below precision","Validate price > 0 and sz >= 0 before conversion","Re-generate instrument definitions when OKX updates instrument specs"],"tags":["okx","rust","parsing","quantity","precision"],"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-14T00:17:10.932Z"}