nautechsystems/nautilus_trader · error

maintenance margin calculation overflow

Error message

maintenance margin calculation overflow

What it means

Same overflow guard as the initial margin variant, but in the leveraged maintenance margin path: |notional| × margin_maint is computed with checked_mul and any overflow, or a Money conversion failure at the currency precision, produces this error. It protects the account model from producing an invalid reserve requirement.

Source

Thrown at crates/model/src/accounts/margin_model.rs:290

        let currency = margin_currency(instrument, use_quote)?;
        Money::from_decimal(margin, currency).map_err(Into::into)
    }

    fn calculate_maintenance_margin(
        &self,
        instrument: &dyn Instrument,
        quantity: Quantity,
        price: Price,
        _leverage: Decimal,
        use_quote_for_inverse: Option<bool>,
    ) -> anyhow::Result<Money> {
        let use_quote = use_quote_for_inverse.unwrap_or(false);
        let notional = instrument.try_calculate_notional_value(quantity, price, Some(use_quote))?;
        let margin = notional
            .as_decimal()
            .abs()
            .checked_mul(instrument.margin_maint())
            .ok_or_else(|| anyhow::anyhow!("maintenance margin calculation overflow"))?;
        let currency = margin_currency(instrument, use_quote)?;
        Money::from_decimal(margin, currency).map_err(Into::into)
    }
}

/// Divides notional value by leverage before applying margin rates.
///
/// Margin is calculated as `(notional_value / leverage) * margin_rate`.
/// This is the default model, appropriate for crypto exchanges and venues
/// where leverage directly reduces margin requirements.
#[derive(Debug, Clone, Copy)]
#[cfg_attr(
    feature = "python",
    pyo3::pyclass(module = "nautilus_trader.model", from_py_object)
)]
#[cfg_attr(
    feature = "python",
    pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.model")

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Validate quantity/price magnitudes before the call
  2. Check instrument.margin_maint() for a plausible rate
  3. Propagate or handle the error instead of panicking; reject the position

Example fix

// before
let mm = model.calculate_maintenance_margin(&inst, qty, price, None).unwrap();
// after
let mm = model.calculate_maintenance_margin(&inst, qty, price, None)?; // handle Err upstream
Defensive patterns

Strategy: try-catch

Validate before calling

if notional.abs() > Decimal::from(1e18) { bail!("notional too large for maintenance margin"); }

Try / catch

match model.calculate_maintenance_margin(&inst, qty, price, use_quote) {
    Ok(m) => m,
    Err(e) if e.to_string().contains("overflow") => { warn!("maintenance margin overflow"); default_reserve }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: calculate_maintenance_margin called with notional × margin_maint exceeding decimal limits, or a margin that Money::from_decimal cannot represent for the resolved currency.

Common situations: Huge price/quantity inputs in simulation; corrupt market data producing astronomic notionals; instruments with exaggerated margin_maint rates.

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/9a4d58ca0e3d076c. Report an issue: GitHub.