[project] name = "nautilus-trader" version = "2.0.0rc4" description = "Production-grade Rust-native trading engine with deterministic event-driven architecture" authors = [{ name = "Nautech Systems", email = "info@nautechsystems.io" }] classifiers = [ "Operating System :: OS Independent", "Development Status :: 4 - Beta", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Rust", "Topic :: Software Development :: Libraries", "Topic :: Scientific/Engineering", "Topic :: Office/Business :: Financial", "Topic :: Office/Business :: Financial :: Investment", "Intended Audience :: Developers", "Intended Audience :: Financial and Insurance Industry", "Intended Audience :: Science/Research", ] license = "LGPL-3.0-only" license-files = ["LICENSE"] readme = "../README.md" requires-python = ">=3.12,<3.15" dependencies = [] [project.optional-dependencies] visualization = [ "pandas>=2.3.3,<4.0.0", "plotly>=6.9.0,<7.0.0", "kaleido>=1.3.0,<2.0.0", "simplejson>=4.1.1,<5.0.0", ] [project.urls] homepage = "https://nautilustrader.io" repository = "https://github.com/nautechsystems/nautilus_trader" docs = "https://nautilustrader.io/docs" [build-system] # Keep the maturin pin exact; scripts/maturin-version.bash uses it for CI wheel builds. requires = ["maturin==1.15.0", "patchelf"] build-backend = "maturin" [tool.maturin] manifest-path = "../crates/pyo3/Cargo.toml" module-name = "nautilus_trader._libnautilus" python-source = "." features = [ "extension-module", "arrow", "betfair", "high-precision", "mimalloc", "redis", "postgres", "defi", "hypersync", "tracing-bridge", ] strip = false include = ["**/*.pyi"] [tool.uv] required-version = ">=0.12,<0.13" environments = ["sys_platform != 'win32' or platform_machine == 'AMD64'"] exclude-newer = "7 days" # Remove after maturin 1.15.0 clears the global release cooldown exclude-newer-package = { maturin = "2026-08-24T12:12:00Z" } # Block sdist builds for every third-party package in python/uv.lock so # unexpected loss of wheel publishing fails `uv lock` instead of silently # building from source. Kept in sync with python/uv.lock by # scripts/check-no-build-packages.sh (also a pre-commit hook). The local # nautilus-trader package is intentionally absent because it must be built # by maturin. no-build-package = [ "accessible-pygments", "alabaster", "babel", "beautifulsoup4", "certifi", "charset-normalizer", "choreographer", "click", "colorama", "coverage", "docutils", "execnet", "furo", "h11", "idna", "imagesize", "iniconfig", "jinja2", "kaleido", "linkify-it-py", "logistro", "markdown-it-py", "markupsafe", "maturin", "mdit-py-plugins", "mdurl", "memray", "myst-parser", "narwhals", "numpy", "orjson", "packaging", "pandas", "platformdirs", "plotly", "pluggy", "psutil", "pygments", "pytest", "pytest-asyncio", "pytest-cov", "pytest-memray", "pytest-xdist", "python-dateutil", "pyyaml", "requests", "rich", "roman-numerals", "ruff", "simplejson", "six", "snowballstemmer", "soupsieve", "sphinx", "sphinx-basic-ng", "sphinx-comments", "sphinxcontrib-applehelp", "sphinxcontrib-devhelp", "sphinxcontrib-htmlhelp", "sphinxcontrib-jsmath", "sphinxcontrib-qthelp", "sphinxcontrib-serializinghtml", "textual", "ty", "typing-extensions", "tzdata", "uc-micro-py", "urllib3", "uvicorn", "uvloop", ] [dependency-groups] dev = ["maturin==1.15.0", "ruff>=0.16.4", "ty>=0.0.74"] test = [ "pytest>=9.1.1", "pytest-asyncio>=1.4.0", "pytest-cov>=7.1.0", "pytest-memray>=1.10.0; sys_platform == 'darwin' or sys_platform == 'linux'", "pytest-xdist[psutil]>=3.8.0", "uvicorn>=0.52.4", "uvloop>=0.22.1; sys_platform != 'win32'", ] docs = [ "furo==2025.12.19", "linkify-it-py>=2.1.0,<3.0.0", "myst-parser>=5.1.0,<6.0.0", "sphinx-comments>=0.0.3,<1.0.0", ] [tool.ruff] target-version = "py312" line-length = 100 exclude = [ "stubs/**", "nautilus_trader/_libnautilus.pyi", ".git", "../build", "../dist", "../.git", "../patches", "../target", "patches", ] [tool.ruff.lint] select = ["ALL"] ignore = [ "COM812", # Ruff formatter controls trailing commas "D200", # One-line docstrings use the multi-line form by convention (docformatter --make-summary-multi-line) "D203", # Conflicts with D211; ruff ignores D203 automatically, listed here to silence the warning "D212", # Multi-line docstring summaries start on the second line by convention (docformatter --pre-summary-newline); D213 applies instead "EM101", # Exception messages stay inline "EM102", # Exception messages stay inline "TRY003", # Exception messages stay inline ] # Allow autofix for all enabled rules (when `--fix`) is provided fixable = ["ALL"] # E4 = import-related rules (E401: multiple imports on one line, E402: module level import not at top) # E501 = line too long # UP006 = Use list instead of List for type annotation (field name 'list' shadows built-in in Bybit schemas) # UP035 = typing.List is deprecated (field name 'list' shadows built-in in Bybit schemas) # Autofix is disabled for these rules; any violations are fixed manually unfixable = ["E4", "E501", "UP006", "UP035"] # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.lint.per-file-ignores] "nautilus_trader/**/*.pyi" = [ "A002", "ANN401", "CPY001", "D", "E501", "F401", "N802", "PYI011", "RUF002", "RUF100", ] # Generated stubs mirror Rust API names and types; E501 stays in the generator header too "nautilus_trader/adapters/*/__init__.py" = [ "F405", ] # Adapter facades re-export star-imported names in __all__ "python/nautilus_trader/**/*.pyi" = [ "A002", "ANN401", "CPY001", "D", "E501", "F401", "N802", "PYI011", "RUF002", "RUF100", ] # Root-relative form used by repository-wide checks "python/nautilus_trader/adapters/*/__init__.py" = [ "F405", ] # Root-relative form used by repository-wide checks "docs/getting_started/**/*.py" = [ "B018", "CPY001", "D", "E402", "E501", "I001", "INP001", "PLR0913", "PLR0917", "S101", "T20", ] # TODO: Remove Jupytext exemptions as these guides are updated "docs/tutorials/**/*.py" = [ "ANN001", "B018", "CPY001", "D", "E402", "E501", "ERA001", "FBT002", "I001", "INP001", "N806", "PLR0913", "PLR0917", "PLR2004", "PLW2901", "S101", "T20", "TC003", ] # TODO: Remove Jupytext exemptions as these tutorials are updated "docs/how_to/**/*.py" = [ "B018", "CPY001", "D", "E402", "E501", "ERA001", "I001", "INP001", "S101", "T20", ] # TODO: Remove Jupytext exemptions as these guides are updated "docs/api_reference/conf.py" = [ "A001", "D100", "INP001", ] # Sphinx requires the `copyright` config variable name; a Sphinx config script is not a package "examples/**/*.py" = [ "A002", "ANN001", "ANN401", "CPY001", "DTZ", "E501", "FBT001", "FBT002", "FBT003", "INP001", "N806", "PLR0913", "PLR0917", "PLR2004", "S101", "S105", "S106", "T20", "TC003", ] # Examples are exempt from copyright headers (see check_copyright_year.sh) and can use asserts, mock credentials, and print "examples/backtest/notebooks/**/*.py" = [ "ERA001", ] # Jupytext notebook headers are not commented-out code "examples/backtest/model_configs_example.py" = [ "ERA001", ] # `node.run()` is left commented because the example ships no catalog data "examples/backtest/synthetic_data_pnl_test.py" = ["FURB171", "N802"] "examples/live/blockchain/actors.py" = [ "ERA001", "FIX002", "TD002", "TD003", ] # Optional timer demo is left commented on purpose "examples/live/interactive_brokers/_common.py" = ["S603"] "examples/live/polymarket/updown_smoke_tester.py" = ["TRY004"] "tests/**/*.py" = [ "A002", "ANN001", "ANN202", "ANN401", "ARG001", "ARG004", "ARG005", "ASYNC110", "BLE001", "E402", "E501", "E711", "FBT001", "FBT002", "FBT003", "INP001", "ISC004", "PLC0206", "PLC0415", "PLR0124", "PLR0913", "PLR0915", "PLR0917", "PLR2004", "PT019", "PTH103", "S101", "S105", "S106", "S301", "S603", "SLF001", "TC001", "TC003", ] # Tests can use asserts, mock credentials, private access, literal comparisons, and local imports "python/tests/**/*.py" = [ "A002", "ANN001", "ANN202", "ANN401", "ARG001", "ARG004", "ARG005", "ASYNC110", "BLE001", "E402", "E501", "E711", "FBT001", "FBT002", "FBT003", "INP001", "ISC004", "PLC0206", "PLC0415", "PLR0124", "PLR0913", "PLR0915", "PLR0917", "PLR2004", "PT019", "PTH103", "S101", "S105", "S106", "S301", "S603", "SLF001", "TC001", "TC003", ] # Root-relative form used by repository-wide checks "memray_tests/**/*.py" = [ "S101", ] # Memory tests use assertions like the main test suite "python/memray_tests/**/*.py" = [ "S101", ] # Root-relative form used by repository-wide checks "tests/unit/persistence/test_option_greeks_replay.py" = ["ERA001"] "python/tests/unit/persistence/test_option_greeks_replay.py" = [ "ERA001", ] # Comment mentions `__init__`; it is not commented-out code "nautilus_trader/analysis/tearsheet.py" = [ "ANN401", "PLC0415", "PLR0913", "PLR0917", "TRY004", ] "python/nautilus_trader/analysis/tearsheet.py" = [ "ANN401", "PLC0415", "PLR0913", "PLR0917", "TRY004", ] # Optional pandas import, chart callbacks, and ValueError for argument checks "nautilus_trader/analysis/reporter.py" = ["ANN401", "PLC0415"] "python/nautilus_trader/analysis/reporter.py" = ["ANN401", "PLC0415"] "nautilus_trader/core/datetime.py" = ["PLC0415"] "python/nautilus_trader/core/datetime.py" = ["PLC0415"] "nautilus_trader/testkit/providers.py" = ["ANN401", "PLC0415"] "python/nautilus_trader/testkit/providers.py" = ["ANN401", "PLC0415"] "generate_stubs.py" = ["S603", "T201"] "python/generate_stubs.py" = ["S603", "T201"] "generate_docstrings.py" = ["ARG001", "PLR0912", "PLR0915", "T201"] "python/generate_docstrings.py" = ["ARG001", "PLR0912", "PLR0915", "T201"] ".pre-commit-hooks/check_pyo3_names.py" = ["PLR0912", "PLR0915", "S603", "T201"] "scripts/check-example-imports.py" = ["T201"] "scripts/check-markdown-tables.py" = ["INP001"] "scripts/security-audit.py" = ["INP001"] "scripts/ci/check_commit_message.py" = ["S603", "T201"] "scripts/ci/test_*.py" = [ "S101", "S105", "S106", "S603", "T201", ] # Tests can use asserts and mock credentials "crates/adapters/*/tests/oracle-py/generate_oracle.py" = [ "PLR0913", "PLR0917", "SLF001", "T201", ] [tool.ruff.lint.flake8-annotations] # Renderer and callback signatures forward heterogeneous keyword arguments allow-star-arg-any = true [tool.ruff.lint.isort] force-single-line = true lines-after-imports = 2 split-on-trailing-comma = true known-first-party = ["nautilus_trader"] [tool.ruff.format] docstring-code-format = true [tool.ruff.lint.mccabe] max-complexity = 10 [tool.pytest.ini_options] testpaths = ["tests"] addopts = "-ra --new-first --failed-first" asyncio_mode = "strict" asyncio_default_fixture_loop_scope = "session" filterwarnings = ["ignore::UserWarning", "ignore::DeprecationWarning"]