nautechsystems/nautilus_trader · error

invalid Futures trade id {}: {e}

Error message

invalid Futures trade id {}: {e}

What it means

Thrown by parse_futures_trade_tick when the trade's price string cannot be converted to a Price at the cached instrument's price_precision. The chain is Decimal::from_str (fails on malformed strings) then Price::from_decimal_dp (fails when the value is negative, zero, or has more precision than the instrument declares); the message prefixes the offending trade's ID so the raw venue payload can be located.

Source

Thrown at crates/adapters/binance/src/futures/http/client.rs:3158

                &rate,
                instrument_id,
                ts_init,
            )?);
        }

        Ok(result)
    }
}

fn parse_futures_trade_tick(
    trade: &BinanceFuturesTrade,
    instrument_id: InstrumentId,
    price_precision: u8,
    size_precision: u8,
    ts_init: UnixNanos,
) -> anyhow::Result<TradeTick> {
    let price = parse_required_price_at_precision(&trade.price, price_precision, "trade.price")
        .map_err(|e| anyhow::anyhow!("invalid Futures trade id {}: {e}", trade.id))?;
    let size = parse_required_quantity_at_precision(&trade.qty, size_precision, "trade.qty")
        .map_err(|e| anyhow::anyhow!("invalid Futures trade id {}: {e}", trade.id))?;
    let ts_event = parse_millis(trade.time, "Futures trade time")?;

    let aggressor_side = if trade.is_buyer_maker {
        AggressorSide::Sell
    } else {
        AggressorSide::Buy
    };

    Ok(TradeTick::new(
        instrument_id,
        price,
        size,
        aggressor_side,
        TradeId::new(trade.id.to_string()),
        ts_event,
        ts_init,

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Reload instrument definitions (re-request instruments) so the cache holds the venue's current price_precision, then retry
  2. Capture the failing raw trade (by the ID in the message) and compare its decimals against the cached instrument's precision to confirm the mismatch
  3. If the value is malformed/negative, inspect for proxy or fixture tampering rather than retrying
  4. Report persistent mismatches upstream — NautilusTrader must not silently round venue prices
Defensive patterns

Strategy: validation

Validate before calling

// keep instrument precisions fresh before parsing live trades
if client.get_price_precision(&symbol).is_err() {
    client.request_instruments(None).await?;
}

Try / catch

Catch per-trade: the error names the trade ID — log it with the raw price string, skip the tick (or halt the stream if mismatches cluster), and trigger an instrument-cache refresh before resuming.

Prevention

When it happens

Trigger: An aggTrade/trade payload whose price string has more decimal places than quantity_precision... (price side: price_precision) of the cached instrument definition — typically after Binance changes tick precision and the client cache still holds stale precision loaded at session start; malformed values like '-' or scientific-notation strings; negative or zero prices (impossible from the venue, possible from broken fixtures).

Common situations: Long-running live sessions that loaded instruments before a venue precision change; testnet instruments whose metadata differs from mainnet; replay fixtures with synthetic price strings; stale instrument cache after Binance contract adjustments (e.g. price precision changes on delisting/consolidation events).

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/2f761a144fcaeef7. Report an issue: GitHub.