# How to Configure Risk Engine Settings in Nautilus Trader: A Complete Guide

> Master Nautilus Trader risk engine settings. Learn to configure risk for backtests and live trading with this complete guide. Optimize your trading strategies today.

- Repository: [Nautech Systems/nautilus_trader](https://github.com/nautechsystems/nautilus_trader)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Configure risk engine settings in Nautilus Trader by instantiating `RiskEngineConfig` for backtests or `LiveRiskEngineConfig` for live trading, then passing the configuration object to the system kernel or directly to the engine constructor.**

The risk engine in Nautilus Trader enforces pre-trade risk checks, rate limits, and notional caps to protect your trading capital. To configure risk engine settings, you create immutable configuration objects that define parameters such as maximum order rates, notional limits per instrument, and bypass flags. This guide explains how to configure risk engine settings using the base `RiskEngineConfig` class for backtesting and the extended `LiveRiskEngineConfig` for production environments.

## Understanding Risk Engine Configuration Classes

Nautilus Trader provides two primary configuration classes for the risk engine. The base `RiskEngineConfig` handles common settings for both backtesting and live trading, while `LiveRiskEngineConfig` extends it with asynchronous execution parameters.

### Base Configuration with RiskEngineConfig

The `RiskEngineConfig` class in [`nautilus_trader/risk/config.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/risk/config.py) defines the core risk parameters used by both backtest and live risk engines. This immutable configuration object validates settings at construction time using Pydantic-style type hints.

Key attributes include:

- **`bypass`**: When set to `True`, all pre-trade risk checks are skipped except for duplicate ID validation. This is useful for spot-only venues that do not support the full risk model.
- **`max_order_submit_rate`**: A rate limit string formatted as `"N/HH:MM:SS"` that restricts order submission frequency. For example, `"100/00:00:01"` allows 100 submit commands per second.
- **`max_order_modify_rate`**: Same format as the submit limit, but controlling order modification commands.
- **`max_notional_per_order`**: A dictionary mapping `instrument_id` strings to maximum notional values (e.g., `{"BTC-USD": 1_000_000}`) to cap individual order values.
- **`debug`**: Enables verbose diagnostic logging when set to `True`.

### Live Trading with LiveRiskEngineConfig

For production environments, the `LiveRiskEngineConfig` class in [`nautilus_trader/live/config.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/live/config.py) extends the base configuration with asynchronous execution parameters. The system kernel automatically instantiates a `LiveRiskEngine` when this configuration type is provided and the environment is not `BACKTEST`.

Additional live-only attributes include:

- **`qsize`**: Defines the internal `asyncio.Queue` capacity for commands and events. The default value of `100_000` is suitable for high-throughput strategies, but you can lower this for memory-constrained environments.
- **`graceful_shutdown_on_exception`**: Determines the system's response to queue-processing errors. When `True`, the engine attempts a coordinated shutdown via `self.shutdown_system()`. When `False`, the process exits immediately with `os._exit(1)`.

## How the System Kernel Applies Risk Engine Settings

The system kernel in [`nautilus_trader/system/kernel.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/system/kernel.py) handles the instantiation of the appropriate risk engine based on your configuration type. When building a trading node, the kernel inspects the top-level `Config` object and selects the engine implementation accordingly.

```python

# Kernel snippet that selects the appropriate engine

if isinstance(config.risk_engine, LiveRiskEngineConfig):
    self._risk_engine = LiveRiskEngine(
        loop=self.loop,
        portfolio=self._portfolio,
        msgbus=self._msgbus,
        cache=self._cache,
        clock=self._clock,
        config=config.risk_engine,
    )
elif isinstance(config.risk_engine, RiskEngineConfig):
    self._risk_engine = RiskEngine(
        portfolio=self._portfolio,
        msgbus=self._msgbus,
        cache=self._cache,
        clock=self._clock,
        config=config.risk_engine,
    )

```

This wiring logic ensures that `LiveRiskEngine` receives the event loop and live-specific configuration, while the standard `RiskEngine` operates with synchronous backtest components.

## Configuring Risk Engine Settings: Code Examples

### Minimal Live Risk Engine Configuration

To configure risk engine settings for a live trading environment without using the high-level kernel, instantiate `LiveRiskEngineConfig` and pass it directly to the `LiveRiskEngine` constructor.

```python
from nautilus_trader.live.config import LiveRiskEngineConfig
from nautilus_trader.live.risk_engine import LiveRiskEngine
import asyncio

# Custom configuration

risk_cfg = LiveRiskEngineConfig(
    bypass=False,                       # enforce all checks

    max_order_submit_rate="50/00:00:01",
    max_order_modify_rate="20/00:00:01",
    max_notional_per_order={"ETH-USD": 500_000},
    debug=True,                         # verbose logging

    qsize=10_000,                       # smaller internal queues

    graceful_shutdown_on_exception=True,
)

# Assuming you already have a running event loop, portfolio, msgbus, cache and clock:

loop = asyncio.get_event_loop()
risk_engine = LiveRiskEngine(
    loop=loop,
    portfolio=portfolio,
    msgbus=msgbus,
    cache=cache,
    clock=clock,
    config=risk_cfg,
)

risk_engine.start()   # launches internal command/event queue tasks

```

### High-Level Kernel Configuration

For most use cases, configure risk engine settings through the top-level `Config` object, allowing the system kernel to handle engine instantiation automatically.

```python
from nautilus_trader.config import (
    Config,
    LiveRiskEngineConfig,
    LiveDataEngineConfig,
    LiveExecEngineConfig,
    LivePortfolioConfig,
    LiveCacheConfig,
    Environment,
)

# Build a top-level config that the kernel will consume

cfg = Config(
    environment=Environment.LIVE,
    risk_engine=LiveRiskEngineConfig(
        bypass=True,           # useful for spot-only exchanges

        qsize=5_000,
    ),
    data_engine=LiveDataEngineConfig(),
    exec_engine=LiveExecEngineConfig(),
    portfolio=LivePortfolioConfig(),
    cache=LiveCacheConfig(),
)

# The kernel will automatically instantiate a LiveRiskEngine with the above config

from nautilus_trader.system.kernel import NautilusKernel
kernel = NautilusKernel(config=cfg)
kernel.start()   # starts all components including the risk engine

```

### Backtest Risk Engine Configuration

For backtesting scenarios, use the base `RiskEngineConfig` class without live-specific parameters.

```python
from nautilus_trader.risk.config import RiskEngineConfig

# In a back-test you can disable all checks:

risk_cfg = RiskEngineConfig(bypass=True)

```

## Key Source Files

The following source files define and implement the risk engine configuration system:

- **[`nautilus_trader/risk/config.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/risk/config.py)**: Contains the base `RiskEngineConfig` class defining `bypass`, rate limits, notional caps, and debug settings.
- **[`nautilus_trader/live/config.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/live/config.py)**: Defines `LiveRiskEngineConfig` with additional `qsize` and `graceful_shutdown_on_exception` parameters.
- **[`nautilus_trader/live/risk_engine.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/live/risk_engine.py)**: Implements the asynchronous `LiveRiskEngine` that consumes the configuration.
- **[`nautilus_trader/system/kernel.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/system/kernel.py)**: Contains the bootstrap logic that instantiates the appropriate risk engine based on configuration type.
- **[`docs/api_reference/risk.md`](https://github.com/nautechsystems/nautilus_trader/blob/main/docs/api_reference/risk.md)**: API documentation for the `nautilus_trader.risk` package.

## Summary

- **Use `RiskEngineConfig`** for backtesting and basic risk management with attributes like `bypass`, `max_order_submit_rate`, and `max_notional_per_order`.
- **Use `LiveRiskEngineConfig`** for production environments to access live-specific settings including `qsize` and `graceful_shutdown_on_exception`.
- **Pass configuration objects** either directly to engine constructors or through the top-level `Config` object consumed by `NautilusKernel` in [`nautilus_trader/system/kernel.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/system/kernel.py).
- **Validate settings** at construction time; misconfigured values raise immediate `TypeError` exceptions before runtime.
- **Control rate limits** using the `"N/HH:MM:SS"` format to protect venue API quotas from excessive order submissions or modifications.

## Frequently Asked Questions

### What is the difference between RiskEngineConfig and LiveRiskEngineConfig?

`RiskEngineConfig` is the base configuration class found in [`nautilus_trader/risk/config.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/risk/config.py) that provides core risk parameters like rate limits and notional caps for both backtesting and live trading. `LiveRiskEngineConfig` extends this base class in [`nautilus_trader/live/config.py`](https://github.com/nautechsystems/nautilus_trader/blob/main/nautilus_trader/live/config.py) to add asynchronous execution parameters specific to production environments, including `qsize` for queue capacity and `graceful_shutdown_on_exception` for error handling behavior.

### How do I bypass all risk checks in Nautilus Trader?

Set the `bypass` parameter to `True` when creating your configuration object. When `bypass=True`, the risk engine skips all pre-trade risk checks including order-size limits, rate limits, and notional caps, while still maintaining duplicate ID validation. This is particularly useful for spot-only venues that do not support the full risk model, and can be configured for both backtests using `RiskEngineConfig(bypass=True)` and live trading using `LiveRiskEngineConfig(bypass=True)`.

### What happens when max_order_submit_rate is exceeded?

When the number of order submissions exceeds the threshold defined in `max_order_submit_rate` (formatted as `"N/HH:MM:SS"`), the risk engine blocks additional submit commands until the rate limit window resets. This protects your venue API quotas from excessive requests that could result in bans or throttling. The engine enforces this limit internally before passing commands to the execution layer, ensuring that only compliant order flow reaches the exchange.

### How does graceful_shutdown_on_exception work in live trading?

The `graceful_shutdown_on_exception` parameter in `LiveRiskEngineConfig` determines the system's response to unexpected errors in queue-processing tasks. When set to `True`, the risk engine attempts a coordinated shutdown by calling `self.shutdown_system()` to close positions and cancel orders cleanly. When set to `False`, the process terminates immediately using `os._exit(1)` without cleanup, which may leave orphaned orders on exchanges but prevents hanging processes during critical failures.