A high-performance algorithmic trading platform and event-driven backtester
- Website: https://nautilustrader.io
- Docs: https://docs.nautilustrader.io
- Support: email@example.com
NautilusTrader is an open-source, high-performance, production-grade algorithmic trading platform, providing quantitative traders with the ability to backtest portfolios of automated trading strategies on historical data with an event-driven engine, and also deploy those same strategies live.
The platform is 'AI-first', designed to deploy models for algorithmic trading strategies developed using the Python ecosystem - within a highly performant and robust Python native environment. This helps to address the challenge of keeping the research/backtest environment consistent with the production live trading environment.
NautilusTraders design, architecture and implementation philosophy holds software correctness and safety at the highest level, with the aim of supporting Python native, mission-critical, trading system backtesting and live deployment workloads.
The platform is also universal and asset class agnostic - with any REST, WebSocket or FIX API able to be integrated via modular adapters. Thus, it can handle high-frequency trading operations for any asset classes including FX, Equities, Futures, Options, CFDs, Crypto and Betting - across multiple venues simultaneously.
- Fast: C-level speed through Rust and Cython. Asynchronous networking with uvloop
- Reliable: Type safety through Rust and Cython. Redis backed performant state persistence
- Flexible: OS independent, runs on Linux, macOS, Windows. Deploy using Docker
- Integrated: Modular adapters mean any REST, WebSocket, or FIX API can be integrated
- Advanced: Time in force
AT_THE_CLOSE, advanced order types and conditional triggers. Execution instructions
reduce-only, and icebergs. Contingency order lists including
- Backtesting: Run with multiple venues, instruments and strategies simultaneously using historical quote tick, trade tick, bar, order book and custom data with nanosecond resolution
- Live: Use identical strategy implementations between backtesting and live deployments
- Multi-venue: Multiple venue capabilities facilitate market making and statistical arbitrage strategies
- AI Agent Training: Backtest engine fast enough to be used to train AI trading agents (RL/ES)
nautilus - from ancient Greek 'sailor' and naus 'ship'.
The nautilus shell consists of modular chambers with a growth factor which approximates a logarithmic spiral. The idea is that this can be translated to the aesthetics of design and architecture.
Traditionally, trading strategy research and backtesting might be conducted in Python (or other suitable language), with the models and/or strategies then needing to be reimplemented in C, C++, C#, Java or other statically typed language(s). The reasoning here is to utilize the performance and type safety a compiled language can offer, which has historically made these languages more suitable for large trading systems.
The value of NautilusTrader here is that this reimplementation step is circumvented - as the critical core components of the platform have all been written entirely in Cython. Because Cython can generate efficient C code (which then compiles to C extension modules as native binaries), Python can effectively be used as a high-performance systems programming language - with the benefit being that a Python native environment can be offered which is suitable for professional quantitative traders and trading firms.
Python was originally created decades ago as a simple scripting language with a clean straight forward syntax. It has since evolved into a fully fledged general purpose object-oriented programming language. Based on the TIOBE index, Python is currently the most popular programming language in the world. Not only that, Python has become the de facto lingua franca of data science, machine learning, and artificial intelligence.
The language out of the box is not without its drawbacks however, especially in the context of implementing large performance-critical systems. Cython has addressed a lot of these issues, offering all the advantages of a statically typed language, embedded into Pythons rich ecosystem of software libraries and developer/user communities.
What is Cython?
Cython is a compiled programming language which aims to be a superset of the Python programming language, designed to give C-like performance with code that is written in Python - with optional C-inspired syntax.
The project heavily utilizes Cython to provide static type safety and increased performance for Python through C extension modules. The vast majority of the production code is actually written in Cython, however the libraries can be accessed from both pure Python and Cython.
What is Rust?
Rust is a multi-paradigm programming language designed for performance and safety, especially safe concurrency. Rust is blazingly fast and memory-efficient (comparable to C and C++) with no runtime or garbage collector. It can power mission-critical systems, run on embedded devices, and easily integrates with other languages.
Rust’s rich type system and ownership model guarantees memory-safety and thread-safety deterministically — eliminating many classes of bugs at compile-time.
The project increasingly utilizes Rust for core performance-critical components. Python language binding is handled through Cython, with static libraries linked at compile-time before the wheel binaries are packaged, so a user does not need to have Rust installed to run NautilusTrader. In the future as more Rust code is introduced, PyO3 will be leveraged for easier Python bindings.
Architecture (data flow)
NautilusTrader is designed in a modular way to work with 'adapters' which provide connectivity to data publishers and/or trading venues - converting their raw API into a unified interface. The following integrations are currently supported:
|Betfair||BETFAIR||Sports Betting Exchange||Guide|
|Binance||BINANCE||Crypto Exchange (CEX)||Guide|
|Binance US||BINANCE||Crypto Exchange (CEX)||Guide|
|Binance Futures||BINANCE||Crypto Exchange (CEX)||Guide|
|FTX||FTX||Crypto Exchange (CEX)||Guide|
|FTX US||FTX||Crypto Exchange (CEX)||Guide|
|Interactive Brokers||IB||Brokerage (multi-venue)||Guide|
Refer to the Integrations documentation for further details.
We recommend running the platform with the latest stable version of Python, and in a virtual environment to isolate the dependencies.
To install the latest binary wheel from PyPI:
pip install -U nautilus_trader
scipy on ARM architectures such as MacBook Pro M1 / Apple Silicon, this stackoverflow thread
Installation from source requires the
Python.h header file, which is included in development releases such as
You'll also need the latest stable
cargo to compile the Rust libraries.
It's possible to install from source using
pip if you first install the build dependencies
as specified in the
pyproject.toml. However, we highly recommend installing using poetry as below.
Install rustup (the Rust toolchain installer):
cargoin the current shell:
- Linux and macOS:
- Start a new PowerShell
- Linux and macOS:
Install poetry (or follow the installation guide on their site):
curl -sSL https://install.python-poetry.org | python3 -
Clone the source with
git, and install from the projects root directory:
git clone https://github.com/nautechsystems/nautilus_trader cd nautilus_trader poetry install --no-dev
Refer to the Installation Guide for other options and further details.
Versioning and releases
NautilusTrader is currently following a bi-weekly beta release schedule. The API is becoming more stable, however breaking changes are still possible between releases. Documentation of these changes in the release notes are made on a best-effort basis.
masterbranch will always reflect the source code for the latest released version
developbranch is normally very active with frequent commits and may contain experimental features. We aim to maintain a stable passing build on this branch
The current roadmap has a goal of achieving a stable API for a
2.x version. From this
point we will follow a formal process for releases, with deprecation periods for any API changes.
Makefile is provided to automate most installation and build tasks. It provides the following targets:
make install-- Installs the package using poetry
make build-- Runs the Cython build script
make clean-- Cleans all none source artifacts from the repository
make docs-- Builds the documentation HTML using Sphinx
make pre-commit-- Runs the pre-commit checks over all files
Indicators and strategies can be developed in both Python and Cython (although if performance and latency sensitivity is import we recommend Cython). The below are some examples of this:
- indicator example written in Python
- indicator examples written in Cython
- strategy examples written in both Python and Cython
- backtest examples using a
Docker containers are built using a base
python:3.10-slim with the following image variant tags:
nautilus_trader:latesthas the latest release version installed
nautilus_trader:develophas the head of the
jupyterlab:develophas the head of the
developbranch installed along with
jupyterlaband an example backtest notebook with accompanying data
The container images can be pulled as follows:
docker pull ghcr.io/nautechsystems/<image_variant_tag>
You can launch the backtest example container by running:
docker pull ghcr.io/nautechsystems/jupyterlab:develop docker run -p 8888:8888 ghcr.io/nautechsystems/jupyterlab:develop
Then navigate to the
backtest_example.ipynb and run it!
The following is a minimal EMA Cross strategy example which just uses bar data.
While trading strategies can become very advanced with this platform, it's still possible to put
together simple strategies. First inherit from the
Strategy base class, then only the
methods which are required by the strategy need to be implemented.
class EMACross(Strategy): """ A simple moving average cross example strategy. When the fast EMA crosses the slow EMA then enter a position at the market in that direction. Cancels all orders and closes all positions on stop. """ def __init__(self, config: EMACrossConfig): super().__init__(config) # Configuration self.instrument_id = InstrumentId.from_str(config.instrument_id) self.bar_type = BarType.from_str(config.bar_type) self.trade_size = Decimal(config.trade_size) # Create the indicators for the strategy self.fast_ema = ExponentialMovingAverage(config.fast_ema_period) self.slow_ema = ExponentialMovingAverage(config.slow_ema_period) self.instrument: Optional[Instrument] = None # Initialized in on_start def on_start(self): """Actions to be performed on strategy start.""" # Get instrument self.instrument = self.cache.instrument(self.instrument_id) # Register the indicators for updating self.register_indicator_for_bars(self.bar_type, self.fast_ema) self.register_indicator_for_bars(self.bar_type, self.slow_ema) # Get historical data self.request_bars(self.bar_type) # Subscribe to live data self.subscribe_bars(self.bar_type) def on_bar(self, bar: Bar): """Actions to be performed when the strategy receives a bar.""" # BUY LOGIC if self.fast_ema.value >= self.slow_ema.value: if self.portfolio.is_flat(self.instrument_id): self.buy() elif self.portfolio.is_net_short(self.instrument_id): self.close_all_positions(self.instrument_id) self.buy() # SELL LOGIC elif self.fast_ema.value < self.slow_ema.value: if self.portfolio.is_flat(self.instrument_id): self.sell() elif self.portfolio.is_net_long(self.instrument_id): self.close_all_positions(self.instrument_id) self.sell() def buy(self): """Users simple buy method (example).""" order: MarketOrder = self.order_factory.market( instrument_id=self.instrument_id, order_side=OrderSide.BUY, quantity=self.instrument.make_qty(self.trade_size), ) self.submit_order(order) def sell(self): """Users simple sell method (example).""" order: MarketOrder = self.order_factory.market( instrument_id=self.instrument_id, order_side=OrderSide.SELL, quantity=self.instrument.make_qty(self.trade_size), ) self.submit_order(order) def on_stop(self): """Actions to be performed when the strategy is stopped.""" # Cleanup orders and positions self.cancel_all_orders(self.instrument_id) self.close_all_positions(self.instrument_id) # Unsubscribe from data self.unsubscribe_bars(self.bar_type) def on_reset(self): """Actions to be performed when the strategy is reset.""" # Reset indicators here self.fast_ema.reset() self.slow_ema.reset()
We aim to provide the most pleasant developer experience possible for this hybrid codebase of Python, Cython and Rust. Please refer to the Developer Guide for helpful information.
Involvement from the trading community is a goal for this project, all help is welcome! Developers can open issues on GitHub to discuss proposed enhancements, changes, or to make bug reports. Questions and more general thoughts are best directed to a discussions thread.
Refer to the CONTRIBUTING.md for further information.
Please make all pull requests to the
Chat with contributors and active users of NautilusTrader on our Discord server! This is also the best place to monitor announcements, and learn about the latest features as they become available.
NautilusTrader is licensed under the GNU Lesser General Public License v3.0.
Contributors are also required to sign a standard Contributor License Agreement (CLA), which is administered automatically through CLA Assistant.
Copyright (C) 2015-2022 Nautech Systems Pty Ltd. All rights reserved. https://nautilustrader.io
Release history Release notifications | RSS feed
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Hashes for nautilus_trader-1.147.1-cp310-cp310-win_amd64.whl
Hashes for nautilus_trader-1.147.1-cp310-cp310-manylinux_2_31_x86_64.whl
Hashes for nautilus_trader-1.147.1-cp310-cp310-macosx_10_16_x86_64.whl
Hashes for nautilus_trader-1.147.1-cp39-cp39-win_amd64.whl
Hashes for nautilus_trader-1.147.1-cp39-cp39-manylinux_2_31_x86_64.whl
Hashes for nautilus_trader-1.147.1-cp39-cp39-macosx_10_16_x86_64.whl
Hashes for nautilus_trader-1.147.1-cp38-cp38-win_amd64.whl
Hashes for nautilus_trader-1.147.1-cp38-cp38-manylinux_2_31_x86_64.whl
Hashes for nautilus_trader-1.147.1-cp38-cp38-macosx_10_16_x86_64.whl