nautechsystems/nautilus_trader · error
effective raw scale should fit in QuantityRaw
Error message
effective raw scale should fit in QuantityRaw
What it means
Quantity's `__int__` (Python int() conversion) truncates the raw fixed-point value by dividing by 10^precision. The scale constant 10^precision is first converted into QuantityRaw (an i64/u64), and if the effective scale does not fit in that integer type the conversion fails and this panic is thrown. It guards an internal invariant of the fixed-point representation.
Source
Thrown at crates/model/src/python/types/quantity.rs:398
)))
}
}
fn __neg__(&self) -> Decimal {
self.as_decimal().neg()
}
fn __pos__(&self) -> Self {
*self
}
fn __abs__(&self) -> Self {
*self
}
fn __int__(&self) -> QuantityRaw {
let scale = QuantityRaw::try_from(raw_scale(self.precision))
.expect("effective raw scale should fit in QuantityRaw");
self.raw / scale
}
fn __float__(&self) -> f64 {
self.as_f64()
}
#[pyo3(signature = (ndigits=None))]
fn __round__(&self, ndigits: Option<u32>) -> Decimal {
self.as_decimal()
.round_dp_with_strategy(ndigits.unwrap_or(0), RoundingStrategy::MidpointNearestEven)
}
fn __repr__(&self) -> String {
format!("{self:?}")
}
fn __str__(&self) -> String {View on GitHub (pinned to 18893faf8b)
Solutions
- Lower the precision used for the Quantity so 10^precision fits in QuantityRaw.
- Use as_f64()/float() conversion instead of int() for high-precision quantities.
- If high precision is genuinely needed, ensure the build uses the high-precision (i128) feature so QuantityRaw is wide enough.
Example fix
// before q = Quantity.from_raw(123456789012345678901, precision=25) print(int(q)) # panics // after q = Quantity.from_raw(123456789012345678901, precision=25) print(int(float(q))) # truncate via float, or use a lower precision
Defensive patterns
Strategy: validation
Validate before calling
# Python side
if quantity.precision > 18: # 10**18 is near QuantityRaw (i64) limit
raise ValueError("precision too high for int() conversion")
int(quantity) Type guard
def safe_int(q) -> int | None:
return None if q.precision > 18 else int(q) Prevention
- Keep instrument price precisions within realistic market ranges (<= 12 digits).
- Prefer float(q) or q.as_f64() over int(q) for inspection.
- Enable the high-precision feature if large precisions are required.
When it happens
Trigger: Calling int(quantity) on a Quantity whose currency/price precision implies a raw scale (10^precision) larger than QuantityRaw::MAX, e.g. a very high precision value exposed through the Python bindings.
Common situations: Using extreme precision values (near or above the i64/u64 digit limit ~18-19 digits) when constructing instruments or prices, then converting to int in Python; test fixtures with unrealistic precision settings.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Quantity overflow for ticks={ticks}, decimals={decimals}: {e
- invalid quantity `{value}` at precision {precision}: {e}
- Failed to scale continuous-future adjustment to fixed precis
- Continuous-future adjustment exceeds PriceRaw range
- raw wei value exceeds unsigned 128-bit range
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/686aa4e398e58e25.
Report an issue: GitHub.