docs/concepts/adapters.md
Adapters integrate data providers and trading venues into NautilusTrader.
They can be found in the top-level adapters subpackage.
An adapter typically comprises these components:
flowchart LR
subgraph Venue ["Trading Venue"]
API[REST API]
WS[WebSocket]
end
subgraph Adapter ["Adapter"]
HTTP[HttpClient]
WSC[WebSocketClient]
IP[InstrumentProvider]
DC[DataClient]
EC[ExecutionClient]
end
subgraph Core ["Nautilus Core"]
DE[DataEngine]
EE[ExecutionEngine]
end
API <--> HTTP
WS <--> WSC
HTTP --> IP
HTTP --> DC
HTTP --> EC
WSC --> DC
WSC --> EC
DC <--> DE
EC <--> EE
| Component | Purpose |
|---|---|
HttpClient | REST API communication. |
WebSocketClient | Real‑time streaming connection. |
InstrumentProvider | Loads and parses instrument definitions from the venue. |
DataClient | Handles market data subscriptions and requests. |
ExecutionClient | Handles order submission, modification, and cancellation. |
Instrument providers parse venue API responses into Nautilus Instrument objects.
An InstrumentProvider serves two use cases:
sandbox or live environment context
for actors and strategiesHere is an example of discovering the current instruments for the Binance Futures testnet:
import asyncio
import os
from nautilus_trader.adapters.binance.common.enums import BinanceAccountType
from nautilus_trader.adapters.binance.common.enums import BinanceEnvironment
from nautilus_trader.adapters.binance import get_cached_binance_http_client
from nautilus_trader.adapters.binance.futures.providers import BinanceFuturesInstrumentProvider
from nautilus_trader.common.component import LiveClock
async def main():
clock = LiveClock()
client = get_cached_binance_http_client(
clock=clock,
account_type=BinanceAccountType.USDT_FUTURES,
api_key=os.getenv("BINANCE_FUTURES_TESTNET_API_KEY"),
api_secret=os.getenv("BINANCE_FUTURES_TESTNET_API_SECRET"),
environment=BinanceEnvironment.TESTNET,
)
provider = BinanceFuturesInstrumentProvider(
client=client,
account_type=BinanceAccountType.USDT_FUTURES,
)
await provider.load_all_async()
# Access loaded instruments
instruments = provider.list_all()
print(f"Loaded {len(instruments)} instruments")
if __name__ == "__main__":
asyncio.run(main())
Each integration handles this differently. An InstrumentProvider within a TradingNode
generally offers two loading behaviors:
from nautilus_trader.config import InstrumentProviderConfig
InstrumentProviderConfig(load_all=True)
InstrumentProviderConfig(load_ids=["BTCUSDT-PERP.BINANCE", "ETHUSDT-PERP.BINANCE"])
Subscriptions do not load instruments by themselves. Before a strategy subscribes to live data, configure the provider to load the instrument at startup or request the instrument explicitly and wait until it reaches the cache.
Data clients handle market data subscriptions and requests for a venue. They connect to venue APIs and normalize incoming data into Nautilus types.
Actors and strategies can request data using built-in methods. Data returns via callbacks:
from nautilus_trader.model import Instrument, InstrumentId
from nautilus_trader.trading.strategy import Strategy
class MyStrategy(Strategy):
def on_start(self) -> None:
# Request an instrument definition
self.request_instrument(InstrumentId.from_str("BTCUSDT-PERP.BINANCE"))
# Request historical bars
self.request_bars(BarType.from_str("BTCUSDT-PERP.BINANCE-1-HOUR-LAST-EXTERNAL"))
def on_instrument(self, instrument: Instrument) -> None:
self.log.info(f"Received instrument: {instrument.id}")
def on_historical_data(self, data) -> None:
self.log.info(f"Received historical data: {data}")
For real-time data, use subscription methods:
def on_start(self) -> None:
# Assumes the instrument has already been loaded into the cache
# Subscribe to live trade updates
self.subscribe_trade_ticks(InstrumentId.from_str("BTCUSDT-PERP.BINANCE"))
# Subscribe to live bars
self.subscribe_bars(BarType.from_str("BTCUSDT-PERP.BINANCE-1-MINUTE-LAST-EXTERNAL"))
def on_trade_tick(self, tick: TradeTick) -> None:
self.log.info(f"Trade: {tick}")
def on_bar(self, bar: Bar) -> None:
self.log.info(f"Bar: {bar}")
:::tip See the Actors documentation for a complete reference of available request and subscription methods with their corresponding callbacks. :::
Execution clients handle order management for a venue. They translate Nautilus order commands into venue-specific API calls and process execution reports back into Nautilus events.
Key responsibilities:
The ExecutionEngine routes commands to the appropriate
execution client based on the order's venue. See the Execution guide for details
on order management from a strategy perspective.
:::tip For building a custom adapter, see the Adapter Developer Guide. :::