{"record":{"id":"40c1ea644c965c04","repo":"nautechsystems/nautilus_trader","slug":"trade-bin-missing-close-price-for-instrument-id","errorCode":null,"errorMessage":"Trade bin missing close price for {instrument_id}","messagePattern":"Trade bin missing close price for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bitmex/src/http/parse.rs","lineNumber":748,"sourceCode":"    instrument: &InstrumentAny,\n    bar_type: &BarType,\n    ts_init: UnixNanos,\n) -> anyhow::Result<Bar> {\n    let instrument_id = bar_type.instrument_id();\n    let price_precision = instrument.price_precision();\n\n    let open = bin\n        .open\n        .ok_or_else(|| anyhow::anyhow!(\"Trade bin missing open price for {instrument_id}\"))?;\n    let high = bin\n        .high\n        .ok_or_else(|| anyhow::anyhow!(\"Trade bin missing high price for {instrument_id}\"))?;\n    let low = bin\n        .low\n        .ok_or_else(|| anyhow::anyhow!(\"Trade bin missing low price for {instrument_id}\"))?;\n    let close = bin\n        .close\n        .ok_or_else(|| anyhow::anyhow!(\"Trade bin missing close price for {instrument_id}\"))?;\n\n    let open = Price::new(open, price_precision);\n    let high = Price::new(high, price_precision);\n    let low = Price::new(low, price_precision);\n    let close = Price::new(close, price_precision);\n\n    let (open, high, low, close) =\n        normalize_trade_bin_prices(open, high, low, close, &bin.symbol, Some(bar_type));\n\n    let volume_contracts = normalize_trade_bin_volume(bin.volume, &bin.symbol);\n    let volume = parse_contracts_quantity(volume_contracts, instrument);\n    let ts_event = UnixNanos::from(bin.timestamp);\n\n    Ok(Bar::new(\n        *bar_type, open, high, low, close, volume, ts_event, ts_init,\n    ))\n}\n","sourceCodeStart":730,"sourceCodeEnd":766,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bitmex/src/http/parse.rs#L730-L766","documentation":"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.","triggerScenarios":"request_bars handling a trade bin whose `close` field is null — commonly the still-forming current bin or a partial API response.","commonSituations":"Streaming/subscribing to the live latest bin; historical requests crossing an exchange data hiccup; API version or response-shape changes that relax field presence.","solutions":["Drop the in-progress bin; request only closed bins.","Retry after the bin interval; finalized bins include close.","Validate/filter bins for null OHLC before calling parse_trade_bin.","Check for BitMEX adapter or API response schema updates."],"exampleFix":"// before\nlet close = bin.close.ok_or_else(|| anyhow::anyhow!(\"Trade bin missing close price for {instrument_id}\"))?;\n// after\nlet Some(close) = bin.close else {\n    log::warn!(\"Skipping bin with no close for {instrument_id}\");\n    return Ok(None);\n};","handlingStrategy":"validation","validationCode":"let complete = [bin.open, bin.high, bin.low, bin.close].iter().all(|p| p.is_some());","typeGuard":"fn close_available(bin: &BitmexTradeBin) -> Option<f64> { bin.close }","tryCatchPattern":"match parse_trade_bin(&bin, instrument_id, precision) {\n    Ok(bar) => bars.push(bar),\n    Err(e) => debug!(\"skipping bin for {instrument_id}: {e}\"),\n}","preventionTips":["Drop the live bin from bar windows before parsing.","Poll finalized bins after interval boundaries.","Keep a schema-tolerant filter between the HTTP layer and the parser."],"tags":["bitmex","bars","missing-data","null-field"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}