{"record":{"id":"2d9713079bd6301a","repo":"nautechsystems/nautilus_trader","slug":"failed-to-convert-price-to-u64","errorCode":null,"errorMessage":"Failed to convert price to u64","messagePattern":"Failed to convert price to u64","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/grpc/order.rs","lineNumber":135,"sourceCode":"            - self.quantum_conversion_exponent\n            - QUOTE_QUANTUMS_ATOMIC_RESOLUTION);\n\n        // When exponent is negative, we multiply by 10^|exponent|\n        // When exponent is positive, we divide by 10^exponent (multiply by 10^-exponent)\n        let factor = if exponent < 0 {\n            Decimal::from(10_i64.pow(exponent.unsigned_abs()))\n        } else {\n            Decimal::new(1, exponent.unsigned_abs())\n        };\n\n        let raw_subticks = price * factor;\n        let subticks_per_tick = Decimal::from(self.subticks_per_tick);\n        let quantums = Self::quantize(&raw_subticks, &subticks_per_tick);\n        let result = quantums.max(subticks_per_tick);\n\n        result\n            .to_u64()\n            .ok_or_else(|| anyhow::anyhow!(\"Failed to convert price to u64\"))\n    }\n\n    /// Convert decimal into quantums.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if conversion fails.\n    pub fn quantize_quantity(&self, quantity: Decimal) -> Result<u64, anyhow::Error> {\n        // When atomic_resolution is negative, we multiply by 10^|atomic_resolution|\n        // When atomic_resolution is positive, we divide by 10^atomic_resolution\n        let factor = if self.atomic_resolution < 0 {\n            Decimal::from(10_i64.pow(self.atomic_resolution.unsigned_abs()))\n        } else {\n            Decimal::new(1, self.atomic_resolution.unsigned_abs())\n        };\n\n        let raw_quantums = quantity * factor;\n        let step_base_quantums = Decimal::from(self.step_base_quantums);","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/grpc/order.rs#L117-L153","documentation":"quantize_price rounds a dYdX price into subticks and must return it as u64 for the proto Order. The error is thrown when the quantized Decimal cannot fit into u64 (negative, fractional residue, or exceeding u64::MAX), meaning the price or market subticks_per_tick parameters are nonsensical.","triggerScenarios":"Calling market_order_subticks (directly or via build for market/stop-market orders) with an oracle price so large that quantization exceeds u64::MAX, a negative raw price, or a market with a subticks_per_tick value that makes quantums.max(subticks_per_tick) unrepresentable.","commonSituations":"Corrupt or absurd oracle price data; a misconfigured market where subticks_per_tick is huge or zero/negative; passing a price already denominated in the wrong units (e.g. raw not human price); a Decimal that lost its scale via a bad conversion upstream.","solutions":["Validate the raw price is positive and within a sane range before calling market_order_subticks","Verify market_params.subticks_per_tick matches the dYdX market's actual configuration (fetch from markets endpoint)","Check where the oracle price comes from — a wrong unit multiplier can inflate the price enormously","If the price is legitimately huge, cap/clamp it or reject the order upstream instead of relying on this conversion"],"exampleFix":"// before\nlet subticks = builder.build()?.quantize_price(raw_price)?;\n// after\nanyhow::ensure!(raw_price > Decimal::ZERO, \"price must be positive\");\nanyhow::ensure!(raw_price < Decimal::from(1_000_000_000u64), \"price out of sane range\");\nlet subticks = builder.build()?.quantize_price(raw_price)?;","handlingStrategy":"validation","validationCode":"anyhow::ensure!(raw_price.is_sign_positive(), \"price must be positive\");\nanyhow::ensure!(raw_price <= Decimal::from(u64::MAX), \"price exceeds u64 range\");","typeGuard":"fn is_representable_u64(d: &Decimal) -> bool {\n    d.is_sign_positive() && d <= Decimal::from(u64::MAX)\n}","tryCatchPattern":null,"preventionTips":["Validate price sign and magnitude before building orders","Verify subticks_per_tick per market against the dYdV markets endpoint","Keep price units consistent (human price, not raw) end to end"],"tags":["rust","decimal-conversion","overflow","dydx"],"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"}