Rust edition: this page follows the live DeepWiki structure but treats the current Rust crates as implementation authority. Non-Rust surfaces are identified at their boundary and are not presented as Rust APIs.
Fixed-Point Precision System
Relevant Rust source files
crates/model/src/types/fixed.rscrates/model/src/types/price.rscrates/model/src/types/quantity.rscrates/model/src/types/money.rs
Purpose and Scope
This document explains the fixed-point arithmetic system used throughout NautilusTrader for all financial calculations involving prices, quantities, and monetary amounts. The system replaces floating-point arithmetic with deterministic, precision-preserving integer arithmetic to ensure accurate financial calculations and avoid rounding errors inherent in IEEE 754 floating-point operations.
The Rust fixed-point system provides compile-time 64-bit or high-precision 128-bit integer backing for the core financial value types.
Fixed-Point Representation
Conceptual Model
Fixed-point arithmetic represents decimal numbers as scaled integers. Instead of storing 123.45 as a floating-point number, the system stores it as a scaled integer (e.g., 1234500000000000000 in high-precision mode) with a precision indicator. This approach provides exact decimal representation without floating-point approximation errors.
Diagram — Fixed-Point Value Representation and Scaling
| Stage | High-precision example |
|---|---|
| Input | Decimal value 123.45 with declared precision 2 |
| Scale | FIXED_SCALAR = 10^16 |
| Stored raw value | 1_234_500_000_000_000_000i128 |
| Recovery | raw / 10^16 = 123.45 |
Precision Modes
NautilusTrader supports two precision modes, determined at compile time via the high-precision feature flag. This choice impacts the underlying data types and maximum representable values.
| Mode | FIXED_PRECISION |
Raw Type Width | FIXED_SCALAR |
PRECISION_BYTES |
|---|---|---|---|---|
| High-Precision | 16 decimals | 128-bit (i128/u128) |
10^16 | 16 bytes |
| Standard | 9 decimals | 64-bit (i64/u64) |
10^9 | 8 bytes |
Core Value Types
Type Hierarchy and Code Entities
Diagram — Fixed-Point Type Hierarchy and FFI Integration
| Rust value | Raw representation | Additional invariant |
|---|---|---|
Price |
signed PriceRaw plus precision: u8 |
Negative values are permitted within the documented range. |
Quantity |
unsigned QuantityRaw plus precision: u8 |
Values cannot be negative. |
Money |
signed raw value plus Currency |
Arithmetic requires compatible currencies. |
Price Type
Represents market prices. Unlike quantities, prices can be negative (e.g., for spreads or certain basis trades).
- Range (High-Precision):
PRICE_MAX= 17,014,118,346,046.0 - Precision: Up to
FIXED_PRECISION(16 or 9). - Arithmetic: Supports addition, subtraction, and negation. Multiplication/Division results in
f64orDecimal.
Quantity Type
Represents non-negative amounts (shares, contracts, lots).
- Range (High-Precision):
QUANTITY_MAX= 34,028,236,692,093.0 - Constraint: Values must be within [0,
QUANTITY_MAX]. - Arithmetic: Supports checked model operations; invalid unsigned results are rejected according to the Rust type's documented invariant.
Money Type
Represents monetary amounts denominated in a specific Currency.
- Currency Constraint: Addition/Subtraction requires matching currencies.
- Precision: Inherited from the
Currencyobject's precision. - Account Balance: The
AccountBalancetype usesMoneyfortotal,locked, andfreefields, enforcing the invarianttotal = locked + free.
Construction and Safety
Construction API
Diagram — Construction Methods and Data Flow
Construction is a boundary sequence: parse the external representation, apply the selected fixed scale, validate precision and range in new_checked, then construct the typed Price, Quantity, or Money value. Raw constructors are reserved for already-scaled trusted values and must use the same compile-time precision mode.
Avoiding Floating-Point Errors
To maintain precision and avoid the inherent unreliability of IEEE 754 doubles beyond 16 decimal places:
- Prefer specialized constructors: For values with precision higher than 16 (e.g., DeFi wei values), the system uses
from_weior integer-based raw constructors. - Hard Limits: The system enforces
MAX_FLOAT_PRECISION = 16for any float-based input because floats are only reliable up to ~16 decimal digits. - Correctness Checking: All core types implement
new_checkedto validate ranges and precision at instantiation. - Legacy Correction: When decoding from catalogs, correction functions (e.g.,
correct_raw_i128) round raw values to the nearest valid multiple to fix floating-point errors introduced by legacy V2 wranglers.
Arithmetic Behavior
| Operation | Result | Notes |
|---|---|---|
Type + Type |
Type |
Precision is the maximum of both operands. |
Type - Type |
Type |
Quantity panics if result < 0. |
Type * f64 |
f64 |
Results in standard floating point. |
Type / f64 |
f64 |
Results in standard floating point. |
Type * Decimal |
Decimal |
High-precision decimal result. |