{"record":{"id":"dc7d5e45a09fab8b","repo":"nautechsystems/nautilus_trader","slug":"notional-calculation-overflow","errorCode":null,"errorMessage":"notional calculation overflow","messagePattern":"notional calculation overflow","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/instruments/mod.rs","lineNumber":728,"sourceCode":") -> anyhow::Result<Money> {\n    let amount = if is_inverse && !use_quote_for_inverse {\n        anyhow::ensure!(\n            price.is_positive(),\n            \"price must be positive for inverse notional valuation\"\n        );\n        quantity\n            .as_decimal()\n            .checked_mul(multiplier.as_decimal())\n            .and_then(|value| value.checked_div(price.as_decimal()))\n            .ok_or_else(|| anyhow::anyhow!(\"inverse notional calculation overflow\"))?\n    } else if is_inverse {\n        quantity.as_decimal()\n    } else {\n        quantity\n            .as_decimal()\n            .checked_mul(multiplier.as_decimal())\n            .and_then(|value| value.checked_mul(price.as_decimal()))\n            .ok_or_else(|| anyhow::anyhow!(\"notional calculation overflow\"))?\n    };\n\n    Money::from_decimal(amount, currency).map_err(Into::into)\n}\n\nimpl Display for CurrencyPair {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}(instrument_id='{}', tick_scheme='{}', price_precision={}, size_precision={}, \\\nprice_increment={}, size_increment={}, multiplier={}, margin_init={}, margin_maint={})\",\n            stringify!(CurrencyPair),\n            self.id,\n            self.tick_scheme()\n                .map_or_else(|| \"None\".into(), |s| s.to_string()),\n            self.price_precision(),\n            self.size_precision(),\n            self.price_increment(),","sourceCodeStart":710,"sourceCodeEnd":746,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/instruments/mod.rs#L710-L746","documentation":"For non-inverse instruments the notional is quantity * multiplier * price using checked Decimal arithmetic. If the chained checked_mul operations return None (capacity overflow of the Decimal type), try_notional_value raises this error instead of returning a corrupted Money value.","triggerScenarios":"try_calculate_notional_value on a linear instrument where quantity * multiplier * price exceeds decimal bounds — oversized quantity, oversized multiplier, or an extreme price multiplying together beyond Decimal limits.","commonSituations":"Misconfigured instrument multiplier (e.g. contract size in wrong units), test/simulation code feeding absurd quantities, or valuation on hyper-inflated synthetic price series in backtests.","solutions":["Verify the instrument's multiplier/size configuration; fix units if the multiplier is wrong.","Clamp quantity and price to instrument-defined max_quantity/max_price before computing notional.","Catch the error from the try_ notional API and skip/report the valuation for that tick instead of failing the run."],"exampleFix":"// before\nlet notional = instrument.calculate_notional_value(price, qty, None)?;\n// after\nanyhow::ensure!(qty <= instrument.max_quantity(), \"qty exceeds instrument max\");\nanyhow::ensure!(price <= instrument.max_price(), \"price exceeds instrument max\");\nlet notional = instrument.calculate_notional_value(price, qty, None)?;","handlingStrategy":"try-catch","validationCode":"if qty > instrument.max_quantity() || price > instrument.max_price() { return Err(TradeError::NotionalOverflowRisk); }","typeGuard":null,"tryCatchPattern":"// Rust\nlet notional = instrument\n    .try_calculate_notional_value(price, qty, None)\n    .map_err(|e| { log::error!(\"notional overflow: {e}\"); TradeError::NotionalOverflow })?;","preventionTips":["Validate instrument multiplier and size units at startup","Clamp price/quantity to instrument max values before computing notional","Use the try_ API and skip/report valuations that overflow instead of panicking"],"tags":["notional","overflow","decimal-arithmetic","money"],"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"}