Implementation:Nautechsystems Nautilus trader TradingNode Add Client Factory
| Field | Value |
|---|---|
| sources | https://github.com/nautechsystems/nautilus_trader, https://nautilustrader.io/docs/ |
| domains | algorithmic trading, design patterns, factory pattern, plugin architecture |
| last_updated | 2026-02-10 12:00 GMT |
Overview
Concrete tool for registering exchange-specific client factories on a live trading node provided by NautilusTrader.
Description
The TradingNode class exposes two registration methods:
add_data_client_factory(name, factory)-- registers aLiveDataClientFactorysubclass that will be used to create the data client for the given name.add_exec_client_factory(name, factory)-- registers aLiveExecClientFactorysubclass that will be used to create the execution client for the given name.
Both methods delegate to the internal TradingNodeBuilder. The builder stores the mapping of name to factory class and enforces uniqueness (duplicate names raise KeyError). At build time (node.build()), the builder iterates over the node configuration's client dictionaries and calls each registered factory's static create() method, passing the event loop, message bus, cache, clock, and the exchange-specific configuration.
The factory base classes (LiveDataClientFactory and LiveExecClientFactory) define the contract: a static create() method that accepts (loop, name, config, msgbus, cache, clock) and returns a LiveDataClient or LiveExecutionClient respectively. Each exchange adapter provides its own subclass that implements this method.
Usage
Import the factory classes from the desired exchange adapter and register them on the node after construction but before calling node.build().
Code Reference
Source Location
| Item | Path |
|---|---|
| add_data_client_factory | nautilus_trader/live/node.py lines 230-249
|
| add_exec_client_factory | nautilus_trader/live/node.py lines 251-270
|
| LiveDataClientFactory | nautilus_trader/live/factories.py lines 27-66
|
| LiveExecClientFactory | nautilus_trader/live/factories.py lines 69-109
|
Signature
# TradingNode methods
def add_data_client_factory(
self,
name: str,
factory: type[LiveDataClientFactory],
) -> None: ...
def add_exec_client_factory(
self,
name: str,
factory: type[LiveExecClientFactory],
) -> None: ...
# Factory base class interfaces
class LiveDataClientFactory:
@staticmethod
def create(
loop: asyncio.AbstractEventLoop,
name: str,
config: LiveDataClientConfig,
msgbus: MessageBus,
cache: Cache,
clock: LiveClock,
) -> LiveDataClient: ...
class LiveExecClientFactory:
@staticmethod
def create(
loop: asyncio.AbstractEventLoop,
name: str,
config: LiveExecClientConfig,
msgbus: MessageBus,
cache: Cache,
clock: LiveClock,
) -> LiveExecutionClient: ...
Import
from nautilus_trader.live.node import TradingNode
from nautilus_trader.live.factories import LiveDataClientFactory
from nautilus_trader.live.factories import LiveExecClientFactory
I/O Contract
Inputs
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | str |
Yes | The name key matching the entry in data_clients or exec_clients config dict.
|
| factory | type[LiveDataClientFactory] or type[LiveExecClientFactory] |
Yes | The factory class (not an instance) to register. |
Outputs
| Output | Type | Description |
|---|---|---|
| (none) | None |
The factory is stored internally in the TradingNodeBuilder.
|
Errors
| Exception | Condition |
|---|---|
ValueError |
If name is not a valid (non-empty) string.
|
KeyError |
If name has already been registered.
|
Usage Examples
Registering Binance Factories
from nautilus_trader.live.node import TradingNode
from nautilus_trader.config import TradingNodeConfig
from nautilus_trader.adapters.binance.factories import BinanceLiveDataClientFactory
from nautilus_trader.adapters.binance.factories import BinanceLiveExecClientFactory
from nautilus_trader.adapters.binance.config import BinanceDataClientConfig
from nautilus_trader.adapters.binance.config import BinanceExecClientConfig
config = TradingNodeConfig(
trader_id="TRADER-001",
data_clients={"BINANCE": BinanceDataClientConfig(api_key="key", api_secret="secret")},
exec_clients={"BINANCE": BinanceExecClientConfig(api_key="key", api_secret="secret")},
)
node = TradingNode(config=config)
# Register factories (must happen before node.build())
node.add_data_client_factory("BINANCE", BinanceLiveDataClientFactory)
node.add_exec_client_factory("BINANCE", BinanceLiveExecClientFactory)
# Now build and run
node.build()
node.run()
Registering Multiple Exchanges
# Register factories for two exchanges
node.add_data_client_factory("BINANCE", BinanceLiveDataClientFactory)
node.add_exec_client_factory("BINANCE", BinanceLiveExecClientFactory)
node.add_data_client_factory("BYBIT", BybitLiveDataClientFactory)
node.add_exec_client_factory("BYBIT", BybitLiveExecClientFactory)
node.build()