nautechsystems/nautilus_trader · error · anyhow::Error
trade price must be in (0, 1)
Error message
trade price must be in (0, 1)
What it means
Polymarket markets are probabilistic, so all trade prices must be strictly between 0 and 1. The adapter enforces this invariant before constructing a domain Price, rejecting any payload with a price outside the open unit interval.
Source
Thrown at crates/adapters/polymarket/src/websocket/dispatch.rs:1475
liquidity_side: LiquiditySide,
ts_event: UnixNanos,
ts_init: UnixNanos,
) -> anyhow::Result<FillReport> {
let venue_order_id = VenueOrderId::from(trade.taker_order_id.as_str());
let trade_id = TradeId::from(trade.id.as_str());
let order_side = determine_order_side(
trade.trader_side,
trade.side,
trade.asset_id.as_str(),
trade.asset_id.as_str(),
);
let size_precision = instrument.size_precision();
let price_precision = instrument.price_precision();
let size_dec = parse_decimal_exact(&trade.size)?;
let price_dec = parse_decimal_exact(&trade.price)?;
anyhow::ensure!(size_dec > Decimal::ZERO, "trade quantity must be positive");
anyhow::ensure!(
price_dec > Decimal::ZERO && price_dec < Decimal::ONE,
"trade price must be in (0, 1)"
);
let last_qty = Quantity::from_decimal_dp(size_dec, size_precision)?;
let last_px = Price::from_decimal_dp(price_dec, price_precision)?;
let fee_rate = instrument_taker_fee(instrument);
let commission_value = compute_commission(
fee_rate,
instrument_fee_exponent(instrument)?,
size_dec,
price_dec,
liquidity_side,
)?;
let pusd = crate::execution::get_pusd_currency();
Ok(FillReport {
account_id,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the raw payload price — if it is quoted in cents (0–100), convert to probability by dividing by 100 before dispatch
- Decide whether settlement prices of exactly 0 or 1 are legitimate for your market and relax the bound accordingly
- Check for Polymarket schema changes and update the adapter
- Filter the message and continue if out-of-range prints are expected at market resolution
Example fix
// before: strict open-interval check rejects settlement prints
anyhow::ensure!(
price_dec > Decimal::ONE.zero() && price_dec < Decimal::ONE,
"trade price must be in (0, 1)"
);
// after: accept resolved-market extremes
anyhow::ensure!(
price_dec >= Decimal::ZERO && price_dec <= Decimal::ONE,
"trade price must be in [0, 1]"
); Defensive patterns
Strategy: validation
Validate before calling
let price_dec = parse_decimal_exact(&trade.price)?;
if price_dec <= Decimal::ZERO || price_dec >= Decimal::ONE {
log::warn!("skipping trade with out-of-range price {}", trade.price);
return Ok(None);
} Type guard
fn is_valid_probability_price(raw: &str) -> bool {
parse_decimal_exact(raw)
.map(|d| d > Decimal::ZERO && d < Decimal::ONE)
.unwrap_or(false)
} Prevention
- Remember Polymarket prices are probabilities in (0,1), not cents
- Convert cent-quoted feeds (divide by 100) before dispatch
- Decide on settlement-price (0/1) handling policy up front
When it happens
Trigger: Processing a polymarket trade message whose `price` field parses to <= 0 or >= 1 — e.g. "1.0", "0", "1.5", or a price accidentally quoted in cents (e.g. "54" instead of "0.54").
Common situations: A venue feed switching to a different price convention (cents vs probability); settlement trades at exactly 1.0 or 0.0; malformed messages during resolution/market close events.
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
- RTDS TWAP topic {:?} requires window_s={}, received {}
- {field} {value} must be greater than zero and less than one
- order price must be in (0, 1)
- invalid order quantity
- trade quantity must be positive
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6e11b8a4fdd7c919.
Report an issue: GitHub.