nautechsystems/nautilus_trader · error

Invalid parity transformed price for OwnOrderBook::combined_

Error message

Invalid parity transformed price for OwnOrderBook::combined_with_opposite

What it means

OwnOrderBook::combined_with_opposite transforms each order from the opposite book by mirroring it across the 0.5 price point: parity_price = 1 - price, computed via Price::from_decimal(Decimal::ONE - order.price.as_decimal()).expect(...). This panics when the parity result is invalid for a Price — i.e. when the original price is < 0 or > 1 (making 1-p negative or invalid), NaN, infinite, or violates Price precision. Own books for prediction/binary markets use prices in [0,1], and an out-of-range price violates that domain.

Source

Thrown at crates/model/src/orderbook/own.rs:556

        for client_order_id in asks_to_remove {
            log_audit_error(&client_order_id);
            if let Err(e) = self.asks.remove(&client_order_id) {
                log::error!("{e}");
            }
        }
    }
}

fn log_audit_error(client_order_id: &ClientOrderId) {
    log::error!(
        "Audit error - {client_order_id} absent from valid order IDs, deleting from own book"
    );
}

fn transform_opposite_order(order: OwnBookOrder, side: OrderSide) -> OwnBookOrder {
    let parity_price = Price::from_decimal(Decimal::ONE - order.price.as_decimal())
        .expect("Invalid parity transformed price for OwnOrderBook::combined_with_opposite");

    OwnBookOrder::new(
        order.trader_id,
        order.client_order_id,
        order.venue_order_id,
        side,
        parity_price,
        order.size,
        order.order_type,
        order.time_in_force,
        order.status,
        order.ts_last,
        order.ts_accepted,
        order.ts_submitted,
        order.ts_init,
    )
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify every OwnBookOrder price is within 0 <= p <= 1 before calling combined_with_opposite.
  2. Normalize probabilities at ingestion (clamp or reject values outside [0,1] with a clear error) when building the book.
  3. Check the persistence/serialization path for price corruption or unit changes (e.g. stored as percent or fixed-point raw).
  4. Skip and log offending orders instead of combining the whole book, while investigating the data source.
  5. If prices come from a model/strategy, add an assertion where they are produced to catch out-of-domain values early.

Example fix

// before
let combined = own_book.combined_with_opposite(other_book); // other_book has price 1.5
// after
for order in other_book.orders() {
    let p = order.price.as_decimal();
    assert!(p.is_finite() && p >= Decimal::ZERO && p <= Decimal::ONE,
        "own book price {p} outside [0,1]");
}
let combined = own_book.combined_with_opposite(other_book);
Defensive patterns

Strategy: validation

Validate before calling

fn in_parity_domain(p: &Price) -> bool {
    let d = p.as_decimal();
    d.is_finite() && d >= Decimal::ZERO && d <= Decimal::ONE
}
assert!(book.orders().iter().all(|o| in_parity_domain(&o.price)));

Type guard

fn is_probability_price(p: &Price) -> bool {
    let d = p.as_decimal();
    d.is_finite() && d >= Decimal::ZERO && d <= Decimal::ONE
}

Try / catch

// Validate [0,1] domain before combining; the expect panics otherwise. Python:
try:
    combined = own_book.combined_with_opposite(other)
except BaseException as e:
    log.warning("combined_with_opposite failed: %s", e)

Prevention

When it happens

Trigger: Calling combined_with_opposite when any OwnBookOrder in the opposite book has a price outside the [0,1] domain (or non-finite), so `1 - price` cannot be represented as a valid Price.

Common situations: Loading own-book state persisted with raw/out-of-range prices; a bug upstream that stored probabilities not normalized to [0,1]; NaN prices from external math; precision mismatch after Price type changes between versions.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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