nautechsystems/nautilus_trader · error

Trade bin missing close price for {instrument_id}

Error message

Trade bin missing close price for {instrument_id}

What it means

parse_trade_bin requires the bin's `close` field, but BitMEX delivered it as null. Since a Bar without a close price is meaningless, the parser aborts with this anyhow error identifying the instrument.

Source

Thrown at crates/adapters/bitmex/src/http/parse.rs:748

    instrument: &InstrumentAny,
    bar_type: &BarType,
    ts_init: UnixNanos,
) -> anyhow::Result<Bar> {
    let instrument_id = bar_type.instrument_id();
    let price_precision = instrument.price_precision();

    let open = bin
        .open
        .ok_or_else(|| anyhow::anyhow!("Trade bin missing open price for {instrument_id}"))?;
    let high = bin
        .high
        .ok_or_else(|| anyhow::anyhow!("Trade bin missing high price for {instrument_id}"))?;
    let low = bin
        .low
        .ok_or_else(|| anyhow::anyhow!("Trade bin missing low price for {instrument_id}"))?;
    let close = bin
        .close
        .ok_or_else(|| anyhow::anyhow!("Trade bin missing close price for {instrument_id}"))?;

    let open = Price::new(open, price_precision);
    let high = Price::new(high, price_precision);
    let low = Price::new(low, price_precision);
    let close = Price::new(close, price_precision);

    let (open, high, low, close) =
        normalize_trade_bin_prices(open, high, low, close, &bin.symbol, Some(bar_type));

    let volume_contracts = normalize_trade_bin_volume(bin.volume, &bin.symbol);
    let volume = parse_contracts_quantity(volume_contracts, instrument);
    let ts_event = UnixNanos::from(bin.timestamp);

    Ok(Bar::new(
        *bar_type, open, high, low, close, volume, ts_event, ts_init,
    ))
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Drop the in-progress bin; request only closed bins.
  2. Retry after the bin interval; finalized bins include close.
  3. Validate/filter bins for null OHLC before calling parse_trade_bin.
  4. Check for BitMEX adapter or API response schema updates.

Example fix

// before
let close = bin.close.ok_or_else(|| anyhow::anyhow!("Trade bin missing close price for {instrument_id}"))?;
// after
let Some(close) = bin.close else {
    log::warn!("Skipping bin with no close for {instrument_id}");
    return Ok(None);
};
Defensive patterns

Strategy: validation

Validate before calling

let complete = [bin.open, bin.high, bin.low, bin.close].iter().all(|p| p.is_some());

Type guard

fn close_available(bin: &BitmexTradeBin) -> Option<f64> { bin.close }

Try / catch

match parse_trade_bin(&bin, instrument_id, precision) {
    Ok(bar) => bars.push(bar),
    Err(e) => debug!("skipping bin for {instrument_id}: {e}"),
}

Prevention

When it happens

Trigger: request_bars handling a trade bin whose `close` field is null — commonly the still-forming current bin or a partial API response.

Common situations: Streaming/subscribing to the live latest bin; historical requests crossing an exchange data hiccup; API version or response-shape changes that relax field presence.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/40c1ea644c965c04. Report an issue: GitHub.