v1.229.0

jamiepine/voiceboxv1.229.0Jun 26, 2026by github-actions[bot]

AI Summary

This beta release features extensive API refactoring across Python and Rust v2, introducing Redis and Postgres cache adapters for persistence. It adds significant exchange support for Binance Futures, BitMEX, and Hyperliquid, alongside a shift to typed error handling.

Key Highlights

  • Added Redis and Postgres cache adapters for order and position persistence.
  • Added support for Binance Futures funding rates, order-lists, and ticker data.
  • Changed API to return typed errors (e.g., `CurrencyLookupError`) instead of `anyhow::Error`.
  • Added support for Hyperliquid historical trade requests and Databento dataset mapping.

Breaking Changes

  • Changed backtest config builders to validate on `build()` and return `ConfigResult`.
  • Changed Rust actor `self.clock()` to return `ClockApi`.
  • Changed default message bus/cache encoding to JSON.
  • Removed `CacheConfig.database` and `MessageBusConfig.backing`.
  • Renamed `add_native_exec_algorithm` to `add_builtin_actor`.

New Features

  • Added `ProbabilityPriceFeeModel` for configurable sandbox fee models.
  • Added SEC1 EC private key support to socket TLS configuration.
  • Added Binance Futures `MIN_NOTIONAL` parsing and ticker data support.
  • Added BitMEX legacy futures and reference basket instrument parsing.

Full Release Notes

# NautilusTrader 1.229.0 Beta

Released on 25th June 2026 (UTC).

This release includes many breaking changes across the user-facing Python and Rust v2 APIs.

### Enhancements
- Added `Cache::try_currency` with `CurrencyLookupError` for typed missing-currency lookups (Rust)
- Added `Cache::try_instrument` with `InstrumentLookupError` for typed missing-instrument lookups (Rust)
- Added `Cache::try_order` with `OrderLookupError` for typed missing-order lookups (Rust)
- Added negative price support for `Commodity` instruments in risk checks (#2330), thanks for reporting @fabz1
- Added cache order index crash-recovery restore for Redis and Postgres adapters (Rust)
- Added capability-aware `analyze-pool(s)`/`sync-dex` validation that fails before sync for unsupported DEXes
- Added `ProbabilityPriceFeeModel` and configurable sandbox fee models (#4262), thanks @graceyangfan
- Added SEC1 EC private key support to socket TLS configuration (Rust)
- Added `order_position_index` Postgres table for the order-position index; run `make init-db` to migrate
- Added `add_native_exec_algorithm` and `ExecutionAlgorithmConfig` bindings to the Python v2 backtest engine
- Added `Order::to_order_status_report` conversion in Rust
- Added `with_msgbus_publisher` for Rust live-node and kernel builders
- Added benchmark-relative portfolio stats (#4251), thanks @mahimn01
- Added SBE and Cap'n Proto encodings for Rust-native message bus publishers
- Added SBE and Cap'n Proto support for `OptionGreeks`
- Added Postgres cache position event-log persistence and restart recovery (Rust)
- Added Redis cache adapter order, position, and order-index write persistence (Rust)
- Added `RedisCacheConfig`, `PostgresCacheConfig`, and `RedisMessageBusConfig` for Rust factories
- Added Python v2 `Strategy.order_factory` accessor and validating `OrderFactory` bindings
- Added PyO3 cache purge APIs (#4249), thanks @graceyangfan
- Added PyO3 instrument `tick_scheme` fields with Arrow persistence
- Added Binance Futures `bnfcr_currency` config for Credits Trading Mode
- Added Binance Futures funding-rate history support in Rust
- Added Binance Futures `MIN_NOTIONAL` parsing for `min_notional` (#4280), thanks @filipmacek
- Added Binance Futures ticker data support in Rust
- Added Binance order-list submission in Rust
- Added Binance market-data WebSocket fixtures for CM-UM `st` and `ps` fields (Python and Rust)
- Added `BitmexInstrumentState::Unknown` to tolerate unrecognized venue states without bootstrap failure
- Added BitMEX legacy futures, spreads, and reference basket instrument parsing
- Added Blockchain CLI help for discoverable and snapshot-capable DEXes per chain
- Added Databento `venue_dataset_map` to override the default venue-to-dataset mappings
- Added Hyperliquid builder attribution opt-out
- Added Hyperliquid historical trade requests
- Added Hyperliquid minimum notional handling
- Added Interactive Brokers trailing stop basis-point offset support (#4292), thanks @faysou
- Added Lighter NVDA composite market maker Python v2 example
- Added PancakeSwap V3 on-chain snapshot validation via the Uniswap V3 pool reads
- Added PancakeSwap V3 pool-event parsers on BSC, Base, Arbitrum, and Ethereum
- Added Polymarket RTDS custom data subscriptions (#4214), thanks @graceyangfan
- Added Tardis Lighter venue mapping
- Added Tardis `options_chain` CSV loading, streaming, and catalog conversion
- Added Uniswap V3 `SetFeeProtocol` indexing so replayed snapshots carry the correct `fee_protocol`; run `make init-db`
- Added Uniswap V3 `CollectProtocol` indexing so pool snapshots track protocol-fee balances; run `make init-db`

### Breaking Changes
- Changed backtest config builders to validate on `build()` and return `ConfigResult` (Rust)
- Changed `BacktestDataConfig` to require an `instrument_id`, `instrument_ids`, or `bar_types` target
- Changed example strategy and actor configs to use bon `builder()` instead of `new()`/`with_*` (Rust)
- Changed Rust actor `self.clock()` to return `ClockApi`; call methods directly instead of borrowing
- Changed Rust actor/strategy core access; use macros or native traits instead of `Deref`
- Changed PyO3 `DataActor`/`Strategy` historical request `start`/`end` to require UTC datetimes
- Changed Python `NautilusDataType` enum order to put `OptionGreeks` before `InstrumentStatus`
- Changed cache database and message bus backing construction to use factory-owned config structs (Rust)
- Changed `CacheDatabaseAdapter::load_index_order_position` to return position IDs instead of positions (Rust)
- Changed default message bus/cache encoding to JSON; set `encoding="msgpack"` for MessagePack
- Changed Redis cache account/order/position storage to event logs; clear old typed state (Rust)
- Changed Rust message bus subscriber-count and presence queries to return invalid-topic errors instead of panicking
- Changed `SerializationEncoding` repr order to `Json=0`, `MsgPack=1`, `Capnp=2`, `Sbe=3`
- Changed Cap'n Proto `DataAny` ordinals to put `OptionGreeks` before instrument schemas
- Changed SBE `DataAny` variants and template IDs to put `OptionGreeks` before instrument schemas
- Changed `Currency::from_str` and `Currency::is_*` to return `CurrencyLookupError` instead of `anyhow::Error` (Rust)
- Changed `InstrumentId` and `OptionSeriesId` string constructors to return typed errors (Rust)
- Changed `OrderAny::from_events` to return `OrderReplayError` instead of `anyhow::Error` (Rust)
- Changed `OrderList::validate` to return `OrderListValidationError` instead of `anyhow::Error` (Rust)
- Changed `SyntheticInstrument` fallible methods to return `SyntheticInstrumentError` instead of `anyhow::Error` (Rust)
- Changed tick scheme constructors and parsing to return `TickSchemeError` instead of `anyhow::Error` (Rust)
- Changed Parquet catalog write APIs to take borrowed slices instead of owned `Vec` (Rust) (#4296), thanks @sunlei
- Changed WebSocket and socket `reconnect_timeout_ms` to bound only connection establishment (Rust)
- Changed plug-in loader to reject build mismatches by default; opt out with `set_allow_build_mismatch` (Rust)
- Changed Binance Spot SBE WebSocket API schema to version 3:4, matching generated codecs (Rust)
- Changed Blockchain `PoolProfiler.price_sqrt_ratio_x96` to return `int` instead of `str`
- Changed Bybit `BybitHttpClient::submit_order` to take trailing native TP/SL params; PyO3 defaults to `None`
- Removed `CacheConfig.database` and `MessageBusConfig.backing`; pass adapters separately
- Removed common `DatabaseConfig` and `MessageBusBackingConfig`; use Redis/Postgres configs
- Renamed message bus database terminology to backing in Rust message bus APIs
- Renamed `add_native_actor` to `add_builtin_actor` for bundled example actors
- Renamed `add_native_strategy` to `add_builtin_strategy` for bundled example strategies
- Renamed Rust/PyO3 instrument `tick_scheme_name` to `tick_scheme`; Cython keeps `tick_scheme_name`
- Renamed `BitmexInstrumentType::StockPerpetual` to `TradFiPerpetual` (covers equities, FX, and commodities)

### Security
- Hardened Docker toolchain pins
- Fixed instrument base quantity calculation panic on zero last price (Rust)
- Fixed tick scheme navigation panics on NaN, infinite, and out-of-range prices (Rust)
- Fixed domain value conversions to reject invalid numeric inputs instead of panicking (Rust)
- Fixed plug-in host callbacks to return `Panic` errors instead of aborting the node on engine panics (Rust)
- Fixed plug-in `create`, `clone_handle`, and `drop_handle` panics to recover instead of aborting the process (Rust)
- Fixed plug-in host thunks to validate UTF-8 on plug-in strings instead of assuming it (Rust)
- Fixed plug-in loader rejection paths to cap diagnostic reads and never `dlclose` initialized cdylibs (Rust)
- Fixed event-store replay panic on captured fills carrying an invalid order side (Rust)
- Fixed Interactive Brokers disconnect reconciliation corrupting position state (#4230), thanks @HKOWL

### Fixes
- Fixed account-currency PnL stats for NETTING accounts reusing a `PositionId` across cycles (#4294), thanks @faysou
- Fixed account-currency trade PnL stats for foreign-currency instruments (#4211), thanks @faysou
- Fixed blocking Python HTTP functions holding the GIL for the full request duration
- Fixed custom `DataType` metadata ordering and shared custom-data unsubscribes (Rust)
- Fixed data option-chain delta warmup
- Fixed `DataEngine` synthetic bar subscriptions with multiple venue clients (#4279), thanks for reporting @HSGartley
- Fixed DeFi pool profiler swap replay diverging from on-chain state at MIN/MAX-tick boundary swaps (Rust)
- Fixed DeFi replay bootstrap gaps in `PoolSwap` payload exposure, block timestamp units, and actor IDs (Rust)
- Fixed `DonchianChannel` period window (#4239), thanks @KaizynX
- Fixed event-store boot recovery to repair hard-crashed run files and skip damaged ones instead of failing (Rust)
- Fixed event-store capture duplicating order events, commands, and account states across dispatch hops (Rust)
- Fixed event-store snapshot-anchor validation across the verifier, retention, and restore paths (Rust)
- Fixed event-store replay, scan, marker, and halt-signal edge cases around skipped events, gaps, and reruns (Rust)
- Fixed HTTP client errors discarding the underlying cause from the reqwest source chain (Rust)
- Fixed `HttpClient` rejecting invalid response header keys instead of silently dropping them (Rust)
- Fixed `Instrument` rejecting negative `min_price`, preventing spread instruments from loading in Python
- Fixed live external order claim registration in Rust
- Fixed live reconciliation logging below-cached fill mismatches as errors, halting `shutdown_on_error` nodes (Rust)
- Fixed live reconciliation logging transient venue report-query failures as errors (Rust)
- Fixed live reconciliation synthesizing phantom cancels on cancel-replace venues (#4288), thanks @filipmacek
- Fixed local catalog queries and backtests for non-ASCII instrument IDs (#4259), thanks for reporting @seungpyoson
- Fixed matching engine fill commission side in Rust
- Fixed portfolio account update scoping in Rust
- Fixed PyO3 domain `from_raw` methods panicking on invalid input instead of raising `ValueError`
- Fixed rate limiter arithmetic to saturate so extreme quotas deny instead of admitting every request (Rust)
- Fixed reconnect backoff jitter collapsing to zero at the maximum delay (Rust)
- Fixed reconnect timeout cancelling the writer swap and replaying buffered messages into a readerless connection (Rust)
- Fixed recoverable order, commission, and PnL conditions logging as errors, halting `shutdown_on_error` nodes (Rust)
- Fixed Postgres order-client index load panic on orders persisted without a client ID (Rust)
- Fixed Postgres cache writer runtime
- Fixed risk sizing without max quantity in Rust
- Fixed Redis order updates to persist events before index replay can fail (Rust)
- Fixed `RiskEngine` bypass to also skip modify-order risk checks (#2330), thanks for reporting @fabz1
- Fixed socket client `close` stalling on and regressing an already closed client (Rust)
- Fixed socket reconnect confirmation hanging when a stalled peer blocks the buffer drain (Rust)
- Fixed stream-mode WebSocket clients accepting a zero heartbeat interval (Rust)
- Fixed streaming index prices and PyO3 mark, index, and funding data paths
- Fixed per-instrument streaming paths for `MarkPriceUpdate` (#4267), thanks @graceyangfan
- Fixed TLS client authentication silently dropped for combined key and certificate PEM files (Rust)
- Fixed `TwapAlgorithm` rejecting primary orders already cached by the engine submit path (Rust)
- Fixed `TwapAlgorithm` time event and lifecycle dispatch so all scheduled slices execute (Rust)
- Fixed unbounded WebSocket initial connection wait against servers that never complete the upgrade (Rust)
- Fixed WebSocket and socket writer failure paths overwriting a concurrent disconnect with a reconnect (Rust)
- Fixed WebSocket auth and connection-state waiters missing wakeups from unregistered `Notify` futures (Rust)
- Fixed WebSocket idle timeout starvation under control-frame floods faster than the check interval (Rust)
- Fixed Docker image build missing the `patches` directory needed by `pyo3-stub-gen`
- Fixed nightly CI publish and Windows Harden-Runner checks
- Fixed Architect AX to deny invalid submits locally and defer ambiguous command failures to reconciliation
- Fixed Binance Futures empty algo order IDs
- Fixed Binance Futures hedge reduce-only orders in Rust
- Fixed Binance Futures leverage initialization aborting execution client connect (#4289), thanks @YeeTsai
- Fixed Binance Futures node panic on `BNFCR` Credits Trading Mode balances
- Fixed Binance Spot expired order handling
- Fixed Binance Spot/Futures WebSocket connection pool race (#4244), thanks @filipmacek
- Fixed Binance HTTP client handling of non-JSON success responses during demo/testnet reconciliation
- Fixed BitMEX instrument bootstrap aborting on any row deserialize failure (#4283), thanks for reporting @seungpyoson
- Fixed Blockchain snapshot bootstrap checks
- Fixed Blockchain pool-event replay to require durable timestamps before checkpoints
- Fixed Blockchain pool sync aborting on swaps with an unrepresentable spot price
- Fixed Blockchain pool profiler logging self-correcting tick and liquidity mismatches at error severity (now warn)
- Fixed Blockchain snapshot validation rejecting fee-protocol-only mismatches
- Fixed Bybit demo native TP/SL and option params routing through the create-order endpoint (Rust and Python)
- Fixed Deribit chart bar volume for inverse perpetuals (#4245), thanks @filipmacek
- Fixed dYdX Indexer WebSocket dropping subscriptions beyond the 32-per-channel cap (#4290), thanks @filipmacek
- Fixed dYdX to share one REST rate-limit bucket across data and execution clients (#4265), thanks @filipmacek
- Fixed dYdX to deny unsupported submits locally and emit rejections only for definitive CheckTx refusals
- Fixed Hyperliquid bracket-child statuses and atomic fills orphaning orders (#4160), thanks @sonnymai
- Fixed Hyperliquid cancel-replace fill stranding on a dropped `ACCEPTED` (#4270), thanks for reporting @AlphaTraderK
- Fixed Hyperliquid order status queries surfacing a stale cancel closing a live order mid-modify (Rust)
- Fixed Interactive Brokers reconnect startup handling (#4210), thanks @faysou
- Fixed Interactive Brokers PERM cancel/modify routing and pending commission parsing (#4281), thanks @faysou
- Fixed Interactive Brokers to use `permId` for stable order identity (#4276), thanks @faysou
- Fixed Interactive Brokers to deny not-ready submits locally and drop synthetic cancel/modify rejections
- Fixed Kraken spot WebSocket dead-connection detection with an idle timeout (#4275), thanks @folknor
- Fixed Kraken count-only bar requests returning oldest bars instead of latest (#4274), thanks @folknor
- Fixed Lighter AccountState to include perp-side margin balance (#4246), thanks @filipmacek
- Fixed Lighter cancel and modify rejections for local, venue, and acked no-op failures
- Fixed Lighter concurrent batch nonce-ordering race (#4263), thanks @filipmacek
- Fixed Lighter maker-only key lookup authentication (#4234), thanks @filipmacek
- Fixed Lighter positions falsely flattening on malformed snapshots
- Fixed Lighter WebSocket clients exceeding shared venue rate limits (#4282), thanks @filipmacek
- Fixed Lighter nonce exhaustion halting order flow after 16 transactions per connection
- Fixed Lighter nonce recovery after venue rejections wedging subsequent transactions
- Fixed OKX instrument parsing for malformed venue payloads
- Fixed OKX conditional and attached TP/SL algo amend fields (#4268), thanks @jhavie
- Fixed Polymarket batch submit node panic on a venue-rejected leg (empty order ID); now emits `OrderRejected`
- Fixed Polymarket instrument expiration precision for Gamma markets (#4278), thanks for reporting @OnlyC
- Fixed Polymarket expired instruments re-entering live data paths (#4272), thanks @graceyangfan
- Fixed Polymarket marketable BUY fills above nominal size dropped as overfills (Rust)
- Fixed Polymarket marketable fills orphaning when a WS trade beats the submit response (Rust)
- Fixed Polymarket post-only crossing rejections not setting `due_post_only`

### Internal Improvements
- Added Cargo publish dry-run and nightly publish plan checks
- Added a Docker check that Python references match the base image tag and `requires-python`
- Added turmoil coverage for WebSocket heartbeats, server-initiated pings, and server close frames (Rust)
- Improved instrument validation to reject non-positive multiplier and lot size (Rust)
- Improved `FixedTickScheme` validation to reject non-finite tick sizes (Rust)
- Improved release verifier retries and manual-publish recovery checks
- Improved network crate property tests with window-budget, full-domain arithmetic, and jitter-spread checks (Rust)
- Improved retry budget-exceeded errors to include the last underlying error (Rust)
- Improved plug-in ABI-mismatch reporting with manifest diagnostics instead of a null-manifest error (Rust)
- Improved `nautilus_plugin!` macro errors for missing `name` or `version` fields (Rust)
- Improved event-store marker writer and capture diagnostics with logged fail-stop errors (Rust)
- Improved Postgres order-client index restore to pick the latest client ID per order (Rust)
- Improved OTO contingency position ID recovery to persist re-indexed assignments (Rust)
- Improved backtest expiration timers and `TestClock` advancement performance (#4307), thanks @faysou
- Improved sandbox expired-instrument retention to prune after open positions settle (#4293), thanks @graceyangfan
- Improved Polymarket data client module structure (#4260), thanks @graceyangfan
- Improved Polymarket execution lookup retention for expired instruments (#4287), thanks @graceyangfan
- Improved Polymarket execution module structure (#4271), thanks @graceyangfan
- Improved Polymarket resolution module structure (#4269), thanks @graceyangfan
- Optimized `Cache` query filtering to scale with open orders and positions (#4242), thanks for reporting @magnified103
- Refined common clock reference-counted clone calls (#4302), thanks @learnerLj
- Standardized Rust `OrderDenied` reason codes
- Standardized Betfair adapter to emit order events for own orders and reports for external orders only (Rust)
- Standardized Polymarket adapter to emit order events for own orders and reports for external orders only (Rust)
- Upgraded Interactive Brokers Rust adapter to `ibapi` 3.0.1 (#4209), thanks @faysou
- Upgraded `pandas` to v3.0 and widened the supported range to `<4.0.0`
- Upgraded `capnp` and `capnpc` crates to v0.26.0
- Upgraded `redis` crate to v1.2.4
- Upgraded `pyo3` and `pyo3-async-runtimes` crates to v0.29.0

### Documentation Updates
- Added developer-guide rate-limiting policy distinguishing data and execution paths
- Added Binance COIN-M/USD-M architecture docs for stream, REST, rate-limit, and position-mode changes
- Updated plugins concept guide for panic recovery, build pinning, and UTF-8 validation semantics
- Updated event sourcing guide for capture dedup, recovery resilience, and snapshot-anchor verification
- Updated message bus docs for publisher forwarding, payload encoding, and JSON defaults
- Updated message bus docs for backing terminology and inbound subscriber shape
- Updated cache and message bus docs for technology-owned config factories
- Updated commodity instrument and execution concept guides for negative price support
- Updated OKX integration docs with EEA endpoint override guidance (#4250), thanks for reporting @msnatm-code











































<!-- release-checksums:start -->
## Artifact checksums

SHA256 checksums are attached as `SHA256SUMS`, per-asset `.sha256` files, and `dist-manifest.json`.

| Artifact | SHA256 |
| --- | --- |
| [nautilus_trader-1.229.0-cp312-cp312-macosx_15_0_arm64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp312-cp312-macosx_15_0_arm64.whl) | 4428b50bd7670585744faab5c7a2e0a5d7abd60d6a0e39371fc57e8e30a84c54 |
| [nautilus_trader-1.229.0-cp312-cp312-manylinux_2_35_aarch64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp312-cp312-manylinux_2_35_aarch64.whl) | 31f605049465bb62f36d0edc302c664aa7f79f940c251a67a11e212fa308e700 |
| [nautilus_trader-1.229.0-cp312-cp312-manylinux_2_35_x86_64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp312-cp312-manylinux_2_35_x86_64.whl) | 4f374e8d76fd797c34c438b7c73cbe5ea3a0b58af236352544ccab8890c15db7 |
| [nautilus_trader-1.229.0-cp312-cp312-win_amd64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp312-cp312-win_amd64.whl) | f559a382d635f191a0f86623ec8366c05e2175b7d3e14627145f6cd762091280 |
| [nautilus_trader-1.229.0-cp313-cp313-macosx_15_0_arm64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp313-cp313-macosx_15_0_arm64.whl) | 94b7d129d9bbb8dda96177c098ea4a8ccc03a14f47afba6e662c8343503c0316 |
| [nautilus_trader-1.229.0-cp313-cp313-manylinux_2_35_aarch64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp313-cp313-manylinux_2_35_aarch64.whl) | c86e9cd815e0d5d9adec974bffa899ba89db1127cbbab582cfe99f91c9f5fae2 |
| [nautilus_trader-1.229.0-cp313-cp313-manylinux_2_35_x86_64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp313-cp313-manylinux_2_35_x86_64.whl) | 6b9c9cd8a5d6f1217e97840a1daf9e2dd4025f13b918f53c5c436f61fda0f4cb |
| [nautilus_trader-1.229.0-cp313-cp313-win_amd64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp313-cp313-win_amd64.whl) | ec96c757970829e89bd8a2fe561a9289d3972a76ec67add360cd9459123670b5 |
| [nautilus_trader-1.229.0-cp314-cp314-macosx_15_0_arm64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp314-cp314-macosx_15_0_arm64.whl) | abbb725911b836318112bfd9dd39b78efd1defe7ece592c72b46c738db858fb8 |
| [nautilus_trader-1.229.0-cp314-cp314-manylinux_2_35_aarch64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp314-cp314-manylinux_2_35_aarch64.whl) | 789f301e3ade397e0445c5d1bb3f03588e8416f862583f23ad3bec518bbca08b |
| [nautilus_trader-1.229.0-cp314-cp314-manylinux_2_35_x86_64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp314-cp314-manylinux_2_35_x86_64.whl) | 462875147ee1180ae4a736adb99daf88e31aa5c5ab7045a257b5928ff58f43ff |
| [nautilus_trader-1.229.0-cp314-cp314-win_amd64.whl](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0-cp314-cp314-win_amd64.whl) | 435d0c3856a9082026d13d6d3a7b221dfc93aa2924317980696c207b4220c8cf |
| [nautilus_trader-1.229.0.tar.gz](https://github.com/nautechsystems/nautilus_trader/releases/download/v1.229.0/nautilus_trader-1.229.0.tar.gz) | 0006fded769a80fc7199bb0c73b1c362e66be39e2f206d4d8e57149ecb0e196a |

### Verify provenance

After downloading an artifact, verify its GitHub artifact attestation:

```bash
gh attestation verify <artifact> \
  --repo nautechsystems/nautilus_trader \
  --cert-identity "https://github.com/nautechsystems/nautilus_trader/.github/workflows/build.yml@refs/heads/master" \
  --cert-oidc-issuer https://token.actions.githubusercontent.com
```

<!-- release-checksums:end -->


### Release completion note
The automated `publish-release-integrity` job did not complete for this release. PyPI and
crates.io publishing completed, and the published PyPI artifacts verified locally with fresh
Sigstore trust metadata. GitHub-hosted CI continued to fail while verifying
`nautilus_trader-1.229.0-cp312-cp312-macosx_15_0_arm64.whl` because
`pypi-attestations` repeatedly rejected a Sigstore transparency-log checkpoint with
`Signature not found for log ID c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d`.

The final integrity assets, including `crates-manifest.json` and attestation sibling files,
were attached manually after the same registry verification passed outside GitHub-hosted CI.