nautechsystems/nautilus_trader · error · anyhow::Error
AX minimum_order_size must be a positive whole number, was
Error message
AX minimum_order_size must be a positive whole number, was {} What it means
The AX instrument definition's `minimum_order_size` must be a positive whole number (strictly greater than zero with no fractional part). The adapter enforces this because NautilusTrader quantity increments derived from it require discrete whole-number minimums.
Solutions
- Check the raw definition's minimum_order_size value returned by the AX API.
- Round/floor to a whole number at the data source if the venue's value is representable that way, or truncate trailing fraction if it is a formatting artifact.
- If the venue now legitimately supports fractional minimums, extend the adapter's parsing logic instead of altering data.
- Fix fixture values to positive whole numbers in tests/mocks.
Example fix
// before (payload) "minimum_order_size": "0.5" // after "minimum_order_size": "1"
Defensive patterns
Strategy: validation
Validate before calling
fn valid_min_size(d: &InstrumentDefinition) -> bool {
d.minimum_order_size > Decimal::ZERO && d.minimum_order_size.fract().is_zero()
} Prevention
- Validate instrument definitions before feeding them to the adapter
- Quantize venue-provided minimums at ingestion
- Keep fixtures realistic (no zero placeholders)
- Track AX venue metadata changes for new instrument types
When it happens
Trigger: request_instruments/request_instrument -> parse_instrument on a definition where minimum_order_size is zero, negative, or fractional (e.g. 0, -1, 0.5, 10.25).
Common situations: AX venue changes instrument metadata to a fractional minimum lot size; fixtures with placeholder values like 0; a new instrument type (e.g. fractional notional minimums) not supported by the adapter yet.
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
- AX dated contract has different quote and settlement…
- AX scale must not exceed 26 for exact percent conversion…
- AX initial_margin_pct must be positive, was
- AX instrument product must be non-empty without surrounding…
- AX maintenance_margin_pct must be positive, was
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f7d601699cfc59f5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/architect_ax/src/http/parse.rs:210
{
&symbol_prefix[..symbol_prefix.len() - quote_code.len()]
} else {
symbol_prefix
};
let asset_class = AssetClass::from(definition.category);
// Only resolve base currency for FX/crypto where the base code is a currency
let base_currency = match asset_class {
AssetClass::FX | AssetClass::Cryptocurrency => Some(get_currency(base_code)),
_ => None,
};
let quote_currency = get_currency(quote_code);
let settlement_currency = get_currency(definition.funding_settlement_currency.as_str());
let price_increment = decimal_to_price(definition.tick_size, "tick_size")?;
anyhow::ensure!(
definition.minimum_order_size > Decimal::ZERO
&& definition.minimum_order_size.fract().is_zero(),
"AX minimum_order_size must be a positive whole number, was {}",
definition.minimum_order_size
);
let size_increment = decimal_to_quantity(Decimal::ONE, "size_increment")?;
let lot_size = Some(size_increment);
let min_quantity = Some(decimal_to_quantity(
definition.minimum_order_size.normalize(),
"minimum_order_size",
)?);
let (margin_init, margin_maint) = parse_margin_rates(
definition.initial_margin_pct,
definition.maintenance_margin_pct,
)?;
let mut info = Params::new();View on GitHub (pinned to 18893faf8b)