{"record":{"id":"757dfdd12ba9c314","repo":"nautechsystems/nautilus_trader","slug":"empty-funding-rate-for-instrument-id-dated-futu","errorCode":null,"errorMessage":"empty funding_rate for {instrument_id} (dated futures do not have funding rates)","messagePattern":"empty funding_rate for (.+?) \\(dated futures do not have funding rates\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/adapters/bybit/src/websocket/parse.rs","lineNumber":467,"sourceCode":"\n/// Parses a linear ticker payload into a [`FundingRateUpdate`].\n///\n/// # Errors\n///\n/// Returns an error if funding rate, funding interval or next funding time fields are missing or cannot be parsed.\npub fn parse_ticker_linear_funding(\n    data: &BybitWsTickerLinear,\n    instrument_id: InstrumentId,\n    ts_event: UnixNanos,\n    ts_init: UnixNanos,\n) -> anyhow::Result<FundingRateUpdate> {\n    let funding_rate_str = data\n        .funding_rate\n        .as_ref()\n        .context(\"Bybit ticker missing funding_rate\")?;\n\n    if funding_rate_str.is_empty() {\n        anyhow::bail!(\n            \"empty funding_rate for {instrument_id} (dated futures do not have funding rates)\"\n        );\n    }\n\n    let funding_rate = funding_rate_str\n        .as_str()\n        .parse::<Decimal>()\n        .with_context(|| {\n            format!(\"invalid funding_rate value '{funding_rate_str}' for {instrument_id}\")\n        })?;\n\n    let funding_interval = if let Some(funding_interval_hour) = &data.funding_interval_hour {\n        let funding_interval_hour = funding_interval_hour\n            .as_str()\n            .parse::<u16>()\n            .context(\"invalid funding_interval_hour value\")?;\n        Some(\n            funding_interval_hour","sourceCodeStart":449,"sourceCodeEnd":485,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/websocket/parse.rs#L449-L485","documentation":"Bybit's linear ticker payload contained an empty `funding_rate` string. For dated (delivery) futures Bybit sends an empty funding rate because those instruments have no funding; the adapter surfaces this explicitly rather than parsing an empty string into a bogus rate.","triggerScenarios":"`parse_ticker_linear_funding` is called on a ticker message for a dated/delivery futures instrument whose `funding_rate` field is `Some(\"\")`.","commonSituations":"Subscribing to tickers on dated futures (e.g. quarterly expiries) where funding does not apply; running a perp-focused consumer against delivery contracts.","solutions":["Only request funding rates for perpetual instruments; skip dated futures tickers before parsing.","Treat the error as 'instrument has no funding' and continue processing the stream instead of failing.","Check `instrument_info`/contract type when subscribing so delivery contracts are excluded from funding handling."],"exampleFix":"// before: parse every linear ticker\nlet fr = parse_ticker_linear_funding(&data, instrument_id)?;\n// after: skip dated futures\nif !is_perpetual(instrument_id) {\n    return Ok(None); // dated futures have no funding rate\n}\nlet fr = parse_ticker_linear_funding(&data, instrument_id)?;","handlingStrategy":"validation","validationCode":"if !instrument_id.to_string().contains(\"-PERP\") {\n    return Ok(None); // dated futures have no funding rate\n}","typeGuard":"fn is_perpetual(instrument_id: &InstrumentId) -> bool {\n    instrument_id.symbol.to_string().ends_with(\"-PERP\")\n}","tryCatchPattern":"match parse_ticker_linear_funding(&data, instrument_id) {\n    Ok(fr) => publish_funding(fr),\n    Err(e) if e.to_string().contains(\"empty funding_rate\") => {\n        tracing::debug!(\"{instrument_id} is dated; no funding rate\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Subscribe to funding tickers only for perpetual instruments","Filter delivery/dated contracts out of funding consumers","Check instrument metadata (contract type) at subscription time"],"tags":["bybit","websocket","funding-rate","futures"],"backgroundTag":"empty-required-field","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"}