v1.226.0

Liquid4All/cookbookv1.226.0Apr 29, 2026by github-actions[bot]

AI Summary

NautilusTrader 1.226.0 Beta introduces new exchange integrations including Coinbase and Interactive Brokers, along with significant enhancements to the data engine, margin account management, and WebSocket transport capabilities. This release also consolidates configuration patterns and migrates the Polymarket adapter to CLOB V2.

Key Highlights

  • Added Coinbase initial integration adapter (Rust) and Interactive Brokers Rust adapter with PyO3 compatibility.
  • Enhanced data engine with instrument status caching and new portfolio queries (`mark_values`, `equity`).
  • Improved margin account management with new helpers for cross-margin queries and ADL/liquidation detection.
  • Added `sockudo` transport feature and proxy support for WebSocket connections.

Breaking Changes

  • Migrated Polymarket adapter to CLOB V2, changing order fields and collateral currency.
  • Removed `new()` constructors from multiple config structs (DataEngineConfig, ExecutionEngineConfig, etc.) in favor of `builder()` patterns.
  • Replaced `is_sandbox: bool` with `environment: AxEnvironment` enum on various client configs.
  • Consolidated adapter proxy plumbing into a single `proxy_url` field.
  • Changed `MarginBalance.instrument_id` to optional, affecting how margin entries are keyed.

New Features

  • Added `calculate_commission` to `ExecutionClient` for venue-specific reconciliation.
  • Added `MarginAccount.margin_for_currency` and helpers for summing margin buckets.
  • Added `WebSocketConfig.proxy_url` for HTTP CONNECT proxy tunneling with basic-auth.
  • Added Hyperliquid historical funding rates and configurable MARK slippage.
  • Added OKX option greeks support for Black-Scholes and price-adjusted conventions.
  • Added Binance Futures `use_trade_lite` config for low-latency fills.

Full Release Notes

# NautilusTrader 1.226.0 Beta

Released on 29th April 2026 (UTC).

### Enhancements
- Added `Portfolio::mark_values`, `equity`, and `missing_price_instruments` queries for Rust and Python
- Added `instrument_status` / `instrument_statuses` cache queries and auto-caching in the data engine (#3858)
- Added `environment` enum config for BitMEX, Deribit, dYdX, Hyperliquid, and OKX adapters
- Added `BybitEnvironment` to `BybitDataClientConfig` and `BybitExecClientConfig`
- Added missing config values to `LiveExecEngineConfig` (#3841), thanks @Javdu10
- Added `calculate_commission` to `ExecutionClient` for venue-specific reconciliation fills
- Added PyO3 bindings for `DataEngineConfig`, `ExecutionEngineConfig`, and `OrderEmulatorConfig` so they can be constructed from Python
- Added `cache`, `msgbus`, `data_engine`, `exec_engine`, and `portfolio` keyword arguments to `BacktestEngineConfig` Python constructor
- Added `MarginAccount.margin_for_currency` + `margin_init/maint_for_currency` helpers for cross-margin queries
- Added `MarginAccount.total_margin_init(currency)` / `total_margin_maint(currency)` summing both margin buckets
- Added `MarginAccount.account_margins`, `account_margins_init/maint`, and `clear_account_margin` accessors
- Added `transport-sockudo` feature with `TransportBackend` runtime selector for the WebSocket transport (Rust)
- Added `TransportBackend` PyO3 enum and `WebSocketConfig.backend` kwarg for backend selection from Python
- Added custom upgrade-header support on the sockudo backend so adapters carry the same `User-Agent` and per-venue headers on both backends (#3932), thanks @sunlei
- Added `WebSocketConfig.proxy_url` for HTTP `CONNECT` proxy tunneling with basic-auth support
- Added Betfair tiered tick scheme to `BettingInstrument` for ladder-snapped pricing
- Added Binance Futures `use_trade_lite` config to opt into low-latency `TRADE_LITE` fills (Rust, default `False`)
- Added Binance `proxy_url` plumbing for market and user-data WS streams (#3937), thanks for reporting @huangqingchi
- Added Bybit user-related endpoints (#3894), thanks @sunlei
- Added Bybit `BybitPositionIdx` enum and `bybit_resolve_position_idx` PyO3 helper
- Added Coinbase initial integration adapter (Rust)
- Added `DydxNetwork` re-export on the `nautilus_trader.adapters.dydx` package
- Added Hyperliquid historical funding rates via `fundingHistory` info endpoint
- Added Hyperliquid configurable MARKET slippage (`market_order_slippage_bps`) with per-order override
- Added Hyperliquid `OrderBookDepth10` subscription backed by the `l2Book` feed
- Added Hyperliquid `nSigFigs` / `mantissa` L2 precision controls via `subscribe_params`
- Added Interactive Brokers Rust adapter with PyO3 compatibility layer (#3864), thanks @faysou
- Added Kraken xStocks tokenized asset support for spot market data, order submission, and futures instruments
- Added OKX option greeks support for both Black-Scholes and price-adjusted conventions on every tick
- Added OKX `params["greeks_convention"]` (string or list) to narrow option greeks subscriptions
- Added OKX `transport_backend` config to switch websockets between `Tungstenite` and `Sockudo` backends
- Added Polymarket game_id and fee_schedule to instrument info (#3811), thanks @Javdu10
- Added Polymarket batch `SubmitOrderList` via `POST /orders` for limit-order batches (Rust)
- Added Polymarket WebSocket `idle_timeout_ms` for zombie detection (#3908), thanks for reporting @camarigor
- Added Polymarket WebSocket `proxy_url` plumbing
- Added Polymarket `pUSD` collateral currency (`Currency::pUSD()` in Rust, `pUSD` in Python) for the CLOB V2 cutover
- Added configurable `compression` for Tardis Machine replay, defaulting to `zstd`
- Added `ExecutionReport::OrderWithFills` and `send_order_with_fills` emitter for bundled status + fill reconciliation
- Added ADL / liquidation detection and logging across Binance, Bybit, OKX, BitMEX, Hyperliquid, Deribit, and dYdX
- Added Binance Futures COIN-M `delivery_autoclose-` prefix recognition for expiring contract auto-close events
- Added Bybit `adlRankIndicator` warning log when an open position is ranked 4 or higher (next to deleverage)
- Added Hyperliquid liquidation metadata logging on fills and `userEvents.liquidation` routing
- Added Hyperliquid `Auto-Deleveraging` fill detection with warn logging on HTTP and WebSocket paths

### Breaking Changes
- Added `Option<&AccountId>` to Rust `Portfolio::unrealized_pnls`, `realized_pnls`, `total_pnls`; pass `None` to keep prior behavior
- Added `backend: TransportBackend` to `WebSocketConfig`; struct-literal callers must add the field (Rust)
- Added `proxy_url: Option<String>` to `WebSocketConfig`; struct-literal callers must add the field (Rust)
- Migrated Polymarket adapter to CLOB V2: new EIP-712 domain version `2`, new exchange contract addresses, `timestamp`/`metadata`/`builder` order fields replace `taker`/`nonce`/`feeRateBps`, and pUSD replaces USDC.e as collateral; the Python adapter now uses `py-clob-client-v2`
- Consolidated adapter HTTP and WebSocket proxy plumbing onto a single `proxy_url` field, replacing the prior `http_proxy_url` / `ws_proxy_url` split across adapter Rust and Python configs
- Removed `DockerizedIBGatewayConfig::from_env_or_defaults` (Rust); use the bon builder or `Default::default`, which still falls back to `TWS_USERNAME`/`TWS_PASSWORD`
- Removed `OrderMatchingEngineConfig::new` and `with_price_protection_points` (Rust); use `OrderMatchingEngineConfig::builder()` instead
- Removed `BlockchainDataClientConfig::new`, `BlockchainExecutionClientConfig::new`, and `DexPoolFilters::new` (Rust); use the corresponding `::builder()` instead
- Removed `DeribitExecClientConfig::new` and `HyperliquidExecClientConfig::new` convenience constructors (Rust); use the `::builder()` instead
- Removed `DataEngineConfig::new` 12-arg positional constructor (Rust); use `DataEngineConfig::builder()` instead
- Removed synthetic `ACCOUNT-*` placeholders from margin adapters; `MarginBalance` emits with currency only
- Removed `nautilus_system::factories` module; import factory traits from `nautilus_common::factories` (Rust)
- Removed `indicators` from `nautilus-common` default features; enable with `features = ["indicators"]` (Rust)
- Renamed Python `DatabaseConfig.timeout` to `connection_timeout` and `response_timeout` to match the Redis/PyO3 wire schema
- Replaced `is_sandbox: bool` with `environment: AxEnvironment` on `AxDataClientConfig` and `AxExecClientConfig` (Rust and Python), aligning with the Binance/Bybit/Kraken adapter pattern. Default is `Sandbox`.
- Changed `BacktestEngine::add_venue` and `SimulatedExchange::new` (Rust) to take `SimulatedVenueConfig` (bon builder)
- Changed Interactive Brokers Rust configs to use bon builders: `InteractiveBrokersDataClientConfig`, `InteractiveBrokersExecClientConfig`, `InteractiveBrokersInstrumentProviderConfig`, and `DockerizedIBGatewayConfig`
- Changed `get_cached_bybit_http_client` signature: replaced `demo`/`testnet` bools with `environment: BybitEnvironment`
- Changed `UnsubscribeBookSnapshots` to require `interval_ms` for exact snapshot interval unsubscribe (Rust)
- Changed `OrderError::Invariant` variant to wrap `CorrectnessError` instead of `anyhow::Error` (Rust)
- Changed `HyperliquidEip712Signer::new()` to return `Result` and take `&EvmPrivateKey` (Rust)
- Changed `HyperliquidExchangeRequest::new/with_vault` to accept `HyperliquidSignature` directly (Rust)
- Changed Binance USD-M Futures WebSocket URLs from `/ws` to `/market/ws` and `/private/ws`
- Changed Cap'n Proto and SBE wire formats to preserve `Option` state (unstable, may change)
- Changed Python and Serde-backed Rust config decoding to reject unknown fields, so stale or misspelled keys now fail fast during config parsing
- Changed `MarginBalance.instrument_id` to optional; `None` marks account-wide (cross margin) entries keyed by currency
- Changed `MarginAccount.margins_init`/`margins_maint` to per-instrument only; use `account_margins_*` for cross margin
- Changed Binance Futures COIN-M to emit one `MarginBalance` per base coin (previously hardcoded USDT)
- Changed matching-engine `TradeId` format to `T-{hash}-{count}` from `{venue}-{raw_id}-{count}`; `ts_init`-keyed
- Changed `use_random_ids` to no longer govern `TradeId`; flag still affects `VenueOrderId` and `PositionId`
- Changed workspace `nautilus-live` to `default-features = false`; enable `features = ["node"]` for `LiveNode` (Rust)
- Changed adapter `LiveNode` examples to require `--features examples` to build (Rust)
- Changed `ParquetDataCatalog::to_object_path` and `to_object_path_parsed` to return `anyhow::Result` so cross-store URIs surface as errors instead of silently rewriting against the catalog bucket (Rust)
- Changed prefixed remote catalogs (`s3://bucket/base/path`, etc.) to read and write under their declared URI prefix; data previously written to the bucket root by the prior buggy behavior will not be discovered after upgrading and must be moved into the prefix (#3930)

### Security
- Hardened Binance Ed25519 credential detection so base64 HMAC secrets no longer pass as Ed25519 keys (Rust)
- Hardened Binance HTTP request signing by URL-encoding Ed25519 signatures in query strings (Rust)
- Replaced the third-party `urlencoding` crate with the in-tree `nautilus_core::urlencoding` to shrink the supply-chain surface (Rust)
- Bumped pinned SHAs for security-relevant GitHub Actions (`harden-runner`, `codeql-action`, `setup-uv`, `setup-rust-toolchain`) to current upstream releases
- Refreshed `cargo-deny` and `osv-scanner` advisory configuration; removed the stale `pygments` advisory ignore now that upstream is patched

### Fixes
- Fixed sockudo WebSocket backend dropping handshake leftover bytes when the server piggybacks the first frame on the 101 response (#3932), thanks @sunlei
- Fixed account state regeneration dropping account-wide margins on every fill across live and backtest paths
- Fixed `AccountState` to accept empty `balances` and `margins`
- Fixed `FillModel` determinism via `IndexMap` in `OrderMatchingEngine` (#3914), thanks for reporting @timkoopmans
- Fixed quote midpoint raw arithmetic across precision modes (#3849), thanks @BurnOutTrader
- Fixed `quote_quantity` propagation in execution algorithm spawn orders (#3845), thanks @dxwil
- Fixed streaming backtest shutdown determinism on `FORCE_STOP` (#3920)
- Fixed `mark_values`/`equity` keying by base currency when conversion is off; now keys by settlement currency
- Fixed `PortfolioAnalyzer` AttributeError on `MaxDrawdown`/`CAGR`/`CalmarRatio` (#3941), thanks for reporting @a1zb2yc3z
- Fixed `stop_timer` in `TimeBarAggregator` (#3822), thanks @faysou
- Fixed `RiskEngine` applying base `min_quantity`/`max_quantity` bounds to quote-denominated orders
- Fixed backtest `OrderMatchingEngine` treating `quote_quantity=True` orders as base quantity; the quote notional is now converted to a base quantity before fill simulation (#3873), thanks for reporting @fedoraiver
- Fixed `subscribe_option_chain` hanging on bootstrap in backtest (#3938), thanks for reporting @aaurix
- Fixed backtest option expiry fills missing from cache and fills report (#3939), thanks for reporting @hotelmike
- Fixed backtest physical option assignment closing the option leg at the opening premium (#3948), thanks for reporting @hotelmike
- Fixed `DataBackendSession` GIL deadlock when streaming custom data types (#3847), thanks for reporting @GianC0
- Fixed `BacktestNode` streaming with mixed built-in and custom data types (#3853), thanks for reporting @GianC0
- Fixed `DataBackendSession` chunked streaming memory leak causing RSS growth (#3889), thanks for reporting @GianC0
- Fixed book snapshot subscriptions to preserve exact `(instrument_id, interval_ms)` semantics for shared intervals and exact unsubscribe handling (Rust) (#3823), thanks for reporting @dwolfesberger
- Fixed WebSocket auth state during reconnection for Bybit, OKX, and Deribit (#3820), thanks for reporting @KaizynX
- Fixed WebSocket `idle_timeout_ms` reset on `Ping`/`Pong` keep-alive frames (#3907), thanks for reporting @camarigor
- Fixed `TradingNodeConfig.parse` dropping importable live client config `path` and `factory` fields during raw config decoding
- Fixed `OrderTriggered` ValueError on market-style stop orders (#3812), thanks for reporting @jindrichsirucek
- Fixed `consolidate_data_by_period` pairwise merging on fragment-per-flush catalogs (#3857), thanks for reporting @M-Advis
- Fixed `consolidate_data_by_period` destroying data on repeat runs and when straddling files spanned the consolidation window, mirrored in the Rust catalog backend (#3883), thanks @M-Advis
- Fixed `ParquetDataCatalog.get_intervals(identifier=None)` on per-identifier data (#3903), thanks for reporting @GianC0
- Fixed `ParquetDataCatalog.consolidate_data` raising `IndexError` when the start/end range did not overlap any files, and `consolidate_catalog_by_period` aborting the loop on the first unrecognized directory rather than skipping it (#3910), thanks for reporting @M-Advis
- Fixed remote catalog object paths under URI prefix so writes and reads under `s3://bucket/base/path` (and other remote schemes) no longer collapse to the bucket root (#3930), thanks @fedoraiver
- Fixed S3-backed custom data queries and remote Feather discovery (#3931), thanks for reporting @fedoraiver
- Fixed `FeatherWriter` writing 0-precision metadata on leading `CLEAR` delta (#3913), thanks for reporting @fedoraiver
- Fixed empty error log on `TradingNode` clean shutdown from `CancelledError` (#3862), thanks for reporting @jxstanford
- Fixed `Symbol` and `PositionId` deserialize of non-ASCII escaped strings (#3893), thanks for reporting @volemont
- Fixed execution engine ignoring user-supplied `position_id` from `submit_order` (Rust)
- Fixed `ExecutionEngine` leg-fill position events not publishing to subscribers (#3939)
- Fixed cache load not repairing OTO contingent child `position_id` after a partial fill-time crash (Rust)
- Fixed `TestDataGenerator.generate_trade_ticks` using random UUID4; now sequences deterministic `T-{idx}` IDs
- Fixed reconciliation IDs non-deterministic across restarts (#3878), thanks for reporting @peanut-copilot
- Fixed reconciliation synthetic `OrderStatusReport` now propagates fill price to `avg_px` for downstream inferred fills
- Fixed `reconcile_fill_report` dropping fills for unknown orders; now bootstraps external orders for venue closures
- Fixed PyO3 `InstrumentStatus` persistence and backtest streaming through `ParquetDataCatalog` (#3855)
- Fixed PyO3 `LiveNode` `request_bars()` historical callbacks dropped during startup warmup (#3825), thanks @BurnOutTrader
- Fixed PyO3 `DataActor` missing `on_historical_funding_rates` and `on_historical_data` forwarding `None`
- Fixed PyO3 crypto instrument `from_dict` for unregistered base/underlying codes (#3882), thanks for reporting @volemont
- Fixed PyO3 catalog `instruments()` failing on unregistered currencies (#3898), thanks for reporting @volemont
- Fixed PyO3 `from_dict` on non-ASCII strings via `ensure_ascii=False` in `json.dumps` (#3895), thanks @costajohnt
- Fixed Betfair event order: `Instrument` now emits before `InstrumentStatus`/`InstrumentClose` within each MCM
- Fixed Betfair scratched runners (`Removed`/`RemovedVacant`) emitting close only at market close; now fire immediately
- Fixed Betfair non-snapshot book deltas emitting inline; now tailed after trades/tickers to match Python semantics
- Fixed Betfair BSP deltas emitting before book deltas; now tailed after book deltas within each MCM
- Fixed Betfair order rejection reason dropping instruction-level `errorMessage` detail
- Fixed Betfair `query_order` to emit status reports via `customer_order_ref` and `bet_id` lookups (Rust)
- Fixed Binance user data stream not recovering after keepalive failure (#3861), thanks for reporting @KaizynX
- Fixed Binance Futures user data stream event loss during listen key rotation (#3861), thanks for reporting @KaizynX
- Fixed Binance Futures WebSocket trades by forcing `@aggTrade` (#3861), thanks for reporting @KaizynX
- Fixed Binance Futures exchange-generated fills losing real `trade_id` and `commission` by bundling status + fill
- Fixed Binance Ed25519 detector silently accepting base64 HMAC secrets as Ed25519 keys (Rust)
- Fixed Binance HTTP request Ed25519 signature URL-encoding in query strings (Rust)
- Fixed Binance Futures USD-M `cancel_all_orders` silently failing; routes through HTTP (WS API does not support it)
- Fixed Binance Futures `TRADE_LITE` user data events logging "Unknown event type" warnings on every fill
- Fixed Binance USD-M Futures WebSocket routing for `fstream-mm` and `fstream-auth` hosts
- Fixed BitMEX trade ID fallback using random UUID4 when `trdMatchID` missing; now hashed from trade fields
- Fixed Bybit demo mode websocket data URLs (#3742), thanks for reporting @jindrichsirucek
- Fixed Bybit position deserialization for closed positions (#3836), thanks for reporting @pusteckiy
- Fixed Bybit perpetual instrument status to emit `PreClose` when scheduled for delisting (#3829), thanks @dxwil
- Fixed Bybit `load_all_async` dropping `base_coin` filter for options (#3865), thanks for reporting @Baerenstein
- Fixed Bybit `InstrumentStatus` messages silently dropped instead of forwarded to the data engine
- Fixed Bybit and Deribit option chain example `subscribe_option_chain` call (#3887), thanks @sunlei
- Fixed Bybit margin missing for accounts with orders but no positions (#3725), thanks for reporting @marco-rigoni
- Fixed Bybit JSON pong websocket frames not being skipped before classification (#3936), thanks @sunlei
- Fixed Bybit hedge mode `positionIdx` rejection when `position_mode` set (#3944), thanks for reporting @pusteckiy
- Fixed Bybit execution client not applying configured leverage, position mode, or margin mode on connect (Rust)
- Fixed Databento CMBP1 and TCBBO trade IDs using random UUID4 instead of deterministic hash of trade fields
- Fixed Databento dropping `start_ns` after session start; now logs error (#3877), thanks for reporting @jxstanford
- Fixed Deribit mark/index price subscriptions silently dropping data in Python (#3821), thanks for reporting @linimin
- Fixed Deribit `StopMarket` `OrderRejected` on `market_price` price field (#3925), thanks for reporting @marco-rigoni
- Fixed dYdX `generate_order_status_report` fetching only the first order and missing later matches in the response
- Fixed dYdX orderbook snapshots missing `F_SNAPSHOT` flag on deltas; empty-book Clear now emits `F_SNAPSHOT | F_LAST`
- Fixed dYdX crossed-book resolution stripping `F_SNAPSHOT` from synthetic uncrossing deltas and the terminator
- Fixed dYdX trade-tick pagination dedup missing non-adjacent duplicates across page boundaries
- Fixed dYdX trade-tick pagination overshooting target `end` block from fixed block-time estimate
- Fixed dYdX crossed-book size arithmetic using `f64` subtraction; now uses `Decimal` at full precision
- Fixed dYdX position reports overriding venue `side` from `size` sign; venue side now preserved end-to-end
- Fixed dYdX `DydxAdapterConfig` defaulting to mainnet URLs regardless of `network`; added `for_network` helper
- Fixed Hyperliquid `LiveNode` bootstrap panic on HIP-3 instrument symbols containing `*`/`?` (e.g. `dex:STREAMABCD****-USD-PERP`) by substituting wildcard bytes with `x` in `InstrumentId.symbol` while preserving the venue-official name on `raw_symbol` (#3896), thanks for reporting @daiwanwei
- Fixed Hyperliquid bracket order submission grouping (#3810), thanks for reporting @jindrichsirucek
- Fixed Hyperliquid modify cancel-replace emitting stale `OrderCanceled` (#3827), thanks for reporting @P1YU5H-50N1
- Fixed Hyperliquid order status query for closed orders (#3879), thanks for reporting @pusteckiy
- Fixed Hyperliquid batch cancel silently dropping per-item errors (#3879), thanks for reporting @pusteckiy
- Fixed Hyperliquid Rust `query_order` handler to emit status reports (#3879), thanks for reporting @pusteckiy
- Fixed Hyperliquid `request_account_state` discarding parsed margins (#3725), thanks for reporting @marco-rigoni
- Fixed Hyperliquid `cancel_all_orders` dropping per-order rejection events on partial or transport failure
- Fixed Hyperliquid `request_trades` silently returning empty; now bails explicitly
- Fixed Hyperliquid `Auto-Deleveraging` fill direction deserialization (#3922), thanks for reporting @AlphaTraderK
- Fixed IB Gateway Docker image failing on ARM64 hosts (#3813), thanks for reporting @Baki-0501
- Fixed Interactive Brokers rejecting negative average fill price on combo/spread net-credit fills (#3884), thanks @faysou
- Fixed Interactive Brokers position reconciliation `TypeError` when `priceMagnifier` is `None` (#3885), thanks @davidsblom
- Fixed Kraken Futures limit order `OrderUpdated` panic from wire `stop_price: 0.0` treated as trigger price
- Fixed Kraken Futures fast-fill market orders resolving as rejected during order status reconciliation (#3870), thanks for reporting @Stamppot82
- Fixed Kraken Futures margin-account balance parse violating the `AccountBalance` invariant (`total == locked + free`) when Kraken's `af` field and the derived `amount - af` round independently at the currency precision
- Fixed Kraken Spot quote-quantity orders never reaching terminal state from base/quote size mismatch
- Fixed Kraken Spot ticker `QuoteTick.ts_event` using local init time instead of the exchange `timestamp` field (#3926), thanks @ptzafos
- Fixed Kraken trade dedup clearing the entire set at capacity instead of evicting the oldest entry
- Fixed Kraken Futures `AccountBalance` invariant panic on margin parse (#3868), thanks @Stamppot82
- Fixed Kraken Futures WebSocket re-authentication deadlock on reconnect (#3871), thanks for reporting @Stamppot82
- Fixed OKX option greeks not forwarded due to inaccessible Cython `cdef` subscription attribute
- Fixed OKX option greeks emitting `BlackScholes` convention regardless of subscribed greeks type
- Fixed OKX order identity registration race during concurrent order submission (Rust)
- Fixed OKX algo orders missing from order status reconciliation reports
- Fixed OKX spot margin position reconciliation preferring `CurrencyPair` with USDT/USDC/USD quote over alternatives
- Fixed OKX index-price subscription refcount leaking across reconnect and concurrent transitions
- Fixed OKX option summary subscription refcount not rolling back on subscribe failure
- Fixed OKX duplicate fills from empty `trade_id` using deterministic synthesized id instead of random UUID
- Fixed OKX panics on unmapped `OrderStatus` and empty `OptionType` values via `TryFrom` conversion (Rust)
- Fixed OKX `InstrumentStatus` messages logged as unhandled instead of forwarded to the data engine
- Fixed OKX `query_order` to emit status reports by merging regular and algo order lookups (Rust)
- Fixed Polymarket commission formula and fee source for fills (#3838), thanks for reporting @santivazq
- Fixed Polymarket reconciliation fills using incorrect commission (#3860), thanks for reporting @fedoraiver
- Fixed Polymarket instrument `min_quantity` denying market orders via limit-order shares rule (#3874), thanks for reporting @fedoraiver
- Fixed Polymarket `request_instrument(s)` dropping WS via stale `token_meta` (#3900), thanks for reporting @fedoraiver
- Fixed Polymarket `parse_to_quote_ticks` using changed level as top of book (#3905), thanks for reporting @camarigor
- Fixed Polymarket `parse_to_snapshot` missing `F_SNAPSHOT` flag on CLEAR and intermediate ADD deltas
- Fixed Polymarket `parse_to_deltas` flagging `F_LAST` on every delta instead of only the final one
- Fixed Polymarket `parse_to_trade_tick` using `uuid.uuid4()`, producing non-deterministic trade IDs
- Fixed Tardis replay handling of sparse `book_snapshot_*` levels (#3953), thanks for reporting @a1zb2yc3z
- Fixed Tardis trade ID fallback using random UUID4 when venue `id` missing/empty (CSV and WebSocket parsers)

### Internal Improvements
- Added `AccountBalance::from_total_and_locked` and `AccountBalance::from_total_and_free`, and migrated adapter balance parsing to preserve the `total == locked + free` invariant at currency precision (Rust)
- Added typed `CorrectnessError` enum to replace `anyhow::Error` in `correctness` helpers (Rust)
- Added `CorrectnessResultExt::expect_display` for display-formatted panics on typed correctness errors (Rust)
- Added deterministic simulation testing (DST) re-export module gated behind `simulation` feature (Rust)
- Added `wall_clock_now` seam in `nautilus-core` for virtual time under simulation (Rust)
- Added `biased` to `tokio::select!` blocks in network and live crates for deterministic poll order
- Added `nautilus_network::transport` module with `Message`/`TransportError`/`WsTransport` for future backend swap (Rust)
- Added neutral `Message`/`TransportError` re-exports on `nautilus_network` to ease future backend swaps (Rust)
- Added engine config methods on PyO3 `LiveNodeBuilder` (#3848), thanks @BurnOutTrader
- Added read-only `params()` accessor to `SubscribeCommand` and `TradingCommand` (#3846), thanks @faysou
- Added `ShutdownSystem` handling via `commands.system.shutdown` pub/sub topic, wired to kernel, backtest, and live (Rust)
- Added PyO3 `DataActor` parity with v1 for `publish_data`, `publish_signal`, `subscribe_signal`, `unsubscribe_signal`, `add_synthetic`, and `update_synthetic` (Rust)
- Added per-currency account-wide margin storage to `MarginAccount`, routing event margins by `instrument_id` presence
- Added Architect AX unit and integration tests for execution, request filters, and WebSocket parsers
- Added dYdX debug logging to `generate_order_status_report` showing filter scope and `page_full` on `None` results
- Added Polymarket `determine_trade_id` helper with FNV-1a (Rust) and blake2b (Python) deterministic hashing
- Added Hyperliquid criterion benchmarks for L1 signing path
- Added Hyperliquid integration tests for funding rates, trades, cancel-all, and `handle_l2_book` routing
- Added Hyperliquid `minTradeSpotNtlRejected` order status and `Unknown` liquidation method fallback
- Added Binance unit tests for spot/futures dispatch dedup, post-only rejection, and value conversions
- Added `derive_trade_id` FNV-1a helpers in BitMEX and Tardis common parse modules for deterministic fallback
- Added `derive_cmbp_trade_id` in Databento decode for schemas without a native trade ID
- Added property-based tests for Databento trade ID derivation (stability and 16-hex format)
- Added Rust/Python parity tests pinning matching-engine `TradeId` format across language bindings
- Added `node` feature to `nautilus-live` gating `builder`, `config`, `manager`, and `node` modules (default on)
- Added support for user-provided Tokio runtime in live module (#3918), thanks @filipmacek
- Added continuous futures support for bar requests and subscriptions (#3921), thanks @faysou
- Improved `nautilus-live/defi` to no longer pull `LiveNode` orchestration deps
- Improved CI uv cache via `setup-uv` auto mode to skip GHA uploads on self-hosted runners (#3933), thanks @sunlei
- Cleaned up unused dependencies (#3886), thanks @sunlei
- Improved CI cache hygiene on self-hosted runners with uv prune, prek auto-gate, and footprint summary
- Migrated `WebSocketClient` onto the `WsTransport` trait, decoupling reconnect/auth from tungstenite types (Rust)
- Changed Polymarket `PolymarketQuote.best_bid`/`best_ask` to optional, matching the Rust `Option<String>` schema
- Ported Interactive Brokers Rust historical bar replay with Python parity fixes (#3892), thanks @faysou
- Standardized adapter example manifests and trading deps (#3891), thanks @sunlei
- Standardized margin emission convention across live derivatives adapters to use currency-keyed `MarginBalance` entries
- Refactored `reconciliation` module into `types`, `ids`, `positions`, and `orders` submodules (Rust)
- Refactored Binance Futures user data stream dispatch and listen key recovery into dedicated modules (Rust)
- Refactored Binance Futures value conversions into a new `futures::conversions` module (Rust)
- Replaced `AHashMap`/`AHashSet` with `IndexMap`/`IndexSet` in `ExecutionManager` for deterministic ordering in simulations (Rust)
- Refined `nautilus-system` to optional in adapter crates (gated by `python`); default builds drop heavy transitive deps
- Refined DST convention hook to enforce `IndexMap` in `OrderMatchingEngine`
- Refined make cargo-test to not include binaries for test harness builds (#3828), thanks @faysou
- Refined Interactive Brokers combo fill average price calculation (#3834), thanks @faysou
- Refined Kraken WebSocket execution dispatch to emit typed events for tracked orders via per-product modules
- Refined Kraken Spot WS auth via `AuthTracker` with `is_authenticated`/`wait_until_authenticated` Python APIs
- Optimized Hyperliquid L1 signing by caching `PrivateKeySigner` and EIP-712 domain (#3851)
- Optimized `ClientOrderId` generation with cached prefix buffer (#3935), thanks @sunlei
- Optimized `OrderListId` and `PositionId` generation with cached prefix buffers (Rust)
- Upgraded Rust (MSRV) to 1.95.0
- Upgraded Cap'n Proto to v1.4.0
- Upgraded `alloy` crate to v2.0.1
- Upgraded `capnp` crate to v0.25.4 (regenerated schemas with 4-space indents and version headers)
- Upgraded `databento` crate to v0.48.0
- Upgraded `datafusion` crate to v53.1.0
- Upgraded `msgspec` to v0.21.1
- Upgraded `pyarrow` to v24.0.0
- Upgraded `tokio` crate to v1.52.1

### Documentation Updates
- Added Polymarket Python and Rust adapter config tables and updated rate limits
- Added ID determinism invariant to the reconciliation live and execution concept guides
- Added Trade ID derivation sections to Polymarket, Databento, BitMEX, and Tardis integration guides
- Added Trade ID derivation section to the backtesting concept guide
- Added "Equity and mark-to-market" section to the portfolio concept guide
- Added ADL / liquidation handling sections to the Binance, Bybit, OKX, BitMEX, Hyperliquid, Deribit, dYdX guides
- Added reconciliation reports section to the execution concept guide
- Refined docs to follow style guide for symbols and filler words (#3830), thanks @JKDasondee
- Refined Interactive Brokers documentation regarding UTC timestamps (#3826), thanks @faysou
- Refined dYdX integration guide config tables to match the Python API (`environment`, `subaccount`, `base_url_grpc`)
- Updated Hyperliquid integration guide with funding history, depth10, subscribe_params, and slippage
- Updated the configuration concept guide to define unknown-field rejection as the config standard in Python and Rust

### Deprecations
- Deprecated `demo`/`testnet` bools on `BybitDataClientConfig`/`BybitExecClientConfig` - use `environment`
- Deprecated `is_demo` on `OKXDataClientConfig`/`OKXExecClientConfig` - use `environment`
- Deprecated `testnet` on `HyperliquidDataClientConfig`/`HyperliquidExecClientConfig` - use `environment`
- Deprecated `is_testnet` on `DeribitDataClientConfig`/`DeribitExecClientConfig` - use `environment`
- Deprecated `is_testnet` on `DydxDataClientConfig`/`DydxExecClientConfig` - use `environment`
- Deprecated `testnet` on `BitmexDataClientConfig`/`BitmexExecClientConfig` - use `environment`