v1.222.0
nautechsystems/nautilus_traderv1.222.0Jan 2, 2026by github-actions[bot]
AI Summary
Release adding Python 3.14 support, Kraken adapter, Cap'n Proto serialization, and initial backtest visualization tearsheets with plotly. Major improvements to matching engine liquidity consumption tracking and portfolio statistics.
Key Highlights
- Added support for Python 3.14
- Added Kraken integration adapter
- Added Cap'n Proto serialization for efficient zero-copy data interchange
- Added initial backtest visualization tearsheets with plotly
- Added matching engine liquidity_consumption config option
- Added portfolio statistics: CAGR, CalmarRatio, MaxDrawdown
- Added price protection support for market orders
Breaking Changes
- Dropped support for Python 3.11
- Removed prob_fill_on_stop parameter from FillModel
- Renamed parse_instrument to parse_polymarket_instrument
- Standardized data catalog directory naming (order_book_delta -> order_book_deltas)
- Changed ParquetDataCatalog.register_data to treat files=[] as no files
New Features
- Python 3.14 support
- Kraken adapter
- Cap'n Proto serialization
- Tearsheet visualization with plotly
- CAGR, CalmarRatio, MaxDrawdown portfolio statistics
- Quantity.from_decimal, Price.from_decimal, Money.from_decimal constructors
- create_bars_with_fills in Tearsheet
- allow_overfills config option for ExecEngine
- PositionAdjusted events for tracking quantity/PnL changes
Full Release Notes
# NautilusTrader 1.222.0 Beta Released on 1st January 2026 (UTC). This release adds support for Python 3.14 with the following limitations: - dYdX adapter extras (`[dydx]`) unavailable due to upstream `coincurve` compatibility (available on Python 3.12-3.13) - Interactive Brokers adapter extras (`[ib]`) unavailable due to upstream `nautilus-ibapi` compatibility (available on Python 3.12-3.13) ### Enhancements - Added support for Python 3.14 - Added Kraken integration adapter - Added Cap'n Proto (`capnp`) serialization for efficient zero-copy data interchange (opt-in via `capnp` feature flag in `nautilus-serialization` crate) - Added initial backtest visualization tearsheets with plotly - Added matching engine `liquidity_consumption` config option to track per-level consumption and prevent overfilling displayed book liquidity (default `False` to retain current behavior) - Added matching engine trade consumption tracking (when `liquidity_consumption=True` and `trade_execution=True`) to prevent multiple orders matching the same trade tick from collectively overfilling - Added theme support to `bars_with_fills` chart (#3329), thanks @faysou - Added price protection support for market orders (#3065), thanks @Antifrajz - Added `Quantity.from_decimal` constructor (#3189), thanks @faysou - Added `Price.from_decimal` constructor - Added `Money.from_decimal` constructor - Added `create_bars_with_fills` to Tearsheet (#3137), thanks @faysou - Added `proxy_url` support for HTTP clients - Added `CAGR` portfolio statistic - Added `CalmarRatio` portfolio statistic - Added `MaxDrawdown` portfolio statistic - Added `quote_quantity` parameter for `close_position(...)` and `close_all_positions(...)` strategy methods - Added remaining bar aggregation methods: `TICK_IMBALANCE`, `TICK_RUNS`, `VOLUME_IMBALANCE`, `VOLUME_RUNS`, `VALUE_IMBALANCE`, `VALUE_RUNS` (#3217), thanks @nicolad - Added `ParquetDataCatalog.query_first_timestamp` (#3253), thanks @MK27MK - Added `PolymarketDataLoader` for loading historical data with docs and example - Added Binance accurate commission rates per symbol (#3208), thanks @delusionpig - Added Binance cross-margin info to `AccountState` - Added `BinanceInstrumentProviderConfig` to support the `query_commission_rates` config option - Added Bybit spot margin auto-borrow and auto-repay with `auto_repay_spot_borrows` config option - Added Bybit spot margin manual operations (`BybitMarginAction`) for strategy-controlled borrow/repay via `query_account` - Added Bybit HTTP request_tickers support (#3241), thanks @TaiShanQ - Added Databento subscription acknowledgement handling (#3337), thanks @shzhng - Added Databento historical client consolidated schema support (#3338), thanks @shzhng - Added Interactive Brokers optional exchange param for spread contracts (#3319), thanks @faysou - Added Polymarket Gamma API support for instrument loading (#3141), thanks @DeirhX - Added OKX historical trades requests - Added Tardis `book_snapshot_output` config option for tardis machine replays (default `deltas` to retain current behavior) - Added `allow_overfills` config option to `ExecEngineConfig` (default `False`) to handle order fills exceeding order quantity with warning instead of raising - Added `overfill_qty` field to orders for tracking fill quantities exceeding original order quantity - Introduced `PositionAdjusted` events for tracking quantity/PnL changes outside normal order fills (base currency commissions, funding payments, manual adjustments) - Upgraded continuous reconciliation for execution engine using position reports to detect missed fills ### Breaking Changes - Dropped support for Python 3.11 - Removed `prob_fill_on_stop` parameter from `FillModel` and `FillModelConfig` (stop orders have no queue position to simulate as triggers are deterministic when price reaches the trigger level) - Removed `use_ws_trade_api` config option from Bybit execution client (using WebSocket trade API only) - Renamed `parse_instrument` to `parse_polymarket_instrument` in Polymarket adapter for clarity - Renamed `ExecTesterConfig.enable_buys` to `enable_limit_buys` - Renamed `ExecTesterConfig.enable_sells` to `enable_limit_sells` - Changed `ParquetDataCatalog.register_data` to now treat `files=[]` as registering no files; pass `files=None` (default) to include all files - **Standardized data catalog directory naming**: Order book data directory names now use plural forms to align with the Rust catalog and Tardis Machine conventions; this ensures data written by the Python `StreamingFeatherWriter` can be read by the Rust catalog - `order_book_delta/` → `order_book_deltas/` - `order_book_depth10/` → `order_book_depths/` **Migration**: Rename existing data directories to use plural forms: ```bash # If you have existing order book data, rename the directories: mv <your_data_path>/order_book_delta <your_data_path>/order_book_deltas mv <your_data_path>/order_book_depth10 <your_data_path>/order_book_depths ``` ### Security - Added `osv-scanner` for Python dependency vulnerability scanning in pre-commit - Added `cargo-vet` for Rust supply chain security auditing - Hardened unsafe code with runtime checks and `#![deny(unsafe_op_in_unsafe_fn)]` lint - Hardened datetime conversions with overflow protection - Hardened CI workflows by pinning Docker images to SHA digests - Improved actor/component registry safety with `ActorRef` guards and runtime borrow tracking - Fixed code scanning security alerts ### Fixes - Fixed `uint64_t` truncation bug in `determine_trade_fill_qty` for trade execution with `high-precision` mode - Fixed stop market order fill price in `L1_MBP` mode - Fixed cache dropped same-timestamp market data on insert - Fixed race condition in InstrumentProvider causing duplicate instrument initialization in shared providers - Fixed portfolio statistics various bugs and edge cases - Fixed SyntheticInstrument formula error during parsing with hyphened InstrumentId (#3257), thanks @Javdu10 - Fixed balance recalculation to use raw fixed-point (#3356), thanks @kirill-gr1 - Fixed matching engine GTD order expiry key mismatch (#3272), thanks for reporting @linimin - Fixed matching engine order modification for partial fills - Fixed matching engine L2/L3 partial fill quantity calculation on subsequent book updates - Fixed NETTING position flip snapshots and cache index cleanup (#3081), thanks @SarunasSS - Fixed incorrect handling of data responses in msgbus (#3310), thanks @filipmacek - Fixed data engine to use separate aggregators for historical data (#3326), thanks @faysou - Fixed bar execution generating fractional fill quantities (#3352), thanks @Johnkhk - Fixed `BacktestResult.total_positions` to match tearsheet count (#3148), thanks for reporting @2-5 - Fixed risk engine negative price handling for spread instruments (#3136), thanks for reporting @q351941406 - Fixed risk engine trailing stop order risk validations (#3160), thanks for reporting @GianC0 - Fixed risk engine balance checks for cash borrowing - Fixed risk engine balance checks for position-reducing SELL orders (#3256), thanks for reporting @GianC0 - Fixed spawned order client_id caching in `ExecAlgorithm` (#3122), thanks for reporting @kirill-gr1 - Fixed parse_dates parameter in CSV loaders (#3132), thanks @maomao9-0 - Fixed `GreeksCalculator` handling of missing price data (#3116), thanks for reporting @q351941406 - Fixed `StreamingFeatherWriter` `_setup_streaming` with `replace_existing` config (#3234), thanks @cauta - Fixed conversion of streamed instruments to catalog (#3235), thanks @faysou - Fixed active liquidity calculation Pool profiler simulation (#3165), thanks @filipmacek - Fixed duplicate `on_instrument` callback in request flow for Python adapters (#3323), thanks @filipmacek - Fixed Redis index key parsing with `use_instance_id` - Fixed Betfair datetime encoding error in order status reports - Fixed Betfair login race condition during concurrent connections - Fixed Betfair parsing errors for undocumented codes - Fixed Betfair duplicate fills on startup/reconnect - Fixed Binance instrument info dict JSON serialization (#3128), thanks for reporting @woung717 - Fixed Binance ADL orders with TRADE execution type - Fixed Binance Futures Algo Order API for conditional orders (#3287), thanks for reporting @KaizynX - Fixed Bybit historical bars requests partial (unclosed) bar filtering - Fixed Bybit WebSocket bars to respect `timestamp_on_close` config - Fixed `BybitHttpClient` type stub pyi signatures (#3238), thanks @sunlei - Fixed Databento historical client to support consolidated schemas (`cmbp-1`, `cbbo-1s`, `cbbo-1m`) in quote requests - Fixed Databento MBO data decoding when `PRICE_UNDEF` appears with non-zero precision - Fixed Databento Arrow serialization for `PRICE_UNDEF` (#3183), thanks for reporting @marloncalvo - Fixed Databento quote decoding with undefined bid/ask prices - Fixed Interactive Brokers quote tick subscriptions to use tick-by-tick data (#3135), thanks for reporting @genliusrocks - Fixed Interactive Brokers serialization of `IBContractDetails` (#3181), thanks @faysou - Fixed Interactive Brokers parsing of invalid prices (#3246), thanks @faysou - Fixed OKX pre-open instrument parsing and standardize enum usage (#3134), thanks for reporting @3wtz - Fixed OKX `request_bars` pagination halting prematurely in Range mode (#3145), thanks for reporting @3wtz - Fixed OKX `request_bars` pagination using correct backwards API semantics (#3145), thanks for reporting @3wtz - Fixed OKX FOK/IOC order type preservation across parsers (#3182), thanks @CuBeof - Fixed OKX fee rate sign convention for backtesting (#3260), thanks @GhostLee - Fixed Polymarket maker fill order side inversion (#3126), thanks for reporting @santivazq - Fixed Polymarket instrument provider market filtering (#3133), thanks @MisterMM23 - Fixed Polymarket websocket client cancellation on concurrent subscriptions (#3169), thanks @DeirhX - Fixed Polymarket maker fills parsing for cross-asset matching and multiple concurrent fills (#3172), thanks @petioptrv - Fixed Polymarket account balance update timing issue (#3161), thanks for reporting @santivazq - Fixed Polymarket handling of overfilled FOK orders using `allow_overfills` execution engine config option (#3221), thanks for reporting @Javdu10 - Fixed Polymarket `match_time` timestamp parsing (#3273), thanks for reporting @santivazq - Fixed Polymarket timestamp conversions (#3291, #3292), thanks for reporting @santivazq - Fixed Polymarket fill reports for cross-asset matches (#3345), thanks for reporting @santivazq - Fixed Polymarket order side for cross-asset matches (#3357), thanks for reporting @santivazq - Fixed Tardis book snapshot to deltas CLEAR prepending - Fixed Tardis CSV parsing for mid-day snapshots ### Internal Improvements - Added BitMEX submit broadcaster - Added Bybit start/end time filtering for order status reports (#3209), thanks @sunlei - Added BybitRawHttpClient Python bindings (#3252), thanks @sunlei - Added Databento subscription acknowledgement handling and logging - Added non-mutating swap quote simulation for Pool tickmap profiling (#3123), thanks @filipmacek - Added ERC20 token balance tracking to BlockchainExecutionClient (#3224), thanks @filipmacek - Added DeFi pool discovery service with full Uniswap(V2/V3/V4) support (#3255), thanks @filipmacek - Added Deribit HTTP client with instrument support (#3288), thanks @filipmacek - Added Deribit account balance and credential management (#3295), thanks @filipmacek - Added Deribit WebSocket client with market data support (#3297), thanks @filipmacek - Added Deribit WebSocket auth and raw data stream support (#3304), thanks @filipmacek - Added Deribit data client in Rust (#3311), thanks @filipmacek - Added Deribit data client Python bindings (#3315), thanks @filipmacek - Added Deribit data client WebSocket handling and request methods (#3340), thanks @filipmacek - Added Deribit execution client scaffolding (#3350), thanks @filipmacek - Added dYdX v4 crate (#3138), thanks @nicolad - Added dYdX v4 WebSocket in Rust (#3158), thanks @nicolad - Added dYdX v4 DataClient in Rust (#3162), thanks @nicolad - Added dYdX v4 ExecutionClient in Rust (#3163), thanks @nicolad - Added dYdX v4 execution reconciliation in Rust (#3171), thanks @nicolad - Added dYdX v4 gRPC order execution (#3222), thanks @nicolad - Added dYdX v4 order execution via gRPC with Python bindings (#3245), thanks @nicolad - Added dYdX v4 conditional orders (#3259), thanks @nicolad - Added dYdX v4 Python adapter layer (#3275), thanks @nicolad - Added dYdX v4 batch cancel and expose missing Python bindings (#3282), thanks @nicolad - Added dYdX v4 HTTP data, execution, and WebSocket tests (#3290), thanks @nicolad - Added Kraken Futures demo support (#3262), thanks @nicolad - Added check before creation of bars in IB adapter (#3348), thanks @PJPRoche and @faysou - Added check for empty data in _handle_table_nautilus (#3248), thanks @faysou - Integrated trade analytics across DeFi pools swaps and simulated quotes (#3174), thanks @filipmacek - Implemented size for impact bps `PoolProfiler` simulation (#3186), thanks @filipmacek - Implemented dual-parser architecture for DEX event parsing (#3228), thanks @filipmacek - Implemented Bybit chunking support for batch cancel orders (#3244), thanks @sunlei - Scaffolded blockchain execution client with native balance fetch (#3214), thanks @filipmacek - Ported Bybit integration adapter to Rust - Unified tokio runtime selection in Rust adapters (#3321), thanks @filipmacek - Converted `LatencyModel` to trait with `StaticLatencyModel` impl (#3369), thanks @marcus-sa - Refactored network crate to modularize `http`, `socket`, and `websocket` - Refactored reading of feather files in catalog (#3114), thanks @faysou - Refactored processing of historical data (#3038), thanks @faysou - Refactored execution engine reconciliation (#3185), thanks @faysou - Refactored risk engine initialization with shallow clone for portfolio (#3360), thanks @marcus-sa - Refactored `SpreadQuoteAggregator` (#3312), thanks @faysou - Refactored Polymarket instrument provider to use async HttpClient - Refactored Interactive Brokers `HistoricInteractiveBrokersClient` (#3261), thanks @faysou - Refactored IB Historical client (#3276), thanks @faysou - Improved trade execution matching with transient bid/ask override for `trade_execution=True` mode, ensuring limit orders fill correctly when trades occur at the limit price - Improved Stochastics indicator with additional parameters (#3296), thanks @mahmutf - Improved `None` handling in equality and comparison methods - Improved `Actor.request_bars` to enforce standard bar types (#3216), thanks @faysou - Improved JSON-RPC non-standard rate limit error handling (#3227), thanks @filipmacek - Improved Betfair execution error handling and edge cases - Improved Betfair order rejection and duplicate fills handling - Improved Binance data client with optional authentication - Improved Bybit spot borrow repayments (#3223), thanks @vcraciun - Improved Databento live connection stability and reconnects - Improved Databento decoder sentinel value handling (#3361), thanks for reporting @davidsblom - Improved dYdX v3 resilience and reliability (#3225), thanks @SarunasSS - Improved dYdX v4 adapter test coverage (#3212), thanks @nicolad - Improved dYdX v4 network, bars, and batch cancel (#3231), thanks @nicolad - Improved dYdX v4 gRPC execution with edge cases and batch cancel (#3239), thanks @nicolad - Improved dYdX v4 data/exec testers and fix GTT (#3254), thanks @nicolad - Improved dYdX v4 WebSocket subscription state management (#3286), thanks @nicolad - Improved dYdX v4 enums for type safety and improve WS tests (#3294), thanks @nicolad - Improved dYdX v4 model type safety with enums (#3299), thanks @nicolad - Improved dYdX v4 parse block height WebSocket feed and gate short-term order submission (#3320), thanks @nicolad - Improved Polymarket position querying using Gamma API (#3142), thanks @DeirhX - Improved Tardis adapter robustness and error handling - Standardized dYdX WebSocket architecture (#3173), thanks @nicolad - Standardized dYdX client integration tests (#3193), thanks @nicolad - Standardized dYdX per adapter guide conventions (#3267), thanks @nicolad - Changed Interactive Brokers default quote tick subscription to batch quotes (#3196), thanks @faysou - Changed spread quote aggregation to opt-in (#3355), thanks @faysou - Removed redundant debug code for reconcile execution (#3344), thanks @TaiShanQ - Refined timer name validation to accept non-ASCII characters (common for foreign currencies) (#3154), thanks for reporting @woung717 - Refined spread support (#3284), thanks @faysou - Refined support for monthly and yearly bars (#3166), thanks @faysou - Refined bar aggregators in Rust (#3170), thanks @faysou - Refined adding files to catalog session (#3215), thanks @faysou - Refined loading of files in catalog (#3313), thanks @faysou - Refined catalog file filter methods (#3318), thanks @faysou - Refined `HistoricInteractiveBrokersClient` (#3187), thanks @faysou - Refined `BacktestDataIterator` docstrings (#3264), thanks @faysou - Refined `BacktestDataConfig.query` (#3266), thanks @faysou - Refined Databento utils (#3268), thanks @faysou - Refined Interactive Brokers historical data request methods (#3279), thanks @faysou - Refined requests and aggregators (#3328), thanks @faysou - Refined parsing of IB expiries (#3332), thanks @faysou - Refined subscription to spread quotes (#3349), thanks @faysou - Refined data query and subscription (#3353), thanks @faysou - Refined response to join_request (#3366), thanks @faysou - Refined adding instrument to cache after modifying it (#3372), thanks @faysou - Optimized unnecessary string allocations and `Ustr` usage - Optimized build to prefer sccache when available (#3243), thanks @sunlei - Optimized execution reconciliation to avoid quadratic complexity (#3140), thanks @DeirhX - Optimized network clients by enabling `TCP_NODELAY` (#3156), thanks @sunlei - Optimized build by disabling Cargo incremental compilation when using sccache (#3157), thanks @sunlei - Optimized BitMEX submit and cancel broadcasters by removing unnecessary lock on internal transport clients - Optimized full math division for DeFi calculations (#3179), thanks @filipmacek - Optimized parquet data filtering and streaming initialization performance (#3298), thanks @ReCodeLife - Repaired OKX spot margin position reports for borrowing, thanks @sunlei - Repaired Bybit docs links in comment (#3125), thanks @sunlei - Repaired Bybit HTTP order place (#3127), thanks @sunlei - Repaired Bybit `AccountPosition` message parsing (#3147), thanks @sunlei - Repaired Bybit conditional order trigger semantics and type - Repaired Bybit instruments pagination handling (#3210), thanks @sunlei - Repaired Bybit batch place orders (#3211), thanks @sunlei - Repaired Bybit `get_account_details` (#3219), thanks @sunlei - Repaired Bybit `set_position_mode` (#3220), thanks @sunlei - Upgraded implied-vol crate (#3115), thanks @faysou - Upgraded Rust (MSRV) to 1.92.0 - Upgraded Cython to v3.2.3 - Upgraded `databento` crate to v0.37.0 - Upgraded `datafusion` crate to v51.0.0 - Upgraded `msgspec` to 0.20.0 - Upgraded `pyo3` crate to v0.27.2 - Upgraded `pyo3-async-runtimes` crate to v0.27.0 - Upgraded `redis` crate to v1.0.2 ### Documentation Updates - Added Polymarket historical data loading docs - Added visualization docs for `bars_with_fills` tearsheet feature - Added order state flow diagram with lifecycle documentation - Added fee rate sign convention in instruments concept guide - Added fill price determination to backtesting concept guide - Improved concept docs with Mermaid diagrams replacing ASCII diagrams - Improved execution concept guide with overfills explanation - Improved backtesting concept guide to clarify bar execution behavior - Improved documentation for uv-installed Python environments, thanks to @faysou for investigating and reporting - Improved notebook path handling and fix quickstart data loading, thanks for reporting @semihtekten ### Deprecations None