nautechsystems/nautilus_trader · error

inverse notional calculation overflow

Error message

inverse notional calculation overflow

What it means

For inverse instruments the notional is (quantity * multiplier) / price computed with checked Decimal arithmetic. If any checked_mul/checked_div overflows or otherwise fails (None), try_notional_value raises this overflow error rather than silently producing a wrong value.

Source

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

pub(crate) fn try_notional_value(
    quantity: Quantity,
    price: Price,
    multiplier: Quantity,
    is_inverse: bool,
    use_quote_for_inverse: bool,
    currency: Currency,
) -> 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={}, \

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Sanity-check instrument multiplier and quantity magnitudes; correct the instrument definition if the multiplier is misconfigured.
  2. Validate quantity against instrument.max_quantity before valuation.
  3. Handle the Result from the try_ API and clamp/log rather than propagating a panic from the panicking wrapper.

Example fix

// before
let notional = instrument.calculate_notional_value(price, huge_qty, None)?;
// after
anyhow::ensure!(huge_qty <= instrument.max_quantity(), "quantity out of bounds");
let notional = instrument.calculate_notional_value(price, huge_qty, None)?;
Defensive patterns

Strategy: try-catch

Validate before calling

if qty > instrument.max_quantity() || multiplier.as_f64() > 1e12 { return Err(TradeError::NotionalOverflowRisk); }

Try / catch

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

Prevention

When it happens

Trigger: try_calculate_notional_value on an inverse instrument where quantity * multiplier (or its division by price) exceeds the decimal arithmetic capacity — e.g. astronomically large quantity/multiplier values or a near-zero price inflating the quotient.

Common situations: Valuing positions with wrongly scaled multiplier units, instruments configured with huge multipliers, or extreme prices near zero in stressed backtests causing the division to blow past Decimal bounds.

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/81d940fb2a198f9e. Report an issue: GitHub.