{"record":{"id":"921b0940cf5eb8b3","repo":"nautechsystems/nautilus_trader","slug":"market-book-price-must-be-in-0-1","errorCode":null,"errorMessage":"market-book price must be in (0, 1)","messagePattern":"market-book price must be in \\(0, 1\\)","errorType":"validation","errorClass":"InvalidMarketPriceError","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/parse.rs","lineNumber":759,"sourceCode":"/// Returns the crossing price and expected base quantity. If insufficient liquidity,\n/// uses all available levels. If the book side is empty, returns an error.\npub fn calculate_market_price(\n    book_levels: &[ClobBookLevel],\n    amount: Decimal,\n    side: PolymarketOrderSide,\n) -> anyhow::Result<MarketPriceResult> {\n    if book_levels.is_empty() {\n        anyhow::bail!(\"Empty order book: no liquidity available for market order\");\n    }\n\n    // Parse and sort levels deterministically so we never depend on API ordering.\n    // BUY: asks ascending (best/lowest first). SELL: bids descending (best/highest first).\n    anyhow::ensure!(amount > Decimal::ZERO, \"market amount must be positive\");\n    let mut parsed_levels = Vec::with_capacity(book_levels.len());\n    for level in book_levels {\n        let price = parse_decimal_exact(&level.price).context(\"invalid market-book price\")?;\n        let size = parse_decimal_exact(&level.size).context(\"invalid market-book size\")?;\n        anyhow::ensure!(\n            price > Decimal::ZERO && price < Decimal::ONE,\n            InvalidMarketPriceError(\"market-book price must be in (0, 1)\".to_string())\n        );\n        anyhow::ensure!(\n            size >= Decimal::ZERO,\n            \"market-book size must be non-negative\"\n        );\n\n        if !size.is_zero() {\n            parsed_levels.push((price, size));\n        }\n    }\n\n    if parsed_levels.is_empty() {\n        anyhow::bail!(\"Empty order book: no valid price levels for market order\");\n    }\n\n    match side {","sourceCodeStart":741,"sourceCodeEnd":777,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/parse.rs#L741-L777","documentation":"While parsing order-book levels for a market order, calculate_market_price requires each level price to be strictly between 0 and 1, since Polymarket outcome prices are probabilities and 0/1 (or beyond) represent resolved or corrupt data. Offending levels raise this InvalidMarketPriceError. This protects the crossing-price walk from dividing/multiplying with nonsensical prices.","triggerScenarios":"A market book fetch (via bench_submit_market) returns a level with price <= 0 or >= 1 — e.g. a resolved market stuck at 1.0, a stale/corrupt snapshot, or a price expressed in cents (55 instead of 0.55).","commonSituations":"Querying a book for a market that has just resolved (prices pinned at 0 or 1); a venue API change in price scaling; deserialization glitches returning placeholder values.","solutions":["Check the market's active/resolved status before submitting market orders; skip resolved markets.","Inspect the offending level price in the API response and confirm the expected 0–1 scale.","Filter or reject book snapshots containing out-of-range levels before calling calculate_market_price."],"exampleFix":"// before\nlet res = calculate_market_price(&levels, amount, side, precision)?;\n// after\nlet clean: Vec<_> = levels.into_iter().filter(|l| {\n    let p = Decimal::from_str(&l.price).unwrap();\n    p > Decimal::ZERO && p < Decimal::ONE\n}).collect();\nlet res = calculate_market_price(&clean, amount, side, precision)?;","handlingStrategy":"validation","validationCode":"let ok = levels.iter().all(|l| {\n    let p = Decimal::from_str(&l.price).unwrap_or_default();\n    p > Decimal::ZERO && p < Decimal::ONE\n});\nif !ok { return Err(anyhow!(\"book contains out-of-range prices\")); }","typeGuard":"fn is_valid_book_level(l: &Level) -> bool {\n    Decimal::from_str(&l.price).map(|p| p > Decimal::ZERO && p < Decimal::ONE).unwrap_or(false)\n}","tryCatchPattern":"match calculate_market_price(&levels, amount, side, precision) {\n    Ok(r) => submit(r),\n    Err(e) if e.to_string().contains(\"market-book price\") => { log::warn!(\"invalid book: {e}\"); refresh_book_and_retry_later(); }\n    Err(e) => return Err(e),\n}","preventionTips":["Check market active/resolved status before trading","Refetch the book snapshot when invalid levels are seen","Assert price scaling in feed ingestion tests"],"tags":["rust","order-book","market-order","polymarket"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}