nautechsystems/nautilus_trader · error

Liquidity side not set

Error message

Liquidity side not set

What it means

Polymarket fee calculation distinguishes maker vs taker fees, so the order must have a liquidity side set. If order.liquidity_side() returns None or NoLiquiditySide, get_commission cannot select the correct fee rate and bails with 'Liquidity side not set'.

Source

Thrown at crates/adapters/polymarket/src/models.rs:68

pub struct PolymarketFeeModel;

impl FeeModel for PolymarketFeeModel {
    fn get_commission(
        &self,
        order: &OrderAny,
        fill_quantity: Quantity,
        fill_px: Price,
        instrument: &InstrumentAny,
    ) -> anyhow::Result<Money> {
        let InstrumentAny::BinaryOption(binary) = instrument else {
            anyhow::bail!("PolymarketFeeModel requires a binary option instrument");
        };

        let liquidity_side = match order.liquidity_side() {
            Some(LiquiditySide::Maker) => LiquiditySide::Maker,
            Some(LiquiditySide::Taker) => LiquiditySide::Taker,
            Some(LiquiditySide::NoLiquiditySide) | None => {
                anyhow::bail!("Liquidity side not set")
            }
        };

        let Some(schedule) = binary
            .info
            .as_ref()
            .and_then(|info| info.get("fee_schedule"))
            .map(|value| serde_json::from_value::<FeeSchedule>(value.clone()))
            .transpose()
            .context("invalid Polymarket fee schedule")?
        else {
            return Ok(Money::zero(instrument.quote_currency()));
        };

        validate_schedule(&schedule)?;

        let fill_price = fill_px.as_decimal();
        if !(Decimal::ZERO..=Decimal::ONE).contains(&fill_price) {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set order.liquidity_side (Maker or Taker) before requesting commission, typically from the fill/report event.
  2. Only call get_commission in response to fill events that carry a liquidity side.
  3. In tests/backtests, populate LiquiditySide explicitly when constructing fill events.
  4. Default to Taker in caller code when the side is genuinely unknown, if that matches your business rules.

Example fix

// before
let fee = fee_model.get_commission(&order, qty, px, &instrument)?;
// after
if order.liquidity_side().is_none_or(|s| s == LiquiditySide::NoLiquiditySide) {
    log::warn!("liquidity side missing; skipping fee calc");
    return Ok(Money::zero(instrument.quote_currency()));
}
let fee = fee_model.get_commission(&order, qty, px, &instrument)?;
Defensive patterns

Strategy: validation

Validate before calling

if order.liquidity_side().is_none_or(|s| s == LiquiditySide::NoLiquiditySide) {
    return Err("order has no liquidity side; cannot compute commission".into());
}

Type guard

fn has_liquidity_side(order: &OrderAny) -> bool {
    matches!(order.liquidity_side(), Some(LiquiditySide::Maker) | Some(LiquiditySide::Taker))
}

Try / catch

match fee_model.get_commission(&order, qty, px, &instrument) {
    Ok(fee) => fee,
    Err(e) if e.to_string() == "Liquidity side not set" => {
        log::warn!("fill without liquidity side; defaulting taker fee");
        compute_taker_fee_fallback(qty, px, &instrument)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Computing commission for an order whose liquidity side was never assigned — e.g. calling get_commission before the fill event stamped LiquiditySide, or manually constructed order fixtures without liquidity_side.

Common situations: Backtests/tests where OrderFilled events are synthesized without setting liquidity_side; fee preview calls on resting-but-unfilled orders; engine versions where NoLiquiditySide is the default.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/523899a6a4df0c2a. Report an issue: GitHub.