Here you will find guidance and tips for working on NautilusTrader using the Cython language. More information on Cython syntax and conventions can be found by reading the Cython docs .

Function and method signatures

Ensure that all functions and methods returning void or a primitive C type (such as bint , int , double ) include the except * keyword in the signature.

This will ensure Python exceptions are not ignored, and instead are “bubbled up” to the caller as expected.



Improved debugging support for Cython has remained a highly up-voted PyCharm feature for many years. Unfortunately, it’s safe to assume that PyCharm will not be receiving first class support for Cython debugging .

Cython Docs

The following recommendations are contained in the Cython docs:

The summary is it involves manually running a specialized version of gdb from the command line. We don’t recommend this workflow.


When debugging and seeking to understand a complex system such as NautilusTrader, it can be quite helpful to step through the code with a debugger. However, with this not being available for the Cython part of the codebase, there are a few things which can help:

  • Ensure LogLevel.DEBUG is configured for the backtesting or live system you are debugging. This is available on BacktestEngineConfig(logging=LoggingConfig(log_level="DEBUG")) or TradingNodeConfig(logging=LoggingConfig=log_level="DEBUG")) . With DEBUG mode active you will see more granular and verbose log traces which could be what you need to understand the flow.

  • Beyond this, if you still require more granular visibility around a part of the system, we recommend some well-placed calls to a components logger (normally self._log.debug(f"HERE {variable}" is enough).