nautechsystems/nautilus_trader · warning
Decimal average price must parse as f64
Error message
Decimal average price must parse as f64
What it means
In `get_avg_px_for_quantity` (crates/model/src/orderbook/analysis.rs), the cumulative Decimal average is converted to a string and parsed back to f64, panicking if parsing fails. Because a Decimal produced by dividing cumulative value by size always round-trips through its string representation, this panic signals an internal invariant break (e.g. a Decimal implementation emitting an unparseable representation such as NaN/Infinity text). Users hit it only via such a library-internal defect, not through invalid input.
Source
Thrown at crates/model/src/orderbook/analysis.rs:142
for (book_price, level) in levels {
let size_this_level = level.size_raw().min(qty.raw - cumulative_size_raw);
let size_this_level_decimal = Quantity::raw_as_decimal(size_this_level);
cumulative_size_raw += size_this_level;
cumulative_size += size_this_level_decimal;
cumulative_value += book_price.value.as_decimal() * size_this_level_decimal;
if cumulative_size_raw >= qty.raw {
break;
}
}
if cumulative_size_raw == 0 {
0.0
} else {
(cumulative_value / cumulative_size)
.to_string()
.parse::<f64>()
.expect("Decimal average price must parse as f64")
}
}
/// Calculates the worst (last-touched) price while filling a specified quantity
/// from order book levels.
///
/// For buy-side traversal this is the highest ask touched; for sell-side traversal
/// this is the lowest bid touched. Returns `None` when no quantity can be matched.
#[must_use]
pub fn get_worst_px_for_quantity(
qty: Quantity,
levels: &BTreeMap<BookPrice, BookLevel>,
) -> Option<Price> {
let mut cumulative_size_raw: QuantityRaw = 0;
let mut worst_price: Option<Price> = None;
for (book_price, level) in levels {
let size_this_level = level.size_raw().min(qty.raw - cumulative_size_raw);View on GitHub (pinned to 18893faf8b)
Solutions
- Reduce the magnitude of inputs — cap quantity or operate on a shallower price range to avoid Decimal overflow.
- Check the rust_decimal version for known Display/parse round-trip regressions and pin a known-good version.
- Reproduce with the specific book snapshot and file an issue with the failing level data.
- As a workaround, compute the average in f64 incrementally instead of relying on the Decimal round-trip.
Example fix
// before let avg = book.get_avg_px_for_quantity(OrderSide.BUY, huge_qty); // may panic // after let qty = huge_qty.min(book.total_volume(OrderSide.BUY)); let avg = book.get_avg_px_for_quantity(OrderSide.BUY, qty);
Defensive patterns
Strategy: fallback
Validate before calling
// Rust caller: bound the requested quantity to what the book can fill let max_qty = book.cumulative_qty(side, book.best_price(side)); let qty = requested.min(max_qty);
Type guard
fn is_parseable_f64(s: &str) -> bool {
s.parse::<f64>().is_ok()
} Try / catch
// Cannot catch a Rust panic from Python; avoid triggering inputs. qty = min(qty, book.total_volume(side)) avg_px = book.get_avg_px_for_quantity(side, qty)
Prevention
- Bound requested quantities to available book depth.
- Pin rust_decimal to a version with known-good Display/parse round-trip.
- Report overflowing inputs (huge cumulative sizes) upstream with reproduction data.
When it happens
Trigger: Calling get_avg_px_for_quantity with cumulative value/size that produce a non-finite Decimal (e.g. overflow of the internal Decimal representation from extremely large raw values), yielding a string like "Inf" that fails parse::<f64>... or a Decimal formatting regression.
Common situations: Deep books with enormous aggregated sizes/values on high-precision instruments, or after upgrading dependency versions where the Decimal type's Display output changed format.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Invalid bid price for OrderBook::filtered_view
- Invalid bid quantity for OrderBook::filtered_view
- Invalid ask price for OrderBook::filtered_view
- Invalid ask quantity for OrderBook::filtered_view
- Invalid parity transformed price for OwnOrderBook::combined_
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ff2a69c64059bda0.
Report an issue: GitHub.