nautechsystems/nautilus_trader · error
initial margin calculation overflow
Error message
initial margin calculation overflow
What it means
Thrown by the leveraged (non-standard) initial margin path when the checked decimal multiplication of |notional| by margin_init overflows, or when the resulting margin cannot be converted to a Money value at the currency's precision. It is a guard against arithmetic overflow rather than a logic error, since margin amounts can be extremely large for high notionals or rates.
Source
Thrown at crates/model/src/accounts/margin_model.rs:271
}
fn calculate_initial_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))?;
// Spreads and options may quote negative, which carries the sign into the notional.
// A requirement is a reserve against exposure magnitude, so take it on `abs`.
let margin = notional
.as_decimal()
.abs()
.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,
_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())View on GitHub (pinned to 18893faf8b)
Solutions
- Check the quantity and price inputs for unreasonable magnitude before calling
- Verify instrument.margin_init() is a sane rate (e.g. 0.01–1.0, not 1000)
- Handle the error and skip/reject the position instead of unwrapping
Example fix
// before
let margin = model.calculate_initial_margin(&inst, qty, price, None).unwrap();
// after
match model.calculate_initial_margin(&inst, qty, price, None) {
Ok(m) => ...,
Err(e) if e.to_string().contains("overflow") => warn!("margin overflow, rejecting"),
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
if qty.as_decimal().abs() * price.as_decimal() > Decimal::from(1e18) {
return Err(anyhow!("notional too large for margin calc"));
} Try / catch
match model.calculate_initial_margin(&inst, qty, price, use_quote) {
Ok(m) => m,
Err(e) if e.to_string().contains("overflow") => { warn!("initial margin overflow: {e}"); Money::zero(currency) }
Err(e) => return Err(e),
} Prevention
- Bound quantity/price inputs from market data sanity checks
- Keep margin_init rates in [0,1]
- Never unwrap margin calculations in production paths
When it happens
Trigger: calculate_initial_margin with an extremely large notional value (huge quantity × price) multiplied by margin_init such that the rust_decimal product overflows; also when Money::from_decimal cannot represent the margin at the currency precision.
Common situations: Backtests with oversized or malformed prices/quantities; instruments with unreasonably large margin_init rates; low-precision currencies receiving very large margins.
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
- maintenance margin calculation overflow
- WETH balance overflow for included transaction {tx_hash} at
- Decimal overflow adding {lhs} and {rhs}
- Decimal overflow subtracting {rhs} from {lhs}
- Decimal overflow multiplying {lhs} by {rhs}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/386bfa2fea8863b1.
Report an issue: GitHub.