Short answer: Nautilus Trader (NautilusTrader) is an LGPL-3.0 trading engine with a Rust core and Python as its control plane. As of 6 November 2026 a plain pip install nautilus_trader installs 1.231.0, while the official documentation describes the 2.x line, which needs --pre (2.0.0rc8), so code from the docs fails on the default install. It has no UI by design, the project advises against release candidates for live trading with real capital, and it is an engine to build on rather than a bot you can simply start.
Code from the NautilusTrader documentation fails with an ImportError on a default install, because the package name stayed the same while the API changed. What follows comes from the project's documentation and repository, read on 6 November 2026, and from installing both versions in clean virtual environments on Windows 11 that day.
The sample places one fixed order on made-up bars to show events and fills, so it is not a strategy and says nothing about performance. This guide recommends neither the software nor any venue, and automated trading can lose money.
Nautilus Trader Python versions: the pip trap
Decide which line you are using before writing any code, because 1.x and 2.x share a package name but not an API.
| Item | pip install -U nautilus_trader | pip install -U nautilus_trader --pre |
|---|---|---|
| Version installed | 1.231.0 (PyPI, 2 August 2026) | 2.0.0rc8 (PyPI, 29 October 2026) |
| Documented quickstart | Failed: cannot import OrderSide from nautilus_trader.model | Ran after adding NumPy and pandas |
| Other packages pulled in | 13, including pandas, NumPy and PyArrow | None |
BacktestEngine lives in | nautilus_trader.backtest.engine | nautilus_trader.backtest |
Generic on_event hook | Available | Removed; use on_order_event, on_position_event or on_time_event |
| Project's stated status | Latest stable v1 wheel; only critical security backports, for about three months after the v2 cutover | Release candidates for community testing, not recommended for live trading with real capital |
That last row is the real decision: the documentation covers a line the project does not yet recommend for real capital, while v1 is limited to security backports. No date for a final 2.0.0 appeared on the pages read. Keep each line in its own virtual environment, as the migration guide insists, and pin the exact version.
Two more traps surfaced in testing. The release-candidate wheel declares no required dependencies, so on a clean install report generation stops with an ImportError naming pandas; only the quickstart's prerequisites tell you to add NumPy and pandas. Supported Python versions also differ by page, as the FAQ below shows. Both lines ran on Windows 11 Home here, though the installation page lists Windows Server 2022 and later.
NautilusTrader tutorial: one fixed order on synthetic bars
The shortest useful test is a stub that buys on one fixed bar and closes on another, because it shows the event order and exactly where each fill lands.
Install with pip install -U nautilus_trader --pre, then pip install pandas. This ran on 2.0.0rc8 with Python 3.13.18 and 3.14.10, using made-up prices:
from decimal import Decimal
import nautilus_trader
from nautilus_trader.backtest import BacktestEngine
from nautilus_trader.common import LogLevel
from nautilus_trader.config import BacktestEngineConfig, LoggerConfig, StrategyConfig
from nautilus_trader.execution import MakerTakerFeeModel
from nautilus_trader.model import (AccountType, Bar, BarType, Currency, CurrencyPair, InstrumentId,
Money, OmsType, OrderSide, Price, Quantity, Symbol, Venue)
from nautilus_trader.trading import Strategy
SIM, USD = Venue("SIM"), Currency.from_str("USD")
PAIR = CurrencyPair(
instrument_id=InstrumentId.from_str("EUR/USD.SIM"), raw_symbol=Symbol("EUR/USD"),
base_currency=Currency.from_str("EUR"), quote_currency=USD, price_precision=5, size_precision=0,
price_increment=Price.from_str("0.00001"), size_increment=Quantity.from_int(1), ts_event=0, ts_init=0,
lot_size=Quantity.from_int(1_000), margin_init=Decimal("0.03"), margin_maint=Decimal("0.03"))
BAR = BarType.from_str("EUR/USD.SIM-1-MINUTE-LAST-EXTERNAL")
ROWS = [("1.10000", "1.10010", "1.09990", "1.10005"), ("1.10006", "1.10030", "1.10000", "1.10020"),
("1.10022", "1.10025", "1.10000", "1.10010"), ("1.10012", "1.10060", "1.10010", "1.10050"),
("1.10052", "1.10055", "1.10020", "1.10030"), ("1.10031", "1.10045", "1.10025", "1.10040")]
T0, MINUTE = 1_767_225_600_000_000_000, 60_000_000_000 # synthetic 1-minute bars
bars = [Bar(bar_type=BAR, open=Price.from_str(o), high=Price.from_str(h), low=Price.from_str(l),
close=Price.from_str(c), volume=Quantity.from_int(1_000_000),
ts_event=T0 + i * MINUTE, ts_init=T0 + i * MINUTE) for i, (o, h, l, c) in enumerate(ROWS)]
class OneOrder(Strategy): # a stub with fixed bars, not a trading rule
seen = 0
def on_start(self):
self.subscribe_bars(BAR)
def on_bar(self, bar):
self.seen += 1
if self.seen == 2:
self.submit_order(self.order_factory.market(PAIR.id, OrderSide.BUY, Quantity.from_int(100_000)))
elif self.seen == 4:
self.close_all_positions(PAIR.id)
def on_order_event(self, event):
print(type(event).__name__)
def on_position_event(self, event):
print(type(event).__name__)
engine = BacktestEngine(config=BacktestEngineConfig(logging=LoggerConfig(stdout_level=LogLevel.ERROR)))
engine.add_venue(venue=SIM, oms_type=OmsType.NETTING, account_type=AccountType.MARGIN,
starting_balances=[Money(1_000_000, USD)], base_currency=USD, default_leverage=Decimal(1),
fee_model=MakerTakerFeeModel(maker_rate=Decimal(0), taker_rate=Decimal(0)))
engine.add_instrument(PAIR)
engine.add_data(bars)
engine.add_strategy(OneOrder(StrategyConfig()))
engine.run()
print(nautilus_trader.__version__)
fills = engine.generate_order_fills_report()
print(fills[["side", "filled_qty", "avg_px"]].to_string(index=False) if len(fills) else "no fills")
print(engine.generate_account_report(venue=SIM).iloc[-1]["total"])
engine.dispose()Output:
OrderInitialized
OrderSubmitted
OrderFilled
PositionOpened
OrderInitialized
OrderSubmitted
OrderFilled
PositionClosed
2.0.0rc8
side filled_qty avg_px
BUY 100000 1.10020
SELL 100000 1.10050
1000030.00Reading the output (synthetic data, zero fees). The buy filled at 1.10020 and the sell at 1.10050, the closes of the bars on which on_bar fired. 100,000 x 0.00030 = 30, so the balance moved from 1,000,000 to 1,000,030. This only shows the arithmetic is right, not that anything would earn money.
The bar-execution page says the engine runs each bar's open, high, low and close before calling on_bar, so without a latency model an order submitted there settles against the book left at that bar's close. There is no native next-bar-open fill mode, and the page warns that using the current bar's open from on_bar introduces look-ahead, since that bar has already been processed. Backtrader defaults to the next open, as the backtrader and vectorbt test shows, so results will not match across tools until this is aligned. Ported to the 1.231.0 API, the stub produced the same events and fill prices.
The project's next steps are its low-level BacktestEngine and high-level BacktestNode tutorials. Other libraries are compared in backtesting Python libraries.
How NautilusTrader is built: Rust core, Python control plane
NautilusTrader runs a Rust core with Python strategies on top, and its architecture page describes a design that expects failures and recovers through reconciliation.
- Single-threaded core. Within a node, messages are consumed and dispatched on one thread, one at a time.
- Message bus. Components communicate through a central bus using publish/subscribe, request/response and typed command and event messages.
- Crash-only behavior for unrecoverable faults. Release builds abort on panic and expect an external supervisor to restart the process, so a supervisor is part of your deployment. Normal operation still favors graceful shutdown.
- Reconciliation. The page says venue commands are not generally safe to retry blindly. The live page adds that cached order and position state is aligned with venue reports before trader components start, and checks can continue while the node runs.
- One node per process. Concurrent
LiveNodeorBacktestNodeinstances in one process are unsupported, so parallel work means separate processes.
Redis is optional, used only if you configure it as the cache or message bus backend, with version 6.2 as the stated minimum. General design choices for any bot are in trading bot development.
NautilusTrader adapters and what their status means
The project labels each integration planned, building, beta or stable; the labels are its own judgment, not tested here.
| Status | Type | Names |
|---|---|---|
| Stable | Crypto, centralized | Binance, Bybit, Coinbase, Deribit, Kraken, OKX |
| Crypto, decentralized | Derive, dYdX, Hyperliquid, Lighter, Lighter on Robinhood | |
| Broker and derivatives venue | AX Exchange, Interactive Brokers | |
| Data | Blockchain, Databento, Tardis | |
| Beta | Data | CoinAPI |
| Building | Data | FinFeed |
By the project's definitions, stable means a stable feature set and API tested by developers and users to a reasonable level, beta means minimally working and in testing, and building means likely not usable yet. Labels move: that day the develop README already listed FinFeed as beta, while the documentation and the master README still said building. A label is about the adapter, not about whether you may use a venue. That depends on your jurisdiction and the venue's terms, and futures or leveraged products are a separate regulated question. For readers in Turkey, Article 99/A of Capital Markets Law No. 6362 treats activity by foreign crypto-asset platforms directed at Turkish residents as unauthorized. A listing here is not a recommendation, and a data provider's data carries its own license. For venues with no adapter, see broker API integration.
Does NautilusTrader have a UI or dashboard?
No, and it is not planned for the open-source engine: the roadmap lists UI dashboards and frontends as out of scope.
The same list excludes a built-in distributed backtest runner, integrated hyperparameter optimization or built-in AI/ML tooling, and further external integrations such as cloud services, databases and monitoring tools unless explicitly listed. What exists is backtest visualization, with Plotly tearsheets through the visualization extra, which the roadmap distinguishes from full dashboards. Anything an operator watches live, you build or connect yourself. The home page separately lists a Pro tier on a waitlist and a cloud platform in development, with no prices; neither was tried.
Where it can fail: backtest and live are not the same
The documentation warns that a simulation may not reproduce live behavior, so shared strategy code does not remove the need for live-environment testing.
- Unknown outcomes. The live page says a network failure can leave an order command's outcome unknown, and its shutdown notes say a submission acknowledgement does not prove that a cancel or update completed or that positions are flat.
- Activity outside the node. Venue reports can include orders created outside the node.
- No backpressure. Runner channels neither slow producers nor cap queue depth, and the documented queue thresholds are signals rather than guarantees.
- Migration gaps. The v2 migration guide's known limitations include a PostgreSQL cache that does not persist actor or strategy state (Redis backing does), and its catalog section says legacy Parquet files must be migrated before v2 can query them.
Test these cases before any real order. The controls to put around an engine are in trading bot risk management.
What a team must build around NautilusTrader
Expect to supply everything outside the engine, plus people comfortable with event-driven code.
| Area | What it involves |
|---|---|
| Rules | Your own written rules, in Python or Rust |
| Process supervision | A supervisor that restarts after an abort, with one live node per process |
| Monitoring | Dashboards, alerts and monitoring-tool integration, all outside the roadmap's scope |
| Data | Sourcing, licensing and loading data, plus catalog migration between versions |
| Upgrades | Tracking release notes; a formal deprecation process is planned only once the 2.x API is stable |
| Keys | Storage and permissions, as in API key security |
| Adapters | A venue not listed needs one. In v2 the built-in adapter classes are Rust/PyO3, so Rust skills help |
For integration work in general, see Fincode's algorithmic trading page; naming NautilusTrader or any venue here does not mean Fincode integrates it or has built on it.
NautilusTrader on GitHub: license and branches
The code is at nautechsystems/nautilus_trader under LGPL-3.0, and contributions require a contributor license agreement.
develop is the default branch, so the README you see first describes unreleased work. On 6 November 2026 GitHub marked v1.231.0 (2 August 2026) as the latest release and 2.0.0rc8 as a pre-release. The documents conflict on one point: the README calls master recommended for production, yet master's version file read v2.0.0rc8 that day and the same README advises against release candidates for real capital. Roughly, LGPL-3.0 lets your own separate code keep its license if you meet the library's conditions when you distribute it, while changes to the library stay under LGPL. This is not legal advice.
Frequently asked questions
Why does the NautilusTrader quickstart fail with an ImportError?
Without --pre, pip installs 1.231.0, but the documentation describes 2.x. On 6 November 2026 the quickstart failed on 1.231.0 and ran on 2.0.0rc8 after adding NumPy and pandas, as its prerequisites say.
What Python version does NautilusTrader need?
On 6 November 2026 the installation page, the master README and PyPI's metadata for 2.0.0rc8 listed Python 3.13 to 3.14, while the develop README listed 3.13 to 3.15, with 3.15 needing a source build or development wheel. Version 1.231.0 on PyPI also accepts 3.12.
Does NautilusTrader have a UI?
No. Its roadmap lists UI dashboards and frontends as out of scope for the open-source engine. It offers backtest tearsheets through an optional extra.
Is NautilusTrader a bot I can just run?
No. It is an engine: you write the rules and build the deployment, supervision and monitoring around it.
Is NautilusTrader free for commercial use?
The source is available under LGPL-3.0, which allows commercial use under its conditions. Ask a lawyer how those conditions apply to a product you distribute.
Sources
- NautilusTrader on GitHub: README on the default develop branch (versions, install, status scale, license) (opens in a new tab)
- NautilusTrader README on the master branch (Python 3.13-3.14, branches, release candidate warning) (opens in a new tab)
- NautilusTrader: Migrate from v1 to v2 (import paths, on_event removal, separate environments, known limitations) (opens in a new tab)
- NautilusTrader ROADMAP (open-source scope, UI out of scope) (opens in a new tab)
- NautilusTrader docs: Installation (Python, platforms, --pre, Redis) (opens in a new tab)
- NautilusTrader docs: Quickstart (opens in a new tab)
- NautilusTrader docs: Bar-based execution (OHLC sequence, fills from on_bar, look-ahead) (opens in a new tab)
- NautilusTrader docs: Architecture (single thread, message bus, crash-only, reconciliation) (opens in a new tab)
- NautilusTrader docs: Live trading (differences from simulation, reconciliation, one node per process) (opens in a new tab)
- NautilusTrader LICENSE (GNU LGPL version 3) (opens in a new tab)
- NautilusTrader docs: Integrations (status of each adapter) (opens in a new tab)
- NautilusTrader home page (product tiers, disclaimer) (opens in a new tab)
- PyPI: nautilus_trader (1.231.0 and 2.0.0rc8 metadata) (opens in a new tab)
- NautilusTrader releases on GitHub (opens in a new tab)
- Capital Markets Law No. 6362, Article 99/A (Turkish, consolidated text) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.