nautechsystems/nautilus_trader · error · anyhow::Error
Failed to create avg_px price: {e}
Error message
Failed to create avg_px price: {e} What it means
For combo (legged) fills, the adapter computes a partial average price Decimal and converts it to a Price via Price::from_decimal_dp. This error wraps any failure of that conversion — typically because the partial average decimal exceeds the instrument's price precision or cannot be represented at that precision.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/core_updates.rs:956
let mut progress = order_fill_progress.lock();
let (previous_filled, previous_notional) = progress
.get(&client_order_id)
.copied()
.unwrap_or((Decimal::ZERO, Decimal::ZERO));
let total_notional = filled_decimal * avg_decimal;
progress.insert(client_order_id, (filled_decimal, total_notional));
drop(progress);
let fill_delta = filled_decimal - previous_filled;
if fill_delta <= Decimal::ZERO || !is_spread_order {
return Ok(());
}
let notional_delta = total_notional - previous_notional;
let partial_avg_decimal = notional_delta / fill_delta;
let partial_avg_px =
Price::from_decimal_dp(partial_avg_decimal, instrument.price_precision())
.map_err(|e| anyhow::anyhow!("Failed to create avg_px price: {e}"))?;
pending_combo_fill_avgs
.lock()
.entry(client_order_id)
.or_default()
.push_back((fill_delta, partial_avg_px));
Ok(())
}
pub(super) fn flush_pending_combo_fills(
client_order_id: ClientOrderId,
pending_combo_fills: &Arc<Mutex<AHashMap<ClientOrderId, VecDeque<PendingComboFill>>>>,
pending_combo_fill_avgs: &Arc<Mutex<AHashMap<ClientOrderId, VecDeque<(Decimal, Price)>>>>,
order_fill_progress: &Arc<Mutex<AHashMap<ClientOrderId, (Decimal, Decimal)>>>,
exec_sender: &tokio::sync::mpsc::UnboundedSender<ExecutionEvent>,
) -> anyhow::Result<()> {
let mut combo_fills = pending_combo_fills.lock();View on GitHub (pinned to 18893faf8b)
Solutions
- Confirm the instrument definition's price_precision matches the actual IB contract (check the instrument provider data).
- Round/quantize partial_avg_decimal to the instrument precision before building the Price.
- Guard against fill_delta == 0 or degenerate notional deltas before the division.
Example fix
// before
let partial_avg_px =
Price::from_decimal_dp(partial_avg_decimal, instrument.price_precision())
.map_err(|e| anyhow::anyhow!("Failed to create avg_px price: {e}"))?;
// after
let rounded = partial_avg_decimal
.round_dp(u32::from(instrument.price_precision()));
let partial_avg_px = Price::from_decimal_dp(rounded, instrument.price_precision())
.map_err(|e| anyhow::anyhow!("Failed to create avg_px price: {e}"))?; Defensive patterns
Strategy: validation
Validate before calling
// Rust: check precision and divisor before building the Price
if fill_delta <= Decimal::ZERO {
tracing::warn!("Zero fill delta; skipping partial avg price");
return Ok(());
}
let dp = u32::from(instrument.price_precision());
let rounded = partial_avg_decimal.round_dp(dp); Type guard
fn fits_precision(d: Decimal, precision: u8) -> bool {
(d.round_dp(u32::from(precision)) - d).abs() < Decimal::new(1, i64::from(precision))
} Try / catch
let partial_avg_px = match Price::from_decimal_dp(partial_avg_decimal, instrument.price_precision()) {
Ok(px) => px,
Err(e) => {
tracing::error!("Partial avg price out of range: {e}");
return Ok(());
}
}; Prevention
- Confirm instrument price_precision from the instrument provider matches the IB contract
- Quantize computed averages to instrument precision before constructing Price
- Guard divisions by zero fill deltas in combo-fill logic
When it happens
Trigger: update_order_avg_price computes partial_avg_decimal = notional_delta / fill_delta and Price::from_decimal_dp(partial_avg_decimal, instrument.price_precision()) fails — e.g. price_precision is 0/invalid or the decimal cannot be rounded to the allowed decimal places.
Common situations: Instrument loaded with wrong price_precision from the venue/instrument provider; very small fill deltas producing extreme averages that can't fit the precision.
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
- AX {field} scale must not exceed 26 for exact percent conver
- Failed to convert avg fill price to Decimal: {converted_avg_
- price precision {precision} exceeds maximum {MAX_DECIMALS}
- invalid price `{value}`: {e}
- invalid price `{value}` at precision {precision}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/67ac7454e82aae9a.
Report an issue: GitHub.