nautechsystems/nautilus_trader · error · anyhow::Error
Failed to convert avg fill price to Decimal: {converted_avg_
Error message
Failed to convert avg fill price to Decimal: {converted_avg_price} What it means
The adapter converts the IB average fill price (already scaled by the instrument's price magnifier) into a Decimal with from_f64_retain. If the computed avg fill price is NaN or infinite, the conversion returns None and this error is thrown, preventing corrupt notional tracking in order_fill_progress.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/core_updates.rs:935
let is_spread_order = is_spread_instrument_id(instrument_id);
if filled <= 0.0 || !parse::should_use_avg_fill_price(avg_fill_price, instrument_id) {
return Ok(());
}
let Some(instrument) = instrument_provider.find(instrument_id) else {
return Ok(());
};
let price_magnifier = instrument_provider.get_price_magnifier(instrument_id) as f64;
let converted_avg_price = avg_fill_price * price_magnifier;
let avg_px = Price::new(converted_avg_price, instrument.price_precision());
order_avg_prices.lock().insert(client_order_id, avg_px);
let filled_decimal = Decimal::from_f64_retain(filled)
.ok_or_else(|| anyhow::anyhow!("Failed to convert filled qty to Decimal: {filled}"))?;
let avg_decimal = Decimal::from_f64_retain(converted_avg_price).ok_or_else(|| {
anyhow::anyhow!("Failed to convert avg fill price to Decimal: {converted_avg_price}")
})?;
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;View on GitHub (pinned to 18893faf8b)
Solutions
- Validate avg_fill_price is finite and positive before multiplying by the magnifier.
- Verify the instrument's price_magnifier matches the IB contract definition (e.g. 100 for US futures).
- Log the raw IB execution report when triggered to find the malformed price source.
Example fix
// before
let converted_avg_price = avg_fill_price * price_magnifier;
// after
if !avg_fill_price.is_finite() || avg_fill_price <= 0.0 {
tracing::warn!("Skipping avg price update, invalid avg fill price: {avg_fill_price}");
return Ok(());
}
let converted_avg_price = avg_fill_price * price_magnifier; Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate avg fill price and magnifier before scaling
fn valid_avg_price(avg_fill_price: f64, magnifier: f64) -> bool {
avg_fill_price.is_finite()
&& avg_fill_price > 0.0
&& magnifier.is_finite()
&& magnifier > 0.0
&& (avg_fill_price * magnifier).is_finite()
} Type guard
fn is_representable_decimal(x: f64) -> bool {
x.is_finite() && Decimal::from_f64_retain(x).is_some()
} Try / catch
let avg_decimal = match Decimal::from_f64_retain(converted_avg_price) {
Some(d) => d,
None => {
tracing::error!("Invalid avg fill price {converted_avg_price}; skipping update");
return Ok(());
}
}; Prevention
- Verify each instrument's price_magnifier against the IB contract specification
- Validate f64 prices from IB reports before arithmetic
- Add unit tests for NaN/inf fill prices in adapter tests
When it happens
Trigger: update_order_avg_price computes converted_avg_price = avg_fill_price * price_magnifier; if avg_fill_price is NaN/inf (or the magnifier is bogus producing inf), Decimal::from_f64_retain fails and the error is raised.
Common situations: IB reports an avg fill price of NaN (e.g. certain combo or what-if executions); wrong price_magnifier configured for the instrument causing overflow to infinity.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Failed to convert filled qty to Decimal: {filled}
- Failed to create avg_px price: {e}
- invalid price `{value}`: {e}
- Invalid quote rate for pair {pair}, was {value}
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a25f756dd520eabe.
Report an issue: GitHub.