nautechsystems/nautilus_trader · error

Failed to create quantity from {quantity_dec}: {e}

Error message

Failed to create quantity from {quantity_dec}: {e}

What it means

parse_spot_margin_position_from_balance converts the OKX spot-in-use balance into a Nautilus quantity. Quantity::from_decimal_dp fails when the spotInUseAmt decimal cannot be represented at the instrument's size precision (wrong precision or malformed value), and the error is wrapped with the quantity value.

Source

Thrown at crates/adapters/okx/src/common/parse.rs:999

    }

    // Check if spotInUseAmt is zero first
    if spot_in_use_dec.is_zero() {
        // No position if spotInUseAmt is zero (regardless of liability)
        return Ok(None);
    }

    // Position side based on spotInUseAmt sign
    let (position_side, quantity_dec) = if spot_in_use_dec.is_sign_negative() {
        // Negative spotInUseAmt = sold (short position)
        (PositionSide::Short, spot_in_use_dec.abs())
    } else {
        // Positive spotInUseAmt = bought (long position)
        (PositionSide::Long, spot_in_use_dec)
    };

    let quantity = Quantity::from_decimal_dp(quantity_dec, size_precision)
        .map_err(|e| anyhow::anyhow!("Failed to create quantity from {quantity_dec}: {e}"))?;

    let ts_last = parse_millisecond_timestamp(balance.u_time);

    Ok(Some(PositionStatusReport::new(
        account_id,
        instrument_id,
        position_side,
        quantity,
        ts_last,
        ts_init,
        None, // report_id
        None, // venue_position_id is None for net mode margin positions
        None, // avg_px_open not available from balance
    )))
}

/// Parses an OKX position into a Nautilus [`PositionStatusReport`].
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check that size_precision passed to the function matches the instrument's size increment from the OKX instruments endpoint
  2. Log the raw spotInUseAmt and precision; verify the value has <= size_precision decimal places
  3. Re-fetch instrument definitions so precision metadata is current
  4. Round/normalize the quantity to size_precision before calling Quantity::from_decimal_dp

Example fix

// before
let quantity = Quantity::from_decimal_dp(quantity_dec, size_precision)
    .map_err(|e| anyhow::anyhow!("Failed to create quantity from {quantity_dec}: {e}"))?;
// after
let quantity_dec = quantity_dec.round_dp(size_precision as u32);
let quantity = Quantity::from_decimal_dp(quantity_dec, size_precision)
    .map_err(|e| anyhow::anyhow!("Failed to create quantity from {quantity_dec}: {e}"))?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check precision fits before calling
fn quantity_fits_precision(dec: rust_decimal::Decimal, precision: u8) -> bool {
    dec.round_dp(precision as u32) == dec
}
assert!(quantity_fits_precision(quantity_dec, size_precision), "quantity exceeds size precision");

Try / catch

match parse_spot_margin_position_from_balance(&balance, account_id, instrument_id, size_precision, ts_init) {
    Ok(report) => report,
    Err(e) => { tracing::error!("position quantity rejected: {e:#}"); return; }
}

Prevention

When it happens

Trigger: Calling parse_spot_margin_position_from_balance with an OKX balance-and-position payload whose spotInUseAmt has more decimal places than size_precision, or a non-representable value (e.g. scientific notation, negative, or a wrong precision passed by the caller).

Common situations: Instrument definitions loaded with an incorrect size_precision for the trading pair; stale instrument metadata after an OKX lot-size change; spot-margin liability amounts with unexpected precision from the account/balance endpoint.

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