{"record":{"id":"81bf9a6f72ceafec","repo":"nautechsystems/nautilus_trader","slug":"probabilitypricefeemodel-requires-a-fill-price-in","errorCode":null,"errorMessage":"ProbabilityPriceFeeModel requires a fill price in [0, 1]","messagePattern":"ProbabilityPriceFeeModel requires a fill price in \\[0, 1\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/models/fee.rs","lineNumber":458,"sourceCode":"    )\n)]\npub struct ProbabilityPriceFeeModel;\n\nimpl FeeModel for ProbabilityPriceFeeModel {\n    fn get_commission(\n        &self,\n        order: &OrderAny,\n        fill_quantity: Quantity,\n        fill_px: Price,\n        instrument: &InstrumentAny,\n    ) -> anyhow::Result<Money> {\n        if !matches!(instrument, InstrumentAny::BinaryOption(_)) {\n            anyhow::bail!(\"ProbabilityPriceFeeModel requires a binary option instrument\");\n        }\n\n        let fill_price = fill_px.as_decimal();\n        if !(Decimal::ZERO..=Decimal::ONE).contains(&fill_price) {\n            anyhow::bail!(\"ProbabilityPriceFeeModel requires a fill price in [0, 1]\");\n        }\n\n        let fee_rate = match order.liquidity_side() {\n            Some(LiquiditySide::Maker) => instrument.maker_fee(),\n            Some(LiquiditySide::Taker) => instrument.taker_fee(),\n            Some(LiquiditySide::NoLiquiditySide) | None => anyhow::bail!(\"Liquidity side not set\"),\n        };\n\n        let one_minus_p = Decimal::ONE - fill_price;\n        let commission = mul_checked(fill_quantity.as_decimal(), fee_rate)\n            .and_then(|v| mul_checked(v, fill_price))\n            .and_then(|v| mul_checked(v, one_minus_p))\n            .map(|v| v.round_dp(5))?;\n\n        Money::from_decimal(commission, instrument.quote_currency()).map_err(Into::into)\n    }\n}\n","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/models/fee.rs#L440-L476","documentation":"ProbabilityPriceFeeModel treats the fill price as a probability, so it must lie within [0, 1]. get_commission validates the fill_px decimal against the inclusive range ZERO..=ONE and bails if it is outside, because fee math (fill_price * (1 - fill_price)) is only valid for probabilities.","triggerScenarios":"Calling get_commission with a fill_px whose decimal value is < 0 or > 1, e.g. a Price expressed in whole currency units (like 55.50) rather than 0..1 probability units, or a mis-scaled price.","commonSituations":"Feeding a regular asset price into the binary-option fee model; price precision/increment config that scales binary option prices outside [0,1]; unit mismatch between venue pricing and internal Price representation.","solutions":["Pass binary-option fill prices normalized to the [0, 1] probability range","Check the instrument's price_precision/price_increment so prices are parsed at the correct scale","Verify the fill Price was constructed from the venue's probability quote, not a converted cash price"],"exampleFix":"// before\nlet px = Price::new(55.50, 2); // invalid probability\nlet fee = model.get_commission(&order, qty, px, &instrument)?;\n// after\nlet px = Price::new(0.555, 3); // probability in [0, 1]\nassert!((Decimal::ZERO..=Decimal::ONE).contains(&px.as_decimal()));\nlet fee = model.get_commission(&order, qty, px, &instrument)?;","handlingStrategy":"validation","validationCode":"let d = fill_px.as_decimal();\nif !(Decimal::ZERO..=Decimal::ONE).contains(&d) {\n    return Err(anyhow::anyhow!(\"fill price {} not in [0,1]\", d));\n}","typeGuard":"fn is_probability_price(px: &Price) -> bool {\n    (Decimal::ZERO..=Decimal::ONE).contains(&px.as_decimal())\n}","tryCatchPattern":"let fee = model.get_commission(&order, qty, px, &instrument)\n    .with_context(|| format!(\"prob-fee calc failed for px={px}\"))?;","preventionTips":["Confirm binary-option price_precision/increment keep quotes in [0,1]","Sanity-check fill prices against the instrument's price range before fee calc","Don't route non-binary asset prices through the probability fee model"],"tags":["rust","fee-model","binary-option","value-out-of-range"],"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"}