nautechsystems/nautilus_trader · error
commission calculation overflow
Error message
commission calculation overflow
What it means
Fee models compute commissions with `Decimal` arithmetic. `mul_checked` wraps `Decimal::checked_mul` and raises this error when multiplying the rate by a quantity/price (or similar factors) would overflow the Decimal representation. It is a guard against silently producing an invalid commission.
Source
Thrown at crates/execution/src/models/fee.rs:326
}
impl PerContractFeeModel {
/// Creates a new [`PerContractFeeModel`] instance.
///
/// # Errors
///
/// Returns an error if `commission` is negative.
pub fn new(commission: Money) -> anyhow::Result<Self> {
if commission.raw < 0 {
anyhow::bail!("Commission must be greater than or equal to zero")
}
Ok(Self { commission })
}
}
fn mul_checked(lhs: Decimal, rhs: Decimal) -> anyhow::Result<Decimal> {
lhs.checked_mul(rhs)
.ok_or_else(|| anyhow::anyhow!("commission calculation overflow"))
}
impl FeeModel for PerContractFeeModel {
fn get_commission(
&self,
_order: &OrderAny,
fill_quantity: Quantity,
_fill_px: Price,
instrument: &InstrumentAny,
) -> anyhow::Result<Money> {
let contracts = spread_contract_count(instrument)?;
let total = mul_checked(self.commission.as_decimal(), fill_quantity.as_decimal())
.and_then(|v| mul_checked(v, contracts))?;
Money::from_decimal(total, self.commission.currency).map_err(Into::into)
}
}
fn spread_contract_count(instrument: &InstrumentAny) -> anyhow::Result<Decimal> {View on GitHub (pinned to 18893faf8b)
Solutions
- Validate fill quantity, fill price, and instrument multiplier are sane before computing commission.
- Reduce/fix the fee model parameters (rate, cap) that produce overflow-sized products.
- If legitimately large values are needed, scale the computation or use a wider numeric representation upstream.
Example fix
// before: unchecked inputs let fee = model.get_commission(&order, qty, px, &instrument)?; // after: pre-validate magnitudes assert!(qty.as_decimal() < Decimal::MAX / instrument.multiplier().as_decimal()); let fee = model.get_commission(&order, qty, px, &instrument)?;
Defensive patterns
Strategy: validation
Validate before calling
assert qty.as_decimal() > Decimal::ZERO && qty.as_decimal() < Decimal::from(1_000_000) assert instrument.multiplier().as_decimal() < Decimal::MAX / px.as_decimal()
Try / catch
match model.get_commission(&order, qty, px, &instrument) {
Ok(fee) => fee,
Err(e) if e.to_string().contains("overflow") => Money::zero(currency),
} Prevention
- Sanity-check fill quantities and prices before fee computation.
- Keep fee rates and caps within realistic bounds in configuration.
- Use checked arithmetic everywhere around Decimal commission math.
When it happens
Trigger: Calling `get_commission`/`get_commission_with_context` on a fee model (e.g. PerContractFeeModel, capped option fee model) with extreme fill quantities, prices, multipliers, or cap values whose product exceeds Decimal range.
Common situations: Instruments with enormous multipliers, malformed fill data (astronomical quantity), or a misconfigured fee cap/rate; running backtests on synthetic data with unbounded values.
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
- invalid cumulative_quote_qty='{}' for cumulative_filled_qty=
- decimal `{value}` does not fit in i64
- Generic spread contract count overflowed for {symbol}
- Decimal overflow adding {lhs} and {rhs}
- Decimal overflow subtracting {rhs} from {lhs}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e0a09548dc5d5314.
Report an issue: GitHub.