{"record":{"id":"263542ce1407bc93","repo":"nautechsystems/nautilus_trader","slug":"liquidity-side-not-set-263542","errorCode":null,"errorMessage":"Liquidity side not set","messagePattern":"Liquidity side not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/models/fee.rs","lineNumber":411,"sourceCode":"        skip_from_py_object\n    )\n)]\npub struct MakerTakerFeeModel;\n\nimpl FeeModel for MakerTakerFeeModel {\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        let notional =\n            instrument.try_calculate_notional_value(fill_quantity, fill_px, Some(false))?;\n        let 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        let commission = mul_checked(notional.as_decimal(), rate)?;\n\n        Money::from_decimal(commission, notional.currency).map_err(Into::into)\n    }\n}\n\n/// Fee model for probability-priced outcome shares.\n///\n/// Applies `qty * fee_rate * p * (1 - p)` using the instrument's maker or\n/// taker fee rate. This matches venues that represent outcome shares as\n/// [`InstrumentAny::BinaryOption`] instruments quoted on a `[0, 1]`\n/// probability scale.\n///\n/// This model covers quote-currency match-time exchange fees only.\n/// Venue-specific rebate programs or non-quote fee assets remain outside the\n/// core execution layer.\n#[derive(Debug, Clone)]","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/models/fee.rs#L393-L429","documentation":"MakerTakerFeeModel::get_commission computes the fee rate by matching the order's liquidity_side. If the order has `NoLiquiditySide` or `None`, no maker/taker rate can be selected, so the call fails with 'Liquidity side not set'. The model requires the venue/emulator to have stamped the liquidity side on the order before fee calculation.","triggerScenarios":"Calling get_commission with an order whose `liquidity_side()` is None or NoLiquiditySide — typically an order filled outside the normal matching pipeline (simulated fills, custom fill models, or fees computed before the fill report sets the side).","commonSituations":"Backtesting with a custom FillModel that doesn't set liquidity_side; calculating fees on unfilled or partially processed orders; venue adapter not populating liquidity side on fill reports.","solutions":["Ensure the fill/execution report sets `liquidity_side` (Maker/Taker) before fee calculation","In custom fill models or simulators, call set liquidity side explicitly when generating fills","If the side is genuinely unknown, skip maker/taker fee modeling and use a fixed-fee model instead"],"exampleFix":"// before\nlet fee = maker_taker_model.get_commission(&order, qty, px, &instrument)?; // liquidity_side None\n// after\norder.set_liquidity_side(LiquiditySide::Taker);\nlet fee = maker_taker_model.get_commission(&order, qty, px, &instrument)?;","handlingStrategy":"type-guard","validationCode":"if !matches!(order.liquidity_side(), Some(LiquiditySide::Maker) | Some(LiquiditySide::Taker)) {\n    // set the side or use a fallback fee model before calling get_commission\n}","typeGuard":"fn has_liquidity_side(order: &OrderAny) -> bool {\n    matches!(order.liquidity_side(), Some(LiquiditySide::Maker) | Some(LiquiditySide::Taker))\n}","tryCatchPattern":"match model.get_commission(&order, qty, px, &instrument) {\n    Ok(fee) => fee,\n    Err(e) if e.to_string().contains(\"Liquidity side not set\") => fallback_fixed_fee(),\n    Err(e) => return Err(e),\n}","preventionTips":["Ensure fill models and venue adapters always stamp liquidity_side on fills","Add an assertion after fill generation in custom simulators","Verify live venue fill reports include liquidity flags"],"tags":["rust","fee-model","liquidity-side","order-state"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}