nautechsystems/nautilus_trader · error

notional calculation overflow

Error message

notional calculation overflow

What it means

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.

Source

Thrown at crates/model/src/instruments/mod.rs:728

) -> anyhow::Result<Money> {
    let amount = if is_inverse && !use_quote_for_inverse {
        anyhow::ensure!(
            price.is_positive(),
            "price must be positive for inverse notional valuation"
        );
        quantity
            .as_decimal()
            .checked_mul(multiplier.as_decimal())
            .and_then(|value| value.checked_div(price.as_decimal()))
            .ok_or_else(|| anyhow::anyhow!("inverse notional calculation overflow"))?
    } else if is_inverse {
        quantity.as_decimal()
    } else {
        quantity
            .as_decimal()
            .checked_mul(multiplier.as_decimal())
            .and_then(|value| value.checked_mul(price.as_decimal()))
            .ok_or_else(|| anyhow::anyhow!("notional calculation overflow"))?
    };

    Money::from_decimal(amount, currency).map_err(Into::into)
}

impl Display for CurrencyPair {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}(instrument_id='{}', tick_scheme='{}', price_precision={}, size_precision={}, \
price_increment={}, size_increment={}, multiplier={}, margin_init={}, margin_maint={})",
            stringify!(CurrencyPair),
            self.id,
            self.tick_scheme()
                .map_or_else(|| "None".into(), |s| s.to_string()),
            self.price_precision(),
            self.size_precision(),
            self.price_increment(),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the instrument's multiplier/size configuration; fix units if the multiplier is wrong.
  2. Clamp quantity and price to instrument-defined max_quantity/max_price before computing notional.
  3. Catch the error from the try_ notional API and skip/report the valuation for that tick instead of failing the run.

Example fix

// before
let notional = instrument.calculate_notional_value(price, qty, None)?;
// after
anyhow::ensure!(qty <= instrument.max_quantity(), "qty exceeds instrument max");
anyhow::ensure!(price <= instrument.max_price(), "price exceeds instrument max");
let notional = instrument.calculate_notional_value(price, qty, None)?;
Defensive patterns

Strategy: try-catch

Validate before calling

if qty > instrument.max_quantity() || price > instrument.max_price() { return Err(TradeError::NotionalOverflowRisk); }

Try / catch

// Rust
let notional = instrument
    .try_calculate_notional_value(price, qty, None)
    .map_err(|e| { log::error!("notional overflow: {e}"); TradeError::NotionalOverflow })?;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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