{"record":{"id":"02d58e36b1509b2b","repo":"nautechsystems/nautilus_trader","slug":"cannot-calculate-cfd-swap-for-instrument-id-mid","errorCode":null,"errorMessage":"cannot calculate CFD swap for {instrument_id}: midpoint overflow","messagePattern":"cannot calculate CFD swap for (.+?): midpoint overflow","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/modules/cfd_swap.rs","lineNumber":188,"sourceCode":"    }\n\n    fn settlement_price(\n        ctx: &ExchangeContext,\n        instrument_id: InstrumentId,\n    ) -> anyhow::Result<Option<Price>> {\n        let Some(matching_engine) = ctx.matching_engines.get(&instrument_id) else {\n            return Ok(None);\n        };\n        let book = matching_engine.get_book();\n\n        match (book.best_bid_price(), book.best_ask_price()) {\n            (Some(bid), Some(ask)) => {\n                let midpoint = bid\n                    .as_decimal()\n                    .checked_add(ask.as_decimal())\n                    .and_then(|sum| sum.checked_div(Decimal::TWO))\n                    .ok_or_else(|| {\n                        anyhow::anyhow!(\n                            \"cannot calculate CFD swap for {instrument_id}: midpoint overflow\"\n                        )\n                    })?;\n                Ok(Some(Price::from_decimal(midpoint)?))\n            }\n            (Some(price), None) | (None, Some(price)) => Ok(Some(price)),\n            (None, None) => Ok(None),\n        }\n    }\n\n    fn log_calculation_failure(\n        &self,\n        booking_date: Date,\n        instrument_id: InstrumentId,\n        kind: CfdSwapFailureKind,\n        message: &str,\n    ) {\n        let first_failure = self","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/modules/cfd_swap.rs#L170-L206","documentation":"The CFD swap module computes the settlement price as the midpoint of the instrument's bid/ask using checked Decimal arithmetic. If bid+ask overflows the Decimal range (or division by two fails), it cannot form a midpoint and throws this error rather than producing a corrupted price.","triggerScenarios":"Calling settlement_price for an instrument whose bid and ask Decimals are so large their sum exceeds Decimal's maximum (e.g. mis-scaled prices like 1e28 for a low-precision instrument), when both bid and ask are present.","commonSituations":"Instruments configured with wrong precision/scale so prices parse as enormous Decimals; corrupted data where bid/ask carry garbage magnitudes; mixing price scales across data sources.","solutions":["Verify the instrument's price_precision/size and the data feed's price scaling; correct mis-scaled bid/ask data","Clamp or normalize extreme bid/ask values before the bar/quote reaches the module","Check upstream data for corruption (e.g. concatenated digits) and filter bad ticks"],"exampleFix":"// before: feeding raw prices with wrong scale\nlet bid = Price::from_raw(79228162514264337593543950335); // near Decimal::MAX\n// after: validate magnitude before use\nassert!(bid.as_decimal() < Decimal::from(1_000_000), \"bid out of expected range\");","handlingStrategy":"validation","validationCode":"// sanity-check quote magnitudes before the module computes midpoints\nfn valid_price(p: Price) -> bool {\n    let d = p.as_decimal();\n    d > Decimal::ZERO && d < Decimal::from(1_000_000)\n}\nassert!(valid_price(bid) && valid_price(ask));","typeGuard":"fn sane_price(p: &Price) -> bool {\n    p.as_decimal() > Decimal::ZERO && p.as_decimal() < Decimal::from(1_000_000)\n}","tryCatchPattern":"match module.settlement_price(&instrument_id, ts) {\n    Ok(price) => /* use price */,\n    Err(e) if e.to_string().contains(\"midpoint overflow\") => log::warn!(\"bad quote data: {e:#}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Verify instrument price_precision matches the data feed's scaling","Filter or clamp out-of-range ticks/quotes at ingestion","Validate data files for corrupted price fields"],"tags":["backtest","decimal-overflow","cfd","pricing"],"backgroundTag":"value-out-of-range","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"}