nautechsystems/nautilus_trader · error

Invalid leverage {leverage} for {}

Error message

Invalid leverage {leverage} for {}

What it means

Leveraged initial margin calculation requires a strictly positive leverage; leverage <= 0 is meaningless (division by zero or negative notional-per-unit margin). The error includes the offending leverage and the instrument id.

Source

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

    pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.model")
)]
pub struct LeveragedMarginModel;

impl MarginModel for LeveragedMarginModel {
    fn name(&self) -> &'static str {
        "leveraged"
    }

    fn calculate_initial_margin(
        &self,
        instrument: &dyn Instrument,
        quantity: Quantity,
        price: Price,
        leverage: Decimal,
        use_quote_for_inverse: Option<bool>,
    ) -> anyhow::Result<Money> {
        if leverage <= Decimal::ZERO {
            anyhow::bail!("Invalid leverage {leverage} for {}", instrument.id());
        }
        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_div(leverage)
            .and_then(|adjusted| adjusted.checked_mul(instrument.margin_init()))
            .ok_or_else(|| anyhow::anyhow!("initial margin calculation overflow"))?;
        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,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Validate leverage > 0 before calling calculate_initial_margin
  2. Fix the source of leverage (config, exchange metadata) so it carries a positive value
  3. Use the margin model matching the instrument's actual leverage setting

Example fix

// before
model.calculate_initial_margin(&instrument, qty, price, Decimal::ZERO, None)?; // bails
// after
let leverage = Decimal::from(10); // or instrument.leverage()
anyhow::ensure!(leverage > Decimal::ZERO);
model.calculate_initial_margin(&instrument, qty, price, leverage, None)?;
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(leverage > Decimal::ZERO, "leverage must be positive");
let margin = model.calculate_initial_margin(&instrument, qty, price, leverage, None)?;

Type guard

fn is_valid_leverage(l: Decimal) -> bool { l > Decimal::ZERO }

Try / catch

match model.calculate_initial_margin(&instrument, qty, price, leverage, None) {
    Err(e) if e.to_string().starts_with("Invalid leverage") => { /* fix leverage source */ }
    other => other?,
}

Prevention

When it happens

Trigger: Calling calculate_initial_margin on the leveraged margin model with leverage <= Decimal::ZERO (zero or negative Decimal).

Common situations: Leverage loaded from config or an exchange API as 0/0.0 before the instrument is fully initialized; sign flips when computing leverage from notional/margin ratios; unset optional fields defaulting to zero.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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