{"record":{"id":"7dc3195aa12eea0a","repo":"nautechsystems/nautilus_trader","slug":"fee-price-must-be-in-0-1","errorCode":null,"errorMessage":"fee price must be in [0, 1]","messagePattern":"fee price must be in \\[0, 1\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/parse.rs","lineNumber":616,"sourceCode":"        return Ok(Decimal::ZERO);\n    }\n    let commission = size\n        .checked_mul(rate)\n        .context(\"commission calculation overflow\")?;\n    Ok(commission.round_dp(5))\n}\n\nfn fee_curve_rate(\n    fee_rate: Decimal,\n    price: Decimal,\n    fee_exponent: Decimal,\n) -> anyhow::Result<Decimal> {\n    anyhow::ensure!(fee_rate >= Decimal::ZERO, \"fee rate must be non-negative\");\n    anyhow::ensure!(\n        fee_exponent >= Decimal::ZERO,\n        \"fee exponent must be non-negative\"\n    );\n    anyhow::ensure!(\n        (Decimal::ZERO..=Decimal::ONE).contains(&price),\n        \"fee price must be in [0, 1]\"\n    );\n\n    if fee_rate.is_zero() {\n        return Ok(Decimal::ZERO);\n    }\n    let base = price * (Decimal::ONE - price);\n    let base_f64: f64 = base\n        .try_into()\n        .context(\"fee curve base is not representable\")?;\n    let exponent_f64: f64 = fee_exponent\n        .try_into()\n        .context(\"fee exponent is not representable\")?;\n    let curve =\n        Decimal::try_from(base_f64.powf(exponent_f64)).context(\"fee curve is not representable\")?;\n    fee_rate\n        .checked_mul(curve)","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/parse.rs#L598-L634","documentation":"fee_curve_rate requires price to be in the inclusive range [0, 1], since Polymarket binary-outcome prices are probabilities. A price outside that range (e.g. 1.5 or a percentage like 55 instead of 0.55) makes the fee curve meaningless and is rejected.","triggerScenarios":"Calling compute_commission or adjust_market_buy_amount with a price outside [0, 1] — most commonly a percentage-scale price (e.g. 55.0) or a raw price > 1 from a mis-scaled feed.","commonSituations":"Unit confusion between percentage points and probability fractions; a venue feed returning cents (e.g. 55) instead of the 0–1 decimal; stale test fixtures with wrong scaling.","solutions":["Convert the price to the 0–1 decimal scale (divide percentages by 100) before calling compute_commission.","Verify the price feed value actually came from the market book and is not scaled in cents.","Add a pre-call range check so out-of-range prices are caught and logged upstream."],"exampleFix":"// before\nlet price = Decimal::from_str(\"55.0\")?; // percentage\nlet fee = compute_commission(fee_rate, price, fee_exponent)?;\n// after\nlet price = Decimal::from_str(\"0.55\")?; // probability scale\nlet fee = compute_commission(fee_rate, price, fee_exponent)?;","handlingStrategy":"validation","validationCode":"if !(Decimal::ZERO..=Decimal::ONE).contains(&price) { return Err(anyhow!(\"price out of [0,1]: {price}\")); }","typeGuard":"fn is_probability(p: Decimal) -> bool { p >= Decimal::ZERO && p <= Decimal::ONE }","tryCatchPattern":null,"preventionTips":["Convert percentage-scale inputs to fractions at ingestion","Assert 0–1 scale in feed/fixture tests"],"tags":["rust","validation","fees","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"}