Skip to content

Commit c05f692

Browse files
authored
1.102.1
2 parents ad0dbda + f833a6a commit c05f692

File tree

106 files changed

+326
-214
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+326
-214
lines changed

.flake8

+1-9
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ exclude =
2424
dist
2525
docs
2626
noxfile.py
27-
ignore = E225, E227, E252, E999, D100, D101, D102, D104, D200
27+
ignore = E225, E227, E252, E999
2828
max-complexity = 10
2929
max-line-length = 150
3030
statistics = True
@@ -35,11 +35,3 @@ statistics = True
3535
# E227 missing whitespace around bitwise or shift operator (picks up pointers)
3636
# E252 spaces around default argument assignment (incorrect syntax)
3737
# E999 SyntaxError: invalid syntax (cimport seen as invalid syntax)
38-
39-
# Documentation ignores (will be addressed)
40-
# -----------------------------------------
41-
# D100 Missing docstring in public module (todo: picks up entire test suite)
42-
# D101 Missing docstring in public class (todo: picks up entire test suite)
43-
# D102 Missing docstring in public class (todo: picks up entire test suite)
44-
# D104 Missing docstring in public package (todo to complete)
45-
# D200 One-line docstring should fit on one line with quotes (conflicts with Codacy)

.github/workflows/test.yml

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
os: [ ubuntu-latest, macos-latest ]
21-
rust: [ stable ]
2221
python-version: [ 3.7, 3.8, 3.9 ]
2322
name: test - Python ${{ matrix.python-version }} (${{ matrix.os }})
2423
runs-on: ${{ matrix.os }}

CONTRIBUTING.md

+1-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ To contribute, the following steps should be followed;
1616
your local machine. This will automatically run various checks, auto-formatters
1717
and linting tools. Further information can be found here https://pre-commit.com/.
1818

19-
- Install the latest version of isort `pip install -U isort` (used in the pre-commit).
20-
21-
- Before committing it's a good practice to run `pre-commit run --all-files` yourself.
22-
23-
- It's recommended you install _Redis_ with a default configuration, so that integration
19+
- It's recommended you install Redis using the default configuration, so that integration
2420
tests will pass on your machine.
2521

2622
- Open a pull request (PR) on the `develop` branch with a summary comment.

README.md

+59-12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ NautilusTrader is an open-source, high-performance, production-grade algorithmic
2323
providing quantitative traders with the ability to backtest portfolios of automated trading strategies
2424
on historical data with an event-driven engine, and also deploy those same strategies live.
2525

26+
NautilusTrader is AI/ML first, designed to deploy models for algorithmic trading strategies developed
27+
using the Python ecosystem - within a highly performant and robust Python native environment.
28+
2629
The platform aims to be universal, with any REST/FIX/WebSocket API able to be integrated via modular
2730
adapters. Thus the platform can handle high-frequency trading operations for any asset classes
2831
including FX, Equities, Futures, Options, CFDs and Crypto - across multiple venues simultaneously.
@@ -36,14 +39,36 @@ including FX, Equities, Futures, Options, CFDs and Crypto - across multiple venu
3639
- **Multi-venue:** Multiple venue capabilities facilitate market making and statistical arbitrage strategies.
3740
- **AI Agent Training:** Backtest engine fast enough to be used to train AI trading agents (RL/ES).
3841

39-
## Values
42+
## Why NautilusTrader?
4043

41-
- Reliability
42-
- Performance
43-
- Testability
44-
- Modularity
45-
- Maintainability
46-
- Scalability
44+
One of the key value propositions of NautilusTrader is that it addresses the challenge of keeping
45+
the research/backtest environment consistent with the production live trading environment.
46+
47+
Normally research and backtesting may be conducted in Python (or other suitable language), with
48+
trading strategies traditionally then needing to be reimplemented in C++/C#/Java or other statically
49+
typed language(s). The reasoning here is to enjoy the performance a compiled language can offer,
50+
along with the tooling and support which has made these languages historically more suitable for
51+
large enterprise systems.
52+
53+
The value of NautilusTrader here is that this re-implementation step is circumvented, as the
54+
platform was designed from the ground up to hold its own in terms of performance and quality.
55+
56+
Python has simply caught up in performance (via Cython offering C-level speed) and general tooling,
57+
making it a suitable language for implementing a large system such as this. The benefit being
58+
that a Python native environment can be offered, suitable for professional quantitative traders and
59+
hedge funds.
60+
61+
## Why Python?
62+
63+
Python was originally created decades ago as a simple scripting language with a clean straight
64+
forward syntax. It has since evolved into a fully fledged general purpose object-oriented
65+
programming language. Not only that, Python has become the _de facto lingua franca_ of data science,
66+
machine learning, and artificial intelligence.
67+
68+
The language out of the box is not without its drawbacks however, especially in the context of
69+
implementing large systems. Cython has addressed a lot of these issues, offering all the advantages
70+
of a statically typed language, embedded into Pythons rich ecosystem of software libraries and
71+
developer/user communities.
4772

4873
## What is Cython?
4974

@@ -55,6 +80,15 @@ The project heavily utilizes Cython to provide static type safety and increased
5580
for Python through C [extension modules](https://docs.python.org/3/extending/extending.html). The vast majority of the production Python code is actually
5681
written in Cython, however the libraries can be accessed from both pure Python and Cython.
5782

83+
## Values
84+
85+
- Reliability
86+
- Performance
87+
- Testability
88+
- Modularity
89+
- Maintainability
90+
- Scalability
91+
5892
## Documentation
5993

6094
The documentation for the latest version of the package is available at _readthedocs_.
@@ -189,29 +223,42 @@ exchanges.
189223

190224
## Development
191225

192-
For development of the Python codebase, we recommend using the PyCharm _Professional_ edition IDE, as
193-
it interprets Cython syntax. Alternatively, you could use Visual Studio Code with a Cython extension.
226+
For development we recommend using the PyCharm _Professional_ edition IDE, as it interprets Cython
227+
syntax. Alternatively, you could use Visual Studio Code with a Cython extension.
194228

195229
`poetry` is the preferred tool for handling all Python package and dev dependencies.
196230

197231
> https://python-poetry.org/
198232
233+
`pre-commit` is used to automatically run various checks, auto-formatters and linting tools
234+
at commit.
235+
236+
> https://pre-commit.com/
237+
199238
#### Environment Setup
200239

201240
The following steps are for Unix-like systems, and only need to be completed once.
202241

203-
1. Install the Cython package by running:
242+
1. Install the pre-commit package:
243+
244+
pip install pre-commit
245+
246+
2. Install the Cython package by running:
204247

205248
pip install -U Cython==3.0a6
206249

207-
2. Install `poetry` by running:
250+
3. Install `poetry` by running:
208251

209252
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
210253

211-
3. Then install all Python package dependencies, and compile the Rust libs and Python C extensions by running:
254+
4. Then install all Python package dependencies, and compile the C extensions by running:
212255

213256
poetry install
214257

258+
5. Setup the pre-commit hook which will then run automatically at commit:
259+
260+
pre-commit run --all-files
261+
215262
#### Builds
216263

217264
Following any changes to `.pyx` or `.pxd` files, you can re-compile by running:
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,88 @@
11
Coding Standards
22
================
33

4-
- PEP-8 and variations
5-
- Cython specifics
6-
- NumPy docstrings
7-
- flake8 usage and ignores
8-
- pre-commit hook setup and usage
9-
- isort usage
10-
- darglint usage
11-
124
Code Style
135
----------
14-
156
`Black` is a PEP-8 compliant opinionated formatter.
167

178
> https://github.com/psf/black
189

19-
We philosophically agree with `Black`, however it does not currently run over
20-
Cython code. So you could say we are "handcrafting towards" `Blacks` stylistic
21-
conventions.
10+
We philosophically agree with the `Black` formatting style, however it does not
11+
currently run over Cython code. So you could say we are "handcrafting towards"
12+
`Blacks` stylistic conventions.
13+
14+
The current codebase can be used as a guide for formatting guidance.
15+
16+
- For longer lines of code, and when passing more than a couple of arguments -
17+
it's common to take a new line which aligns at the next logical indent (rather
18+
than attempting a hanging alignment off an opening parenthesis).
19+
20+
- The closing parenthesis should be located on a new line, aligned at the logical
21+
indent.
22+
23+
- Also ensure multiple hanging parameters or arguments end with a comma `,`::
24+
25+
LongCodeLine(
26+
some_arg1,
27+
some_arg2,
28+
some_arg3, # <-- ending comma
29+
)
30+
31+
32+
PEP-8
33+
-----
34+
The codebase generally follows the PEP-8 style guide.
35+
36+
One notable departure is that Python `truthiness` is not always taken advantage
37+
of to check if an argument is `None`, or if a collection is empty/has elements.
38+
39+
There are two reasons for this;
40+
41+
1- Cython can generate more efficient C code from `is None` and `is not None`,
42+
rather than entering the Python runtime to check the `PyObject` truthiness.
43+
44+
2- As per the `Google Python Style Guide` it's discouraged to use truthiness to
45+
check if an argument is/is not None, when there is a chance an unexpected object
46+
could be passed into the function or method which will yield an unexpected
47+
truthiness evaluation - which could result in a logical error type bug.
48+
49+
_"Always use if foo is None: (or is not None) to check for a None value.
50+
E.g., when testing whether a variable or argument that defaults to None was set
51+
to some other value. The other value might be a value that’s false in a boolean
52+
context!"_
53+
54+
> https://google.github.io/styleguide/pyguide.html
55+
56+
Having said all of this there are still areas of the codebase which aren't as
57+
performance-critical where it is safe to use Python truthiness to check for None,
58+
or if a collection is empty/has elements.
59+
60+
We welcome all feedback on where the codebase departs from PEP-8 for no apparent
61+
reason.
62+
63+
NumPy Docstrings
64+
----------------
65+
The NumPy docstring syntax is used throughout the codebase. This needs to be
66+
adhered to consistently to ensure the docs build correctly during pushes to the
67+
`master` branch.
68+
69+
> https://numpydoc.readthedocs.io/en/latest/format.html
70+
71+
Flake8
72+
------
73+
`flake8` is utilized to lint the codebase. Current ignores can be found in the
74+
`.flake8` config file, the majority of which are required so that valid Cython
75+
code is not picked up as flake8 failures.
76+
77+
Cython
78+
------
79+
Ensure that all functions and methods returning `void` or a primitive C type
80+
(such as `bint`, `int`, `double`) include the `except *` keyword in the signature.
81+
82+
This will ensure Python exceptions are not ignored, but instead are `bubbled up`
83+
to the caller as expected.
84+
85+
More information on Cython syntax and conventions can be found by reading the
86+
Cython docs.
87+
88+
> https://cython.readthedocs.io/en/latest/index.html
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
Developing Adapters
22
===================
3+
4+
WIP
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,46 @@
11
Environment
22
===========
3+
4+
For development we recommend using the PyCharm _Professional_ edition IDE, as it
5+
interprets Cython syntax. Alternatively, you could use Visual Studio Code with
6+
a Cython extension.
7+
8+
`poetry` is the preferred tool for handling all Python package and dev dependencies.
9+
10+
> https://python-poetry.org/
11+
12+
`pre-commit` is used to automatically run various checks, auto-formatters and linting tools
13+
at commit.
14+
15+
> https://pre-commit.com/
16+
17+
Setup
18+
-----
19+
The following steps are for Unix-like systems, and only need to be completed once.
20+
21+
1. Install pre-commit:
22+
23+
pip install pre-commit
24+
25+
2. Install the Cython package by running:
26+
27+
pip install -U Cython==3.0a6
28+
29+
3. Install `poetry` by running:
30+
31+
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
32+
33+
4. Then install all Python package dependencies, and compile the C extensions by running:
34+
35+
poetry install
36+
37+
5. Setup the pre-commit hook which will then run automatically at commit:
38+
39+
pre-commit run --all-files
40+
41+
Builds
42+
------
43+
44+
Following any changes to `.pyx` or `.pxd` files, you can re-compile by running:
45+
46+
python build.py

docs/source/developer_guide/overview.rst docs/source/developer_guide/packaged_data.rst

+2-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
Overview
2-
========
3-
4-
We recommend the PyCharm Professional edition IDE as it interprets Cython syntax.
5-
Unfortunately the Community edition will not interpret Cython syntax.
6-
7-
> https://www.jetbrains.com/pycharm/
8-
9-
To run code from source, first compile the C extensions for the package::
10-
11-
python build.py
12-
13-
141
Packaged Data
15-
-------------
2+
=============
3+
164
Various data is contained internally in the `tests/test_kit/data` folder.
175

186
Libor Rates
+48-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,59 @@
11
Testing
22
=======
33

4-
To run tests::
4+
The test suite is divided into broad categories of tests including;
5+
- Unit tests
6+
- Integration tests
7+
- Acceptance/System tests
8+
- Performance tests
9+
10+
The performance tests are not run as part of the CI pipeline, but exist to aid
11+
development of performance-critical components.
12+
13+
Tests can be run using either Pytest or the Nox tool.
14+
15+
If you're using PyCharm then tests should run directly by right clicking on the
16+
respective folder (or top level tests folder) and clicking 'Run pytest'.
17+
18+
Alternatively you can use the `pytest .` command from the root level `tests`
19+
folder, or the other sub folders.
20+
21+
Nox
22+
---
23+
Nox sessions are defined within the `noxfile.py`, to run various test collections.
24+
25+
To run unit tests with nox::
526

627
nox -s tests
728

829

9-
If you have `redis-server` up you can run integration tests::
30+
If you have `redis-server` up you can run integration tests with nox::
1031

1132
nox -s integration_tests
1233

1334

14-
- Philosophy
15-
- Unit Tests
16-
- Integration Tests
17-
- Acceptance Tests
35+
Or both unit and integration tests::
36+
37+
nox -s tests_with_integration
38+
39+
Mocks
40+
-----
41+
Unit tests will often include other components acting as mocks. The intent of
42+
this is to simplify the test suite to avoid extensive use of a mocking framework,
43+
although `MagicMock` objects are currently used in particular cases.
44+
45+
Code Coverage
46+
-------------
47+
Code coverage output is generated using `coverage` and reported using `codecov`.
48+
49+
High test coverage is a goal for the project however not at the expense of
50+
appropriate error handling, or causing "test induced damage" to the architecture.
51+
52+
There are currently areas of the codebase which are 'impossible' to test unless
53+
there is a change to the production code. For example the last condition check
54+
of an if-else block which would catch an unrecognized value, these should be
55+
left in place in case there is a change to the production code - which these
56+
checks could then catch.
57+
58+
Other 'design-time' exceptions may also be impossible to test for, and so 100%
59+
test coverage is not the ultimate goal.

0 commit comments

Comments
 (0)