nautechsystems/nautilus_trader · error · anyhow::Error
AX maintenance_margin_pct must be positive, was
Error message
AX maintenance_margin_pct must be positive, was {maintenance_margin_pct} What it means
Validation in AX instrument parsing's parse_margin_rates: the parsed maintenance margin percentage is zero or negative, which cannot represent a valid margin requirement, so the instrument definition is rejected.
Solutions
- Inspect the venue's maintenance margin field for the instrument.
- Correct the upstream value to a positive percentage.
- Fix fixtures to carry realistic positive maintenance margins.
- Handle/filter instruments with missing margin data before parsing if they are not tradable.
Example fix
// before (payload) "margin_maint_pct": "0" // after "margin_maint_pct": "0.05"
Defensive patterns
Strategy: validation
Validate before calling
fn valid_maintenance_margin(v: Decimal) -> bool { v > Decimal::ZERO } Prevention
- Validate both margin fields together before parsing
- Watch for venue feeds defaulting margins to zero
- Fix float-to-Decimal generation so nulls do not become zeros
When it happens
Trigger: parse_instrument (via request_instruments/request_instrument) on a definition where maintenance_margin_pct <= 0.
Common situations: Missing or zero-defaulted margin metadata from the venue, fixtures with placeholder zeros, negative values from a malformed feed.
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
- AX initial_margin_pct must be positive, was
- AX scale must not exceed 26 for exact percent conversion…
- AX maintenance_margin_pct
- AX minimum_order_size must be a positive whole number, was
- Failed to parse liab
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/191375d81e8a0b74.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/architect_ax/src/http/parse.rs:381
.taker_fee(taker_fee)
.info(info)
.ts_event(ts_event)
.ts_init(ts_init)
.build()
.unwrap();
Ok(InstrumentAny::PerpetualContract(instrument))
}
fn parse_margin_rates(
initial_margin_pct: Decimal,
maintenance_margin_pct: Decimal,
) -> anyhow::Result<(Decimal, Decimal)> {
anyhow::ensure!(
initial_margin_pct > Decimal::ZERO,
"AX initial_margin_pct must be positive, was {initial_margin_pct}"
);
anyhow::ensure!(
maintenance_margin_pct > Decimal::ZERO,
"AX maintenance_margin_pct must be positive, was {maintenance_margin_pct}"
);
anyhow::ensure!(
maintenance_margin_pct <= initial_margin_pct,
"AX maintenance_margin_pct {maintenance_margin_pct} exceeds initial_margin_pct {initial_margin_pct}"
);
Ok((
margin_percent_to_rate(initial_margin_pct, "initial_margin_pct")?,
margin_percent_to_rate(maintenance_margin_pct, "maintenance_margin_pct")?,
))
}
fn margin_percent_to_rate(value: Decimal, field: &str) -> anyhow::Result<Decimal> {
let normalized = value.normalize();
let scale = normalized.scale();
anyhow::ensure!(View on GitHub (pinned to 18893faf8b)