Skip to content
All library documents

NautilusTrader Release Notes: Negative Prices and Trading Infrastructure

Article NautilusTrader

Summary

These release notes describe changes to NautilusTrader, a trading platform, including support for negative futures prices except for inverse futures and fixes to risk limits, commission signs, and order handling at negative prices. They also list a Databento feed enhancement for live bars, book depth, statistics, and imbalance subscriptions. A much longer section covering an earlier release describes changes to indicators, simulated execution, venue adapters, data catalogs, and order recovery.

The notes provide a software change log rather than a trading method or empirical strategy evaluation. They identify platform capabilities and corrections that can matter when building or operating trading systems, but do not show their effect on trading results. The supplied text is incomplete, mixing a release candidate with earlier historical notes and cutting off partway through a breaking-change list; its version details should therefore be read in that limited context.

Key ideas

  • The release candidate adds support for negative prices in most futures instruments.
  • Risk limits and maker/taker commission calculations were corrected for negative prices.
  • The notes describe new live market data subscriptions for bars, book depth, statistics, and imbalance data.
  • An earlier release section covers indicator, simulated execution, adapter, and data catalog changes.
  • The document is a partial software changelog and provides no evidence about strategy performance.

Tags

Full text
# NautilusTrader 2.0.0rc7


# NautilusTrader 2.0.0rc7

Released on TBD (UTC).

> [!NOTE]
> This release removes support for Python 3.12 and supports Python 3.13 and 3.14 (#4676).

### Enhancements

- Added `Clock.set_timer_zoned` and Rust `CalendarSchedule` for local calendar recurrence, thanks @faysou
- Added `time_bars_time_zone` and `time_zone` overrides for local calendar bars, thanks @faysou
- Added Rust candidate option IDs for supported CME Globex and OSI equity/index contracts, thanks @faysou
- Added reference instruments to `OptionSeriesId` with compatible derived-reference serialization, thanks @faysou
- Added `OptionSideFilter` and Rust `StrikeSearchProfile` model types for option selection, thanks @faysou
- Added tick scheme registration, thanks @faysou
- Added negative price support for futures, except inverse futures (#5190), thanks @DeLuke84
- Added `BacktestDataConfig.batch_deltas` for batched book delta replay (#5215), thanks for reporting @nicezic
- Added Bybit public liquidation custom data for linear and inverse contracts (#5152), thanks @Martingale42
- Added Databento live bars, book depth, statistics, and imbalance subscriptions (#5201), thanks @faysou
- Added Derive adapter support for API v3
- Added Interactive Brokers subscription idle events (#5041), thanks @faysou
- Added Lighter native transaction batching with automatic splitting for order lists and batch operations

### Breaking Changes

- Removed Rust `TickSchemeError::TickNotFinite`; remove this arm from tick error matches
- Removed Interactive Brokers connection wrappers; use `ibapi::Client` (#5041), thanks @faysou
- Removed Interactive Brokers `ErrorCategory` and `InteractiveBrokersErrorKind` exports (#5041), thanks @faysou
- Replaced Interactive Brokers Rust symbology functions with `Symbology` methods (#5041), thanks @faysou
- Changed Rust `PortfolioGreeks::from(GreeksData)` to apply the contract multiplier
- Changed Rust `VirtualTimer` and `LiveTimer` to store `interval: TimerInterval` instead of `interval_ns`;
  match `TimerInterval::Fixed` to read fixed intervals
- Changed Rust `DataEngineConfig` and `LiveDataEngineConfig` struct literals to require `time_bars_time_zone`;
  use `None` in existing struct literals to retain UTC alignment
- Changed Rust `TimeBarAggregator::new` to require `jiff::tz::TimeZone`; pass `TimeZone::UTC` for UTC bars
- Changed Rust `OptionSeriesId::new` to require a reference instrument; use `new_derived` to derive it
- Changed Rust `OptionSeriesId::from_expiry` and `from_expiry_ns`; pass `None` as the final argument to derive a reference
- Changed Rust `OptionSeriesId::from_crypto_option` and struct literals to require `underlying_instrument_id`
- Changed `OptionSeriesId` equality, hashing, and ordering to include the reference instrument
- Changed `OptionSeriesId` strings with fractional expiries, including topics and handler IDs, to retain nanoseconds
- Changed `OptionSeriesId` to reject empty or whitespace-only underlying symbols when deriving a reference
- Changed Rust `FixedTickScheme::new` to accept `Price`; use `Price::from("0.05")` instead of a float
- Changed Rust `FixedTickSchemeRounder::new` to accept `Price`; use `Price::from("0.05")` instead of a float
- Changed Rust `TickSchemeError::TickNotPositive.tick` to `Price` and added variants; update exhaustive matches
- Changed fixed tick navigation to return `None` for incompatible precision; choose one that represents the tick
- Changed `BacktestNode` to batch book deltas by default, so fills can differ; set `batch_deltas=False` to opt out
- Changed batched `BacktestNode` replay to reject deltas without a closing `F_LAST`; `batch_deltas=False` opts out
- Changed Rust `Order` to require `non_reopened_voided_qty` (#5133), thanks @abhijeetvichare76
- Changed Deribit position `leverage` to `Option<Decimal>` (#5240), thanks @abhijeetvichare76
- Changed Interactive Brokers contract and security filters to reject unknown values (#5041), thanks @faysou
- Changed Interactive Brokers Rust provider loaders; use `load_with_return_async` (#5041), thanks @faysou

### Security

- Fixed Interactive Brokers gateway passwords appearing in debug and serialized output (#5041), thanks @faysou

### Fixes

- Fixed portfolio Greeks panics when calculations, subscribers, or filters write to the cache
- Fixed portfolio Greeks omitting multipliers before filtering and aggregation, including futures
- Fixed missing Python Greeks conversion, scalar-left multiplication, and portfolio addition
- Fixed released emulated orders sending stale order initialization (#5169), thanks @jrile018
- Fixed monthly time bars drifting after a clamped month-end origin offset
- Fixed queued time-bar callbacks affecting aggregation after a stop or restart
- Fixed `RiskEngine` notional limits for negative prices
- Fixed maker/taker commission sign at negative prices
- Fixed cache open-order queries retaining submitted orders after cancel or modify rejections
- Fixed simulated OTO releases reviving children canceled earlier in the same callback
- Fixed simulated reduce-only quote-quantity stops converting their resized quantity again
- Fixed simulated released bracket exits canceled with partially filled entries (#5159), thanks @abhijeetvichare76
- Fixed `BacktestNode` streaming runs leaving the engine running after a data load failure
- Fixed Python indicator constructors aborting the process on invalid periods or oversized capacities
- Fixed reconciliation rejecting fills on a pending order when a `Filled` report exceeds its quantity
- Fixed replacement reconciliation losing native fill IDs and duplicating inferred fills
- Fixed calculated margin equity omitting option value (#5252), thanks for reporting @abhijeetvichare76
- Fixed streaming Parquet promotion failing on `OrderBookDelta.clear()` snapshots (#5268), thanks for reporting @hellow-star
- Fixed simulated bracket exits rejected as reduce-only before entry fills reached the cache (#5248), thanks @awss1i
- Fixed trailing stop prices falling between price increments (#5241), thanks @abhijeetvichare76
- Fixed cached custom currencies and their dependents missing after Redis restart (#5195), thanks @zhaow-de
- Fixed non-reopened voided quantity returning to working leaves after updates (#5133), thanks @abhijeetvichare76
- Fixed duplicate account states and incorrect locked margins during funding settlements (#5249), thanks @XBeg9
- Fixed `GreeksCalculator` underlying resolution across venues (#5234), thanks @awss1i
- Fixed cancel rejection delivery for active orders while preserving their state (#5270), thanks @riven314
- Fixed late modify rejection delivery for submitted orders without reverting amended terms
- Fixed Parquet catalog row order for equal `ts_init` timestamps (#5267), thanks @ragen1337
- Fixed Bybit stale WebSocket subscriptions blocking subscriptions after reconnect (#5250), thanks @Martingale42
- Fixed Bybit failed quote subscriptions retaining shared order book references (#5258), thanks @Martingale42
- Fixed Deribit position reports failing on fractional leverage (#5240), thanks @abhijeetvichare76
- Fixed Hyperliquid account updates retaining balances reported at zero (#5210), thanks @XBeg9
- Fixed Hyperliquid reduce-only filled order lookups overstating fill quantity (#5222), thanks @XBeg9
- Fixed Hyperliquid HIP-4 outcome price and size precision (#5266), thanks @vignesh-chaturvedi
- Fixed Hyperliquid canceled replacements leaving orders open when acceptance updates are missing
- Fixed Hyperliquid recovery sending corrective reductions for canceled replacement orders
- Fixed Hyperliquid dropping late fill reports after orders close
- Fixed Hyperliquid stop-market replacement updates causing order-state panics
- Fixed Interactive Brokers account balances and margins remaining stale after connect (#5041), thanks @faysou
- Fixed Interactive Brokers spread fills arriving before their leg fills (#5041), thanks @faysou
- Fixed Interactive Brokers execution queries replaying historical fills as live fills (#5041), thanks @faysou
- Fixed Kraken spot and futures wallets retaining balances reported at zero (#5186), thanks @zhaow-de
- Fixed Kraken futures margin currencies, aggregation, and maintenance requirements (#5199), thanks @zhaow-de
- Fixed Kraken futures reads silently omitting unresolved live orders and positions (#5217), thanks @zhaow-de
- Fixed Lighter `CancelAllOrders` to select cached orders only from the execution account
- Fixed Lighter batch cancel outcome recovery and overlapping cancellation rejection handling
- Fixed Lighter transaction nonce send ordering under concurrent preparation
- Fixed Polymarket bounded restarts marking cached closed orders as incomplete
- Fixed Polymarket bounded restarts omitting confirmed partial fills from resting orders
- Fixed Polymarket modify canceling a working order when the signed replacement is below the market minimum
- Fixed Polymarket free balance treating BUY fill spend as available before the venue collateral total reflects it
- Fixed Polymarket recovered BUY overfills being rejected instead of raising order quantity
- Fixed sandbox cached quote and trade replay replenishing consumed liquidity on order submissions

### Internal Improvements

- Added `BacktestNode` book delta replay benchmark comparing batched and individual dispatch
- Refined shared pointer cloning in infrastructure, CLI, and event store code (#5236), thanks @mirooon
- Refined Hyperliquid unified account tests to use JSON fixtures (#5220), thanks @XBeg9
- Ported the Interactive Brokers adapter to the `ibapi` v5.0.0 API (#5041), thanks @faysou
- Improved Kraken margin entry average and net-short test coverage (#5214), thanks @zhaow-de
- Improved Lighter report generation with HTTP collection on runtime workers (#5216)
- Optimized core string formatting, precision parsing, and API key masking allocations (#5225), thanks @sunlei
- Optimized core UTC timestamp formatting (#5226), thanks @sunlei
- Optimized hexadecimal encoding and decoding (#5227), thanks @sunlei
- Optimized integer `UnixNanos` parsing (#5228), thanks @sunlei
- Optimized JSON decimal deserialization to avoid temporary string allocations (#5229), thanks @sunlei
- Optimized `UUID4` byte conversion (#5230), thanks @sunlei
- Optimized portfolio snapshots to skip copying account event history (#5237), thanks @XBeg9
- Optimized backtest funding settlements to update positions in place (#5238), thanks @XBeg9
- Optimized Python `Portfolio` queries to avoid copying account event history (#5260), thanks @XBeg9
- Upgraded Rust (MSRV) to 1.99.0
- Upgraded `cargo-hawk` tool to v0.1.15
- Upgraded `prek` tool to v0.5.4
- Upgraded Socket CLI tool to v1.5.0
- Upgraded `uv` tool and pre-commit hook to v0.12.22
- Upgraded `typos` pre-commit hook to v1.51.1
- Upgraded `databento` crate to v0.63.0
- Upgraded `either` crate to v1.19.0
- Upgraded `h2` crate to v0.4.20
- Upgraded `hyper` crate to v1.12.0
- Upgraded `hyper-util` crate to v0.1.21
- Upgraded `ibapi` crate to v5.0.0 (#5041), thanks @faysou
- Upgraded `implied-vol` crate to v2.1.0
- Upgraded `jiff` crate to v0.2.38
- Upgraded `libc` crate to v0.2.190
- Upgraded `pyo3` crates to v0.29.3
- Upgraded `tokio` crate to v1.53.2
- Upgraded `tokio-rustls` crate to v0.26.6
- Upgraded `uuid` crate to v1.27.0
- Upgraded `zeroize` crate to v1.9.1
- Upgraded `ruff` package (dev) and pre-commit hook to v0.16.10
- Upgraded `simplejson` package (visualization) to v4.2.0
- Upgraded `ty` package (dev) to v0.0.84
- Upgraded `uvicorn` package (test) to v0.54.0
- Upgraded `uvloop` package (test) to v0.23.0

### Documentation Updates

- Clarified `Portfolio` equity rules for calculated and reported margin accounts
- Fixed Binance and Hyperliquid custom data examples to unwrap `CustomData` (#5246), thanks @Martingale42
- Updated Derive integration guide for API v3 setup, margin models, and recovery limits
- Clarified Kraken cached and external closing-order recovery (#5208), thanks @zhaow-de
- Clarified Lighter cancel-all scope and batch cancellation failure handling

### Deprecations

---

# NautilusTrader 2.0.0rc6

Released on 4th October 2026 (UTC).

### Enhancements

- Added `WebSocketConfig.max_message_size_bytes` and `max_frame_size_bytes` configurable inbound size limits
- Added configurable `writer_capacity` limits for socket and WebSocket clients, defaulting to 1,024 messages
- Added `NAUTILUS_HTTP2_ADAPTIVE_WINDOW` env var to restore adaptive HTTP/2 flow-control windows
- Added same-venue execution client registration with explicit venue or default routing
- Added Rust `Cache::account_id_for_client` to resolve execution client accounts independent of issuers
- Added Rust `Cache::client_id_for_venue` to resolve the execution client that venue or default routing selects
- Added Python `Cache.top_of_book()` without cloning the resident book (#5011), thanks @youayouly
- Added `RateOfChangeMode` for configurable ROC output units (#5144), thanks @faysou
- Added MACD `signal` and `histogram` outputs (#5144), thanks @faysou
- Added Bollinger Bands `stddev` output (#5144), thanks @faysou
- Added independent VIDYA `cmo_period` configuration (#5144), thanks @faysou
- Added Ichimoku per-line readiness flags (#5144), thanks @faysou
- Added fallible Rust moving-average constructors and Python parameter validation (#5144), thanks @faysou
- Added period-1 support to `EfficiencyRatio` (#5144), thanks @faysou
- Added aggregate instrument fan-out across class directories to `list_parquet_files`
- Added custom data support to `StreamingFeatherWriter` (#4759), thanks for reporting @mystic-io
- Added recovery of unsealed Feather stream files left by a crashed writer (#5115), thanks @faysou
- Added streaming promotion into a separate, optionally remote, `StreamingConfig.catalog` (#5115), thanks @faysou
- Added `timezone` to `RotationConfig.scheduled_dates`, defaulting to UTC (#5115), thanks @faysou
- Added shared-table `record/` and `instrument/` catalog paths for external catalog backends (#5115), thanks @faysou
- Added Parquet catalog migration through `nautilus catalog migrate-parquet` (#4959), thanks @faysou
- Added `type_name` inference to `migrate-parquet` for legacy custom catalogs
- Added typed `batch_size`, `compression`, and `max_row_group_size` to `DataCatalogConfig` (#5166), thanks @faysou
- Added `submission_recovery_policy` config for exhausted submission recovery (#5028), thanks @silarin
- Added a live submission registry and exhaustion diagnostics for unresolved submissions (#5036), thanks @silarin
- Added a startup reconciliation warning for fills dropped without an order report or cached order
- Added `events.order_fill_declined.{instrument_id}` topic republishing fills and voids the engine declines
- Added position report metadata for FIFO and truncated venue entry averages (#5064), thanks for reporting @zhaow-de
- Added live binary option position settlement from `InstrumentClose` (#4963), thanks for reporting @seungpyoson
- Added `deserialize_decimal_token` and `deserialize_optional_decimal_token` to `nautilus_core`
- Added Rust `new_generic_spread_id` and `parse_generic_spread_id_legs` identifier functions (#5041), thanks @faysou
- Added Python `new_generic_spread_id` and `generic_spread_id_to_list` (#5041), thanks @faysou
- Added strategy trigger price modification for trailing stop orders (#5041), thanks @faysou
- Added per-instrument `overrides` on maker/taker fee models
- Added Architect AX account margins and locked USD balance from `/risk-snapshot`
- Added Architect AX bounded mass-status window declaration for reconciliation lookbacks
- Added Architect AX post-only repricing metadata to HTTP and WebSocket order models
- Added Architect AX instrument schedules and estimated funding metadata to response models
- Added Architect AX `book_snapshot_timeout_secs` override, honoring 0 as disabled
- Added Betfair `book_snapshot_timeout_secs` override, honoring 0 as disabled
- Added Binance `book_snapshot_timeout_secs` override, honoring 0 as disabled
- Added typed Parquet catalog round trips for Binance futures custom data
- Added Bybit `book_snapshot_timeout_secs` override, honoring 0 as disabled
- Added `bars_timestamp_on_close` to `BybitDataClientConfig`, defaulting to close (#5160), thanks @folknor
- Added `historical_base_url` and `live_gateway_addr` overrides to `DatabentoDataClientConfig`
- Added Hyperliquid `book_snapshot_timeout_secs` override, honoring 0 as disabled
- Added Kraken bounded mass-status window declaration for reconciliation lookbacks (#5043), thanks @zhaow-de
- Added Lighter support for 64-bit market IDs at and above 4095
- Added Lighter `book_snapshot_timeout_secs` override, honoring 0 as disabled
- Added Lighter `use_gtd` to choose venue or local GTD expiry (#4997), thanks @graceyangfan
- Added Lighter transport batching for batch cancellation and cancel-all requests (#4470)
- Added OKX error codes to order, modify, and cancel rejection reasons as `OKX error <code>: <message>`
- Added OKX scoped fee queries, instrument fee groups, and grouped fee responses (#5207), thanks @silarin
- Added Polymarket session signing and owner-operated session key authorization, listing, and revocation
- Added Polymarket book recovery with snapshot gating and stale-feed detection
- Added Polymarket settlement evidence registry with targeted REST trade resolution (#4876)
- Added Polymarket `MATCHED_NOT_BROADCASTED` trade status
- Added `tardis_http_url` override to `TardisDataClientConfig` and `TardisReplayConfig`
- Added Tardis full 25-level `OrderBookDepth` for `snapshot25` data
- Migrated Polymarket trade and position history to Data API v2 with cursor pagination

### Breaking Changes

- Removed the BitMEX adapter from Rust and Python following the exchange closure on 23 September 2026 (#4552)
- Removed `nautilus_trader.persistence.NautilusDataType` - import from `nautilus_trader.model`
- Removed `NautilusDataType.OrderBook` variant and `"OrderBook"`/`"order_book"` spellings
- Removed instrument `maker_fee` and `taker_fee`; set those rates on the venue `fee_model` instead
- Removed `maker_fee` and `taker_fee` from Arrow instrument schemas and the SQL `instrument` table
- Removed `nautilus_persistence::backend::catalog` - import from `backend::parquet::{catalog, paths}`
- Removed `serialize_decimal` and `serialize_optional_decimal` - use `decimal::serialize` and `serialize_optional`
- Removed Rust `InnerHttpClient` `Default` impl, which panicked on transport errors; use `HttpClient::builder()`
- Removed Rust fixed-width Arrow decoders `decode_price`, `decode_quantity`, and `validate_precision_bytes`
- Removed OBV constructor `period`; output is now cumulative signed volume (#5144), thanks @faysou
- Removed KVO constructor `signal_period`; require `fast_period < slow_period` (#5144), thanks @faysou
- Removed `DirectionalMovement` constructor `ma_type`; use Wilder sums that skip the first bar (#5144), thanks @faysou
- Removed VWAP `update_raw` timestamp; call `reset()` to start a new session (#5144), thanks @faysou
- Removed Rust WMA `new` weights argument; use `with_weights` for custom weights (#5144), thanks @faysou
- Removed the `instrument_id` column from funding rate, instrument status, and option Greeks Arrow files
- Removed `StreamingFeatherWriter` `fs_protocol` and `fs_storage_options`; pass a local path (#5115), thanks @faysou
- Removed flat rotation arguments from `StreamingConfig` and `StreamingFeatherWriter` (#5115), thanks @faysou
- Removed Python `DataBackendSession` and `DataQueryResult` - use `ParquetDataCatalog` queries (#5115), thanks @faysou
- Removed Rust `nautilus_persistence::backend::session` - query through `ParquetDataCatalog` (#5115), thanks @faysou
- Removed `to-json` and `to-parquet` binaries - use `nautilus catalog migrate-parquet` (#5115), thanks @faysou
- Removed `nautilus_persistence::parquet` - use `backend::parquet::io` (#5115), thanks @faysou
- Removed Rust `write_batch_to_parquet` and `write_batches_to_parquet` - use `write_batches_to_object_store`
- Removed Rust `combine_parquet_files` and `min_max_from_parquet_metadata` - use their `_object_store` variants
- Removed `nautilus_persistence::backend::feather` - use `writer::feather` (#5115), thanks @faysou
- Removed `nautilus_persistence::python::catalog` - use `python::backend::parquet::catalog` (#5115), thanks @faysou
- Removed `nautilus_persistence::python::feather` - use `python::backend::feather` (#5115), thanks @faysou
- Removed Rust `DataCatalogConfig::create_catalog` - use `catalog::factory::create_catalog` (#5115), thanks @faysou
- Removed Rust `BybitWebSocketClient` bar timestamp accessors; use the data config (#5160), thanks @folknor
- Replaced Rust `flush_streaming` with `close_streaming_writer` and `reopen_streaming_writer` (#5115), thanks @faysou
- Replaced `StreamingConfig` `catalog_path` and `fs_protocol` with `writer_path` and `catalog` (#5115), thanks @faysou
- Replaced `StreamingConfig` promotion `params` keys with typed promotion fields (#5115), thanks @faysou
- Replaced Parquet `DataCatalogConfig.params` settings with typed fields; `params` keys now fail (#5166), thanks @faysou
- Replaced `StreamingWriter` `backend` and `storage_options` with an optional `catalog` (#5115), thanks @faysou
- Replaced `convert_stream_to_data` `subdirectory` with an `Environment` argument (#5115), thanks @faysou
- Replaced Rust `ParquetDataCatalog::query_typed_data` and `query_typed` with `query`, which now returns `Vec<T>`
- Renamed `OrderBookDepth10` to `OrderBookDepth`, removing the alias and `book_depth10_to_arrow_record_batch_bytes`
- Renamed actor `subscribe_book_depth10`/`unsubscribe_book_depth10` to `subscribe_book_depth`/`unsubscribe_book_depth`
- Renamed `OrderBookDepth10DataWrangler` to `OrderBookDepthDataWrangler`
- Renamed `SubscribeBookDepth10`/`UnsubscribeBookDepth10` commands and their data client hooks, dropping the `10` suffix
- Renamed Python persistence `NautilusDataType.OrderBookDepth10` to `NautilusDataType.OrderBookDepth`
- Renamed `ParquetDataCatalog` method `instrument_id` parameters to `identifier`, matching v1
- Renamed Rust `TestClock`/`TestTimer` to `VirtualClock`/`VirtualTimer` without compatibility aliases
- Renamed Rust `extract_column_by_name_or_index` to `extract_column_by_name`, dropping the positional fallback
- Renamed Databento `load_order_book_depth10` and `get_order_book_depth10`, dropping the `10` suffix
- Renamed the Databento publisher 142 venue from `DEF` to `CDEF`
- Renamed Polymarket `SignatureType` to `PolymarketSignatureType`
- Renamed Tardis `*_tardis_depth10_from_snapshot*` functions and `TardisDepth10StreamIterator`, dropping the `10` suffix
- Changed custom fill-model hooks to receive optional best bid and ask prices
- Changed socket and WebSocket sends to return `SendError::BufferFull` when writer capacity is exhausted
- Changed `SocketClient::writer_tx` to `WriterSender`; update explicit sender types and handle `SendError`
- Changed `Strategy.modify_order` and `ExecutionAlgorithm.modify_order` to return errors for invalid no-change requests
- Changed component lifecycle failures to propagate without logging; callers handle returned errors
- Changed EMA, Wilder, DEMA, and MACD to mean-seeded warmup (#5144), thanks @faysou
- Changed SMA and WMA to report zero until their windows are full (#5144), thanks @faysou
- Changed RSI to Wilder smoothing on [0, 100], with 50 for flat windows; rescale thresholds (#5144), thanks @faysou
- Changed CMO default smoothing to simple averages (#5144), thanks @faysou
- Changed MACD, Keltner, and KVO defaults to exponential averages, matching 1.x (#5098), thanks @nicoloangileri
- Changed VIDYA's CMO default to simple and Pressure's ATR to use the previous close (#5108), thanks @nicoloangileri
- Changed ATR, RVI, and Keltner ATR default smoothing to Wilder (#5144), thanks @faysou
- Changed RVI and ZScore to population deviation; ZScore is zero until its window is full (#5144), thanks @faysou
- Changed Stochastics %D to SMA of %K, with 50 for flat %K and %D windows (#5144), thanks @faysou
- Changed Bias and default ROC output to percentages; ROC looks back exactly `period` updates (#5144), thanks @faysou
- Changed Bollinger Bands to use close prices instead of typical prices (#5144), thanks @faysou
- Changed MACD constructors to take `signal_period` after `slow_period`, defaulting to 9 (#5144), thanks @faysou
- Changed MACD initialization to require signal warmup and reject `fast_period >= slow_period` (#5144), thanks @faysou
- Changed Keltner constructors to take `atr_period` after `k_multiplier` (#5144), thanks @faysou
- Changed WMA default weights to linear weights (#5144), thanks @faysou
- Changed linear regression intercept to use x = 0 (#5144), thanks @faysou
- Changed KVO to Klinger's volume force using daily high-low range and high+low+close trend (#5144), thanks @faysou
- Changed `VolatilityRatio` to current true range over prior EMA, taking a single `period` (#5144), thanks @faysou
- Changed Ichimoku initialization to require all five lines (#5144), thanks @faysou
- Changed Ichimoku displaced lines to lag `displacement - 1` bars (#5144), thanks @faysou
- Changed Aroon outputs to retain full precision instead of rounding to 12 decimals (#5144), thanks @faysou
- Changed windowed indicator period limits to 16,777,216 (#5144), thanks @faysou
- Changed AMA warmup to `period_efficiency_ratio + 1` inputs, seeded from the previous price (#5144), thanks @faysou
- Changed backtest venues to require an explicit `fee_model`, including an explicit zero-fee model
- Changed fee models that read instrument fees to require explicit `maker_rate` and `taker_rate`
- Changed account `calculate_commission` to require explicit `maker_rate` and `taker_rate`
- Changed Rust `ExecutionEngine::register_client` to stop adding venue routes; live and backtest nodes are unaffected
- Changed `Cache.account_for_venue` and `account_id` to return `None` for shared venues; look up by account ID
- Changed Rust `Portfolio` locked-balance and margin queries to take `account_id`; pass `None` for venue lookup
- Changed `ParquetDataCatalog` file methods to take `data_type`, not `data_cls`/`type_name` (#5027), thanks @faysou
- Changed `ParquetDataCatalog.query` to take a `NautilusDataType`, not a directory name (#5027), thanks @faysou
- Changed `ParquetDataCatalog.delete_data_range` to take a non-instrument `NautilusDataType` (#5027), thanks @faysou
- Changed `BacktestDataConfig.data_type` to a `NautilusDataType`; `Instrument` loads all classes (#5027), thanks @faysou
- Changed Rust `OrderCore.events` to read-only `events()`; construct cores with `OrderCore::new`
- Changed `reconciliation_startup_delay_secs` to reject values above 86,400 seconds (one day)
- Changed live node startup to fail when in-scope nonzero venue positions remain unrecovered
- Changed live shutdown to fail when retained submissions remain unresolved (#5156), thanks @silarin
- Changed Rust `calculate_reconciliation_price` and `position_prices_match` to take report average metadata
- Changed same-thread `LiveNode` replacement to require dropping the previous node, even after `dispose()`
- Changed `RiskEngine` to reject orders when accounts, prices, or required funding cannot be established
- Changed `list_parquet_files` and `convert_stream_to_data` to take typed selectors in place of strings
- Changed streaming Feather output to one file per data type and per instrument class (#5115), thanks @faysou
- Changed streaming to stage Feather files on local paths only, rejecting remote paths (#5115), thanks @faysou
- Changed Feather flushes to append to the open `.feather.partial` file; closing seals it (#5115), thanks @faysou
- Changed `StreamingFeatherWriter` rotation time and file info to use catalog type selectors (#5115), thanks @faysou
- Changed `StreamingFeatherWriter.include_types` and record filter keys to reject strings (#5115), thanks @faysou
- Changed Rust `WriterRecordFilter` to take `CatalogDataType` values in place of path prefixes (#5115), thanks @faysou
- Changed `StreamingConfig.writer_backend` to follow the catalog backend, else `Feather` (#5115), thanks @faysou
- Changed streaming to validate `StreamingConfig` and reject zero rotation sizes or intervals (#5115), thanks @faysou
- Changed Rust run manifests and Feather session sources to take `Environment` and `RunStatus` (#5115), thanks @faysou
- Changed `ParquetDataCatalog` to reject LZO and unknown `compression` codes, not use Snappy (#5166), thanks @faysou
- Changed catalog `lz4` compression and code `5` to write `LZ4_RAW`, with `lz4_raw` as an alias (#5166), thanks @faysou
- Changed Rust `DataCatalogConfig` builder to return `ConfigResult` and reject zero counts (#5166), thanks @faysou
- Changed catalog storage options to reject unknown keys, including GCS `project_id` (#5166), thanks @faysou
- Changed Rust `DataCatalogConfig` and `BacktestDataConfig` storage option values to `SecretString`
- Changed `StreamingConfig` type selectors and `record_filters` keys to take enums only (#5115), thanks @faysou
- Changed `ParquetDataCatalog.query_custom_data` to take a `NautilusDataType` (#5115), thanks @faysou
- Changed `ParquetDataCatalog.list_data_types` to return type enums in place of names (#5115), thanks @faysou
- Changed `RotationConfig.mode` to return a `RotationMode` enum (#5115), thanks @faysou
- Changed Rust `CatalogCoverageRow.data_type` to a `CatalogDataType` (#5115), thanks @faysou
- Changed Rust `CatalogBackendType` and `WriterBackendType` to `#[non_exhaustive]`
- Changed Postgres cache connect to require a trader ID and flush only that trader's rows (#5070), thanks @utx0
- Changed Postgres cache connect to fail until old account events are assigned (#5070), thanks @utx0
- Changed `Cache.flush_db` to return errors, so a failing `flush_on_start` stops node startup (#5070), thanks @utx0
- Changed logging init to fail on an unusable log file; lazy Rust init keeps console logging
- Changed Rust `FileWriter::new` to return `anyhow::Result` instead of `Option`
- Changed custom-data writes to require valid schemas; migrate legacy files with `nautilus catalog migrate-parquet`
- Changed catalog depth display to nested bid/ask lists with all levels and order IDs (#4959), thanks @faysou
- Changed Parquet prices, timestamps, enums, and JSON to the open Arrow format; migrate catalogs (#4959), thanks @faysou
- Changed custom data macros to separate model definitions from optional Arrow encoding (#4959), thanks @faysou
- Changed catalog Arrow files to name their type in `type_name` metadata, replacing instrument `class`
- Changed instrument status and option Greeks Arrow conversions to reject batches mixing instruments
- Changed sandbox execution clients to require an explicit `fee_model`, including a zero-fee model
- Changed backtests to fail when a cash, betting, or wallet fill is rejected (#5077), thanks @abhijeetvichare76
- Changed a disposed `BacktestNode` to reject `run()` and `build()` (#5086), thanks @folknor
- Changed DeFi pool `CurrencyPair` base and quote to follow token priority, matching swap trade info and execution
- Changed Betfair, Binance, and Tardis crates to gate Arrow support behind an opt-in `arrow` feature
- Changed Deribit `DeribitWebSocketClient::modify_order` to take `DeribitEditParams`
- Changed Deribit models to deserialize only from borrowed JSON, with `DeribitBookMsg` borrowing its levels
- Changed Python Hyperliquid data and execution client config parameter order to `base_url_http` before `base_url_ws`
- Changed Hyperliquid stale book-delta recovery to shared book recovery, which never requests a reconnect
- Changed Rust `parse_combined_account_balances_and_margins` to require account mode (#5187), thanks @XBeg9
- Changed Kraken legacy currency codes to standard codes; migrate stored currency data (#5155), thanks @zhaow-de
- Changed Kraken EUR/USD quote currencies, REST fees, and PnL to 2 decimals, and JPY to 0 (#5155), thanks @zhaow-de
- Changed Kraken futures balances to retain negative free amounts for wallet shortfalls (#5155), thanks @zhaow-de
- Changed Polymarket `polymarket_trade_sort_key` inputs to v2 `transaction_hash` and `token_id` fields
- Changed Polymarket stream `FAILED` trades to quarantine until a targeted REST result voids applied fills
- Changed Polymarket fills on orders from before a reconnect or restart to wait for a terminal REST result
- Changed Polymarket reconciliation reports to fail while trade settlement evidence is unresolved
- Changed Polymarket user-channel GTD expiry to `OrderExpired`; earlier and REST cancels stay `OrderCanceled`
- Changed Polymarket fee curves to exact decimal arithmetic, rejecting fractional fee exponents
- Changed Polymarket taker fees to read `info.fee_schedule` instead of instrument `taker_fee`
- Changed Tardis `book_snapshot_output` value `"depth10"` to `"depth"` (the legacy value remains accepted)
- Changed Tardis derived trade IDs to hash decimal values, changing IDs for trades without venue IDs
- Changed Tardis `replay` feature to opt-in (no longer a default); it now enables `arrow`

### Security

- Fixed adapter HTTP redirect leaks of credentials and signed payloads, thanks for reporting @seungpyoson
- Fixed Parquet catalog storage errors read as missing files, which could delete data during period consolidation
- Fixed Parquet period consolidation stopping after 10,000 periods, duplicating rows or deleting unconsolidated data
- Fixed logging thread panics when stderr is a closed pipe, which aborted release builds
- Fixed Python float conversions of precision 17 and 18 prices, quantities, and money aborting release builds
- Fixed `Cache.price` mid prices of precision 16 quotes aborting greeks calculations in release builds
- Fixed `Cache.price` midpoints at the precision ceiling panicking the process (#5084), thanks @folknor
- Fixed Python raw and pickle reconstruction of quotes, trades, bars, and price updates aborting release builds
- Fixed Python account balance queries, leverage setters, and `balance_impact` aborting release builds
- Fixed Redis connections leaking passwords to debug logs and panicking on some non-ASCII passwords
- Hardened HTTP and socket transport clients against URL credential leaks into logs, errors, and `Debug` output
- Hardened `DataCatalogConfig` and `BacktestDataConfig` `repr()` and `Debug` against storage option leaks
- Hardened TLS `certs_dir` loading by logging each trusted root at INFO with its SHA-256 fingerprint
- Hardened TLS `certs_dir` loading to fail on unreadable files instead of silently skipping them
- Hardened WebSocket transport client close-reason logging against server-injected line breaks and terminal escapes

### Fixes

- Fixed `StackStr` hashing to support borrowed `str` lookups in maps and sets
- Fixed precision loss when deserializing exactly representable scientific `Decimal` strings
- Fixed `from_pydict` to raise `ValueError` for integers outside the signed or unsigned 64-bit range
- Fixed fills after order expiry being dropped instead of updating the order and position
- Fixed unnecessary Python borrow errors in default actor, strategy, and execution algorithm callbacks
- Fixed duplicate error logging for propagated order-command failures
- Fixed `RetainUnresolved` locally closing unacknowledged orders after recovery exhaustion
- Fixed `Strategy.cancel_all_orders` returning only the first individual cancellation error
- Fixed `Strategy` ignoring `log_rejected_due_post_only_as_warning` for post-only rejections
- Fixed silent Python strategy/algorithm errors (#5039), thanks for reporting @logeid and for initial fix @costajohnt
- Fixed mass-status reconciliation ignoring filled-quantity decreases without fills, thanks for reporting @kta1kri
- Fixed startup reconciliation dropping real fills for external `Accepted` and `Triggered` orders
- Fixed overfill rejections leaving no warning (#5081), thanks @folknor
- Fixed `RiskEngine` risk-limit bypasses through single and batch order modifications, thanks for reporting @kta1kri
- Fixed quote-quantity conversion overflow panics during order risk checks
- Fixed fill OMS resolution to use the owning execution client instead of venue or default routes
- Fixed venue account lookups depending on add order and index rebuilds when accounts share an issuer
- Fixed Python portfolio queries rejecting an explicit account when another account shares its issuer
- Fixed recorded portfolio snapshots latching stale missing-price flags (#5171), thanks @awss1i
- Fixed Python `AccountBalance` and `MarginBalance` `to_dict` amounts losing digits through float formatting
- Fixed Python `PositionStatusReport.to_dict` omitting `avg_px_open`
- Fixed `RiskEngine` using the venue account, not the routed client's (#4946), thanks for reporting @Artur-Sulej
- Fixed `RiskEngine` position-reducing checks counting positions and open orders of other accounts
- Fixed later submits denying or double-routing orders already sent to an execution client (#5020), thanks @s1amese2003
- Fixed overlapping mass-status snapshots reversing newer cached fills or fill voids
- Fixed strategy-scoped cancel-all skipping locally active orders (#5120), thanks @ngarid
- Fixed immediate-mode cancels leaving accepted orders open in the cache (#5120), thanks @ngarid
- Fixed immediate-mode OTO child cancellation and cleanup after entry rejection (#5120), thanks @ngarid
- Fixed trailing-stop orders already in the market being accepted despite `reject_stop_orders`
- Fixed trailing-stop modifies using touch checks instead of stop checks (#5147), thanks @abhijeetvichare76
- Fixed `OrderEmulator` panic releasing a trailing stop limit before its limit price is calculated
- Fixed `OrderEmulator` panic modifying an emulated order from an order or position event handler
- Fixed `OrderEmulator` panic releasing a GTD order as a market order
- Fixed `OrderEmulator` stranding an order whose limit release fails
- Fixed `OrderEmulator` triggering `LAST_PRICE` orders on quotes
- Fixed trailing-stop activation duplicating order events in the cache database
- Fixed OUO order updates resizing the sibling to the leg's total instead of remaining quantity
- Fixed custom fill books falling back to historical liquidity or exceeding their available quantity
- Fixed `BestPriceFillModel` never filling limit orders at or inside the spread
- Fixed fill model panic on probabilities within rounding error of 0 or 1
- Fixed Python `FillModel` subclasses rejecting constructor arguments
- Fixed simulated slippage moving fill prices outside instrument price limits
- Fixed simulated trailing stop limits with a price filling before they trigger
- Fixed simulated cancels rejected for pending OTO children and partially filled market orders
- Fixed simulated venues accepting off-tick prices that could never fill
- Fixed simulated cash accounts allowing binary-option sells to open or increase short positions
- Fixed simulated OTO children left submitted after their parent is rejected
- Fixed simulated bar execution evaluating last-price triggers against the previous bar leg
- Fixed backtest rejection of lower-precision order fields within the same fixed-point scale
- Fixed oversized futures delivery in simulated physical option settlement, thanks for reporting @zakkvald
- Fixed simulated physical option exercise double counting intrinsic value from `InstrumentClose`
- Fixed backtest L1 fills stalling on repeated identical trades (#5017), thanks for reporting @GwangPyo
- Fixed backtest L1 queue estimates ignoring quote size reductions (#5016), thanks for reporting @GwangPyo
- Fixed stale backtest fills triggered by portfolio snapshot timers (#5054), thanks for reporting @frslvr
- Fixed `BacktestEngine` runs after `reset` failing kernel startup and halting `shutdown_on_error` runs
- Fixed Sandbox dropping `OrderAccepted` for an immediately marketable limit IOC (#5102), thanks @graceyangfan
- Fixed Sandbox restart leaving cache-open orders out of the matching engine (#5046), thanks @AmitKumarDeoghoria
- Fixed spread quote aggregation accepting signed leg ratios that flipped the leg sign (#5041), thanks @faysou
- Fixed `convert_stream_to_data` silently skipping staged custom data (#4607), thanks for reporting @mystic-io
- Fixed typed catalog decode for kernel Feather streams of quotes, trades, bars, and related types
- Fixed migration of class-tagged Parquet instruments with `UInt64` or UTC nanosecond timestamps
- Fixed runtime catalog queries to reject legacy instrument schemas with explicit migration guidance
- Fixed streaming Feather writers sealing a new file on every flush (#5115), thanks @faysou
- Fixed Parquet promotion precision for an empty order book depth staged with populated ones (#5115), thanks @faysou
- Fixed a Feather writer panic when a mixed-instrument batch crossed the rotation size limit (#5115), thanks @faysou
- Fixed Parquet writers accepting run IDs that object-store paths encode, which skipped promotion
- Fixed Feather staging writes hanging when the staging worker panics
- Fixed unbounded Feather filename reservations and repeated directory scans during Parquet promotion
- Fixed Parquet promotion from writer paths containing spaces, non-ASCII, or reserved characters
- Fixed Parquet promotion and `convert_stream_to_data` of Feather files with non-ASCII identifiers
- Fixed streaming `replace_existing` emptying the run directory before rejecting an invalid catalog
- Fixed reconciliation fills from venue fill reports not carrying the `reconciliation` event flag
- Fixed live node startup panic on an excessively large `reconciliation_startup_delay_secs`
- Fixed live node startup succeeding with unrecovered venue positions
- Fixed replayed fills doubling positions reconciled from venue position reports (#5041), thanks @faysou
- Fixed startup reconciliation dropping fills that precede order acceptance (#5041), thanks @faysou
- Fixed refused fills stalling position reconciliation (#5041, #5060), thanks for reporting @chaneyka1; thanks @faysou
- Fixed duplicate `LiveNode` builds replacing thread-local messaging (#5049), thanks for reporting @logeid
- Fixed unqueryable Python custom-data writes (#4984), thanks for reporting @shanezilla
- Fixed `customdataclass` nanosecond decoding without pandas (#4984), thanks for reporting @shanezilla
- Fixed catalog interval-filename validation renaming files before rejecting them (#4647)
- Fixed catalog file-name resets overwriting files before validating the new names
- Fixed catalog file-name resets without an identifier moving files out of identifier directories
- Fixed catalog `write_to_json` encoding Windows path separators into object keys
- Fixed local catalog run and data-type listings treating directory read errors as empty
- Fixed catalog run and data-type listings returning percent-encoded names
- Fixed catalog consolidation, deletes, name resets, intervals, and remote queries of non-ASCII identifiers
- Fixed `ParquetDataCatalog` accepting a zero `batch_size` or `max_row_group_size`
- Fixed HTTP client omitting configured `User-Agent` from proxy `CONNECT` requests for HTTPS URLs
- Fixed authenticated HTTP proxy requests failing after cross-origin redirects
- Fixed HTTP client adaptive HTTP/2 flow control triggering Cloudflare resets of large response bodies
- Fixed rate limiters admitting an extra request after idle periods
- Fixed TLS client config panicking on first use when ring is also enabled
- Fixed Sockudo handshake retries logged as errors, hiding reconnect recovery
- Fixed concurrent WebSocket authentication leaving the result and shared state inconsistent
- Fixed WebSocket sends skipping the reconnect replay buffer before authentication (#5128), thanks @Robin1987China
- Fixed dropping unfilled working orders when replacing a reconciliation lifecycle (#5003), thanks @abhijeetvichare76
- Fixed live reconciliation applying report-task results after shutdown (#4982), thanks @folknor
- Fixed backtest data-type and missing-engine errors to name the valid case (#4977), thanks @abhijeetvichare76
- Fixed unclear errors for missing local Parquet catalog paths (#4950), thanks for reporting @Artur-Sulej
- Fixed Windows drive-path catalog file URIs (#4646), thanks for reporting @autotrader2025
- Fixed catalog instrument listing ignoring `base_path` on remote stores such as `s3://` (#5052), thanks @xWaita
- Fixed catalog-wide delete and consolidation skipping directories whose name prefixes a sibling directory
- Fixed catalog-wide delete and consolidation on remote catalogs whose base path contains a `data` segment
- Fixed remote catalogs accepting base paths that object-store paths encode, which broke queries
- Fixed custom data queries matching identifiers by substring instead of the identifier directory
- Fixed bar queries dropping instrument ID identifiers listed alongside full bar types
- Fixed `filter_files` matching bar types by name prefix instead of instrument ID
- Fixed period consolidation panicking on a zero `period_nanos`
- Fixed catalog queries applying time bounds to only one side of an `OR` where clause
- Fixed catalog queries failing on directories whose files differ in precision (#5166), thanks @faysou
- Fixed HTTP catalogs ignoring storage options, which blocked plain `http://` catalogs (#5166), thanks @faysou
- Fixed `write_batches_to_object_store` panicking on an empty batch list
- Fixed OrderBook warnings after sequence counter resets (#5015), thanks @dnouri
- Fixed AroonOscillator `MAX_PERIOD` window dropping the oldest extreme before rollover (#5037), thanks @wbizmo
- Fixed `ArcherMovingAveragesTrends` keeping both trend flags after a reversal (#5125), thanks @wbizmo
- Fixed `VerticalHorizontalFilter` and `RelativeVolatilityIndex` reading NaN on flat prices (#5059), thanks @mkzung
- Fixed indicators changing state on non-finite inputs or malformed candles (#5144), thanks @faysou
- Fixed linear regression R-squared returning NaN for non-flat, low-variance windows (#5144), thanks @faysou
- Fixed rolling indicator precision after large shifts in the window mean (#5144), thanks @faysou
- Fixed Python indicator enums hashing differently from equal integers (#5144), thanks for reporting @faysou
- Fixed option expiry settlement missing underlyings listed on another venue (#5035), thanks @AmitKumarDeoghoria
- Fixed `CryptoOption` applying a one-contract minimum when `min_quantity` is unspecified
- Fixed Postgres cache loading and overwriting another trader's orders, positions, and fills (#5070), thanks @utx0
- Fixed cached time bars replacing same timestamps and skipping older bars (#5109), thanks @dfjmax
- Fixed inverse option notional and PnL using `1 / price` valuation (#5053), thanks for reporting @Kilvish25
- Fixed backtest inverse option cash settlement at quote-point intrinsic value (#5053), thanks for reporting @Kilvish25
- Fixed `TestDataProvider` reading `develop` data in release wheels (#5087), thanks for reporting @bananaunderground
- Fixed adapter JSON decimal and `UnixNanos` parsing with `serde_json/arbitrary_precision`
- Fixed log file rotation for trader IDs or file names containing dots
- Fixed failed log file rotations retrying with a disk sync on every line
- Fixed file logs lagging until the write buffer filled; lines now flush within about 100 ms
- Fixed `nautilus` CLI dropping buffered log lines at exit
- Fixed `OwnOrderBook` ghost orders after re-adding at a new price or a zero-size price update
- Fixed `OrderBook` grouped filtered views overstating liquidity when own orders are better priced
- Fixed own order books appearing with `manage_own_order_books` disabled after a failed order event
- Fixed `OrderBook` filtered views subtracting emulated orders, which never rest in the public book
- Fixed own order books holding quote-quantity orders in quote units before conversion to base units
- Fixed own order book audit removals logging as errors, halting `shutdown_on_error` nodes
- Fixed `OrderBook.get_avg_px_qty_for_exposure` quantities 100x too large for 18-decimal DeFi sizes
- Fixed recoverable adapter conditions logging as errors, halting `shutdown_on_error` nodes
- Fixed quanto margin and balance locks to use the settlement currency (#5073), thanks @abhijeetvichare76
- Fixed margin and betting accounts reserving filled quantity after partial fills (#5130), thanks @abhijeetvichare76
- Fixed time bars stalling after an interval with no updates (#5082), thanks @faysou
- Fixed risk engine reset leaving a halted or reducing engine active without an event (#5085), thanks @folknor
- Fixed canceled FOK orders leaving book liquidity marked consumed (#5106), thanks @ngarid
- Fixed cash-account SELL checks for instruments without a base currency (#5112), thanks @yashwardhan-gautam
- Fixed non-ASCII symbols silently dropping positions (#5143), thanks @Yize9
- Fixed `nautilus-live` failing to compile without the `node` feature (#5177), thanks @zhaow-de
- Fixed adapters logging routine events as warnings and duplicate failures twice
- Fixed Architect AX cancel-all requests ignoring `order_side` (#4470), thanks for reporting @zurpet
- Fixed Architect AX order status reports dropping venue reject reasons
- Fixed Architect AX market data subscriptions not resuming after an explicit reconnect
- Fixed Architect AX terminal order queries losing the original order quantity
- Fixed Architect AX order report parsing of post-only flags, timestamps, and terminal states
- Fixed Architect AX position entry prices to use cost basis when available
- Fixed Architect AX fills being dropped for unknown sibling order states
- Fixed Architect AX book recovery after missing snapshots, invalid frames, and reconnects
- Fixed Architect AX resubscribes racing an earlier unsubscribe and leaving the stream unsubscribed
- Fixed Betfair false fill voids and missing fills during reconciliation after price replacements
- Fixed Betfair false fill voids from inconsistent order and fill snapshots during reconciliation
- Fixed Betfair order quantities in replacement queries and quantity reduction recovery
- Fixed Betfair resting SP bets treated as closed before BSP reconciliation
- Fixed Betfair book recovery after unparsable runner changes, missing images, and changes before an image
- Fixed Betfair market images leaving stale levels on runners the image omits
- Fixed Betfair concurrent book subscriptions dropping markets from the stream subscription
- Fixed Binance order ID encoding for short alphanumeric tags (#5055), thanks for reporting @logeid
- Fixed Binance WebSocket subscribe bursts that closed sockets with 1008 (#5014), thanks @costajohnt
- Fixed historical `BinanceBar` responses never reaching Python (#5002), thanks @abhijeetvichare76
- Fixed Binance bulk non-trading instrument skips logged as warnings instead of debug
- Fixed Binance cancel-all requests ignoring `order_side`
- Fixed Binance Spot `batch_cancel_orders` using a non-existent batch endpoint
- Fixed Binance book recovery after sequence gaps, snapshot failures, and reconnects
- Fixed Binance Spot empty depth snapshots failing to clear the book
- Fixed Binance order book snapshots missing `F_SNAPSHOT` on their price levels
- Fixed Binance Futures panic on depth updates without price levels
- Fixed Binance depth snapshot bursts exceeding the venue request-weight limit
- Fixed Binance Spot book unsubscribe and resubscribe commands reaching the stream pool out of order
- Fixed Binance Rust data clients not registering `BinanceBar` custom data for persistence
- Fixed Blockchain RPC WebSocket blocks missing their chain, panicking the data engine
- Fixed Blockchain swaps awaiting finality rejected by the in-flight check before their fill arrived
- Fixed Bybit cancel-all requests ignoring `order_side` (#4470), thanks for reporting @zurpet
- Fixed Bybit cursor pagination looping forever on repeated page cursors (#5019), thanks @Martingale42
- Fixed Bybit book recovery after update ID gaps, missing snapshots, and reconnects
- Fixed Bybit order book snapshots missing `F_SNAPSHOT` on their price levels
- Fixed Bybit data `is_connected` staying true while a socket reconnects (#5162), thanks @folknor
- Fixed Coinbase trade aggressor side inverted by using the reported maker side
- Fixed Databento live MBO subscriptions never emitting trades (#5095), thanks for reporting @invisiblebackhand
- Fixed DeFi position fees accruing on liquidity after a mint or burn instead of before
- Fixed DeFi swap replay dropping fees on input left at the swap's final price
- Fixed DeFi size-for-impact search never expanding its upper bound
- Fixed DeFi pool balance estimates adding raw fee growth to token amounts
- Fixed DeFi price impact and slippage reporting 0 bps beyond the `u32` range
- Fixed DeFi chain IDs and HyperSync URLs for 12 chains, including Unichain, Ink, and Hyperliquid
- Fixed DeFi `Pool` display repeating the fee label
- Fixed DeFi swap replay advancing fees across a drifted tick partition (#5163), thanks @folknor
- Fixed DeFi pool utilization panics during partial-history replay
- Fixed DeFi mint panics above tick liquidity limits and state changes on rejected mints or burns
- Fixed DeFi size estimates overflowing near the maximum pool tick
- Fixed Deribit prices, sizes, balances, and fees losing digits through `f64` JSON parsing
- Fixed Deribit order and edit amounts and prices losing digits through `f64` serialization
- Fixed Deribit and Tardis Machine book parsing panicking on out-of-range prices
- Fixed Deribit order books going stale when a book message fails conversion
- Fixed Deribit book parsing panicking on amounts that round to zero at size precision
- Fixed Deribit orders and edits emitting no rejection when their values cannot serialize exactly
- Fixed Derive rejecting valid sub-minimum taker orders (#5045), thanks for reporting @Aviksaikat
- Fixed Derive instrument `info` dropping fields from the venue response
- Fixed Hyperliquid fill reconciliation failing for accounts with fills on settled HIP-4 outcomes
- Fixed Hyperliquid mass status failing on `outcomeSettledCanceled` historical orders
- Fixed Hyperliquid book recovery after missing snapshots, invalid frames, and reconnects
- Fixed Hyperliquid order book snapshots missing `F_SNAPSHOT` and closing every level with `F_LAST`
- Fixed Hyperliquid depth-only book subscriptions emitting order book deltas
- Fixed Hyperliquid fills and order updates missed while the execution WebSocket was disconnected
- Fixed Hyperliquid bracket order modification canceling contingent orders
- Fixed Hyperliquid orders left open when canceled while a modify of them was in flight
- Fixed Hyperliquid REST open orders reconciling stops and take-profits as limits (#5145), thanks @JulienKervarrec
- Fixed Hyperliquid historical stop reports losing trigger metadata and blocking fills (#5191), thanks @XBeg9
- Fixed Hyperliquid IOC canceled remainders reconciling as filled and staying open (#5191), thanks @XBeg9
- Fixed Hyperliquid reduce-only quantities in startup reports with complete fill history (#5192), thanks @XBeg9
- Fixed Hyperliquid unified and portfolio margin account balances to use spot collateral (#5187), thanks @XBeg9
- Fixed Interactive Brokers contract details conversion raising `ModuleNotFoundError` (#5051), thanks @dfjmax
- Fixed Kraken spot connect aborting when TradeVolume fails (#5005), thanks @zhaow-de
- Fixed Kraken spot reports spelled with the pair altname not resolving to instruments (#5034), thanks @zhaow-de
- Fixed Kraken spot cancel-all cancelling orders outside the requested instrument (#5044), thanks @zhaow-de
- Fixed Kraken spot report pagination continuing past 500 pages without reporting incomplete (#5062), thanks @zhaow-de
- Fixed Kraken spot startup reconciliation omitting orders closed while the node was down (#5110), thanks @zhaow-de
- Fixed Kraken spot margin reports omitting the surviving-lot entry average (#5065), thanks @zhaow-de
- Fixed Kraken spot position coverage and false flat reports for unreported holdings (#5185), thanks @zhaow-de
- Fixed Kraken scoped reads dropping altname pairs or returning every instrument (#5129), thanks @zhaow-de
- Fixed Kraken currency normalization corrupting XTZ, ZRX, and XAUT codes (#5155), thanks @zhaow-de
- Fixed Kraken fills booking fees in quote currency instead of the reported fee currency (#5155), thanks @zhaow-de
- Fixed Kraken futures balances overwriting holdings across wallets of the same currency (#5155), thanks @zhaow-de
- Fixed Kraken futures double-counting flex USD collateral and contract-symbol balances (#5155), thanks @zhaow-de
- Fixed Kraken futures flex USD portfolio balances using 2 instead of 8 decimals (#5155), thanks @zhaow-de
- Fixed Lighter cancel-all requests ignoring `order_side` (#4470), thanks for reporting @zurpet
- Fixed Lighter book recovery after missing snapshots, sequence gaps, and reconnects
- Fixed Lighter websocket subscription hangs on unparsable confirmations
- Fixed Lighter spot stats parsing for empty mid prices
- Fixed OKX order book snapshots retaining stale price levels after resubscription
- Fixed OKX book deltas missing the `F_LAST` flag, stalling consumers with `buffer_deltas` enabled
- Fixed OKX account state always reporting `MARGIN`, ignoring the configured account type
- Fixed OKX fee and filled-quantity caches growing unbounded over long-running sessions
- Fixed OKX cancel-all requests ignoring `order_side` (#4470), thanks for reporting @zurpet
- Fixed OKX `close_fraction` orders reconciling with zero quantity (#5068), thanks for reporting @victor-santana-hub
- Fixed OKX filled spot market buys remaining `PARTIALLY_FILLED` (#5105), thanks for reporting @BioxMech
- Fixed OKX `activate_feature` rate limit exceeding the published 5 requests per 2 seconds
- Fixed OKX HTTP errors without `data` hiding the venue error code, such as invalid API keys
- Fixed OKX `open_only` order status reports fetching regular and spread order history
- Fixed Polymarket order modifications blocked after a deferred cancel with an unresolved venue outcome
- Fixed Polymarket maker rebates and taker fees zeroing on incomplete schedules
- Fixed Polymarket submits with an unknown outcome staying `SUBMITTED` after missed WebSocket updates
- Fixed Polymarket reconciliation of resolved, unredeemed balances (#4963), thanks for reporting @seungpyoson
- Fixed Polymarket reconciliation closing auto-redeemed positions at the entry price before settlement
- Fixed Polymarket fills matched during a user WebSocket outage never applying after reconnect
- Fixed Polymarket unknown submissions being rejected locally after recovery exhaustion
- Fixed Polymarket late submit evidence repeating acceptance or fills and overwriting replacement order mappings
- Fixed Polymarket uncertain order recovery losing venue cancellation duties after local closure
- Fixed Polymarket BUY fills truncated to the order quantity; overfills now raise the order quantity
- Fixed Polymarket commissions rounding instead of flooring to five decimals like the venue charge
- Fixed Polymarket order quantity updates after a modify dropping fills from earlier venue orders
- Fixed Polymarket restarts replacing fills of closed orders with synthetic fills that lack commission
- Fixed Polymarket restarts failing for retained positions whose fills fall outside a bounded lookback
- Fixed Polymarket denying immediate FOK and FAK BUY orders whose maker amount is not an exact cent
- Fixed Polymarket opening an idle market WebSocket on connect, which the venue closed with code 1008
- Fixed Polymarket HTTP cancels emitting `OrderCanceled` for tracked orders or orders the response omits
- Fixed Polymarket sub-tick settlement prices being rejected or emitted raw (#5176), thanks @yashwardhan-gautam
- Fixed Polymarket fill reports admitting trades that contradict retained settlement outcomes
- Fixed Polymarket 

Shown in full with attribution under the source's licence. Licence: LGPL-3.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.