{"record":{"id":"99b5c8951a61e339","repo":"nautechsystems/nautilus_trader","slug":"order-quantity-must-be-at-least-1-contract","errorCode":null,"errorMessage":"Order quantity must be at least 1 contract","messagePattern":"Order quantity must be at least 1 contract","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/architect_ax/src/common/parse.rs","lineNumber":207,"sourceCode":"/// - The quantity is zero.\npub fn quantity_to_contracts(quantity: Quantity) -> anyhow::Result<u64> {\n    let raw = quantity.raw;\n    let scale = 10_u64.pow(FIXED_PRECISION as u32) as QuantityRaw;\n\n    // AX requires whole contract quantities\n    if !raw.is_multiple_of(scale) {\n        anyhow::bail!(\n            \"AX requires whole contract quantities, was {}\",\n            quantity.as_f64()\n        );\n    }\n\n    // QuantityRaw is u128 under the `high-precision` feature and u64 otherwise,\n    // so the narrowing cast is conditional on the active feature set.\n    #[allow(clippy::unnecessary_cast)]\n    let contracts = (raw / scale) as u64;\n    if contracts == 0 {\n        anyhow::bail!(\"Order quantity must be at least 1 contract\");\n    }\n    Ok(contracts)\n}\n\n/// Converts a [`ClientOrderId`] to a deterministic AX `cid` in the non-negative `int64` range.\n///\n/// Inbound WebSocket `cid` values remain `u64` because venue messages can exceed `int64`.\n#[must_use]\npub fn client_order_id_to_cid(client_order_id: &ClientOrderId) -> u64 {\n    CID_HASHER.hash_one(client_order_id.inner()) & i64::MAX as u64\n}\n\n/// Creates a [`ClientOrderId`] from a cid value.\n///\n/// Used when we receive an order with a cid but cannot resolve it to the\n/// original ClientOrderId (e.g., after restart when in-memory mapping is lost).\n#[must_use]\npub fn cid_to_client_order_id(cid: u64) -> ClientOrderId {","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/architect_ax/src/common/parse.rs#L189-L225","documentation":"The second stage of quantity_to_contracts: a size that is a valid whole multiple (so it passes the fractional check) but rounds down to zero contracts — which in practice means Quantity 0. ArchitectX minimum order size is 1 contract, and the adapter refuses to emit a zero-size order rather than letting the venue reject it opaquely.","triggerScenarios":"Submitting an order with quantity 0 (or 0.0) through the architect_ax adapter: raw == 0 is a multiple of the scale, divides to 0 contracts, and trips this guard.","commonSituations":"Risk-based sizing that floors an already-tiny allocation to 0 and still submits; signal handlers firing with a default/zero size; test orders created with placeholder zero quantities.","solutions":["Skip order submission when the computed size is zero: if qty == 0: return / log and continue","Clamp sizing to at least 1 contract when the signal should trade: qty = max(qty, instrument.lot_size or 1)","Assert qty > 0 in strategy code before order creation as a fast local guard"],"exampleFix":"# before\nqty = int(risk_budget // price)  # floors to 0 for small budgets\norder = self.factory.market(instrument_id, quantity=Quantity.from_int(qty))\n# -> Order quantity must be at least 1 contract\n\n# after\nqty = int(risk_budget // price)\nif qty < 1:\n    self.log.info('Skipping: size rounds to 0 contracts')\n    return","handlingStrategy":"validation","validationCode":"qty = self._compute_position_size(...)\nif qty < 1:\n    self.log.info('Skipping: allocated size rounds to zero contracts')\n    return\norder = self.factory.market(instrument_id, quantity=Quantity.from_int(int(qty)))","typeGuard":"def is_orderable_contracts(qty: float) -> bool:\n    return qty >= 1","tryCatchPattern":"# Validate before submit; a zero-quantity order surfaces as a rejected order event,\n# so guard at sizing time instead of relying on venue/adapter rejection.","preventionTips":["Always branch on qty < 1 after flooring risk-based sizes","Add an assert quantity > 0 in strategy order helpers during development","Treat zero-sized signals as 'no trade', never as a submit-0 order"],"tags":["rust","architect","adapter","quantity","order-validation","zero-quantity"],"backgroundTag":"invalid-order-quantity","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}