Interactive Brokers - Loren1166/NautilusTrader- GitHub Wiki

Interactive Brokers 盈透证券

Interactive Brokers (IB) is a trading platform providing market access across a wide range of financial instruments, including stocks, options, futures, currencies, bonds, funds, and cryptocurrencies. NautilusTrader offers an adapter to integrate with IB using their Trader Workstation (TWS) API through their Python library, ibapi.

盈透证券 (IB) 是一个交易平台,提供对各种金融产品的市场准入,包括股票、期权、期货、货币、债券、基金和加密货币。NautilusTrader 提供了一个适配器,可以使用其 Python 库 ibapi 通过其交易员工作站 (TWS) API 与 IB 集成。

The TWS API serves as an interface to IB's standalone trading applications: TWS and IB Gateway. Both can be downloaded from the IB website. If you haven't installed TWS or IB Gateway yet, refer to the Initial Setup guide. In NautilusTrader, you'll establish a connection to one of these applications via the InteractiveBrokersClient.

TWS API 充当 IB 独立交易应用程序的接口:TWS 和 IB 网关。两者都可以从 IB 网站下载。如果您尚未安装 TWS 或 IB 网关,请参阅初始设置指南。在 NautilusTrader 中,您将通过 InteractiveBrokersClient 建立与其中一个应用程序的连接。

Alternatively, you can start with a dockerized version of the IB Gateway, which is particularly useful when deploying trading strategies on a hosted cloud platform. This requires having Docker installed on your machine, along with the docker Python package, which NautilusTrader conveniently includes as an extra package.

或者,您可以从 dockerized 版本的 IB 网关开始,这在托管云平台上部署交易策略时特别有用。这需要在您的机器上安装 Docker,以及 docker Python 包,NautilusTrader 方便地将其作为额外的包包含在内。

note 注意

The standalone TWS and IB Gateway applications require manually inputting username, password, and trading mode (live or paper) at startup. The dockerized version of the IB Gateway handles these steps programmatically.

独立的 TWS 和 IB 网关应用程序需要在启动时手动输入用户名、密码和交易模式(实时或模拟)。dockerized 版本的 IB 网关以编程方式处理这些步骤。

Installation 安装

To install the latest nautilus-trader package along with the ibapi and optional docker dependencies using pip, execute:

要使用 pip 安装最新的 nautilus-trader 包以及 ibapi 和可选的 docker 依赖项,请执行以下操作:

pip install -U "nautilus_trader[ib,docker]"

For installation via poetry, use:

要通过 poetry 安装,请使用以下命令:

poetry add "nautilus_trader[ib,docker]"

note 注意

Because IB does not provide wheels for ibapi, NautilusTrader repackages it for release on PyPI.

由于 IB 不为 ibapi 提供轮子,因此 NautilusTrader 将其重新打包以在 PyPI 上发布。

Getting Started 入门

Before implementing your trading strategies, please ensure that either TWS (Trader Workstation) or IB Gateway is currently running. You have the option to log in to one of these standalone applications using your personal credentials or alternatively, via DockerizedIBGateway.

在实施您的交易策略之前,请确保 TWS(交易员工作站)或 IB 网关当前正在运行。您可以选择使用您的个人凭据或通过 DockerizedIBGateway 登录到这些独立应用程序之一。

Establish Connection to an Existing Gateway or TWS: 建立与现有网关或 TWS 的连接:

Should you choose to connect to a pre-existing Gateway or TWS, it is crucial that you specify the host and port parameters in both the InteractiveBrokersDataClientConfig and InteractiveBrokersExecClientConfig to guarantee a successful connection.

如果您选择连接到预先存在的网关或 TWS,则必须在 InteractiveBrokersDataClientConfigInteractiveBrokersExecClientConfig 中指定 hostport 参数,以确保成功连接。

Establish Connection to DockerizedIBGateway: 建立与 DockerizedIBGateway 的连接:

In this case, it's essential to supply dockerized_gateway with an instance of DockerizedIBGatewayConfig in both the InteractiveBrokersDataClientConfig and InteractiveBrokersExecClientConfig. It's important to stress, however, that host and port parameters aren't necessary in this context. The following example provides a clear illustration of how to establish a connection to a Dockerized Gateway, which is judiciously managed internally by the Factories.

在这种情况下,必须在 InteractiveBrokersDataClientConfigInteractiveBrokersExecClientConfig 中为 dockerized_gateway 提供 DockerizedIBGatewayConfig 的实例。但是,需要强调的是,在这种情况下,hostport 参数不是必需的。以下示例清楚地说明了如何建立与 Dockerized 网关的连接,该网关由工厂在内部进行明智地管理。

from nautilus_trader.adapters.interactive_brokers.config import DockerizedIBGatewayConfig
from nautilus_trader.adapters.interactive_brokers.gateway import DockerizedIBGateway

gateway_config = DockerizedIBGatewayConfig(
    username="test",
    password="test",
    trading_mode="paper",
)

# This may take a short while to start up, especially the first time
# 这可能需要一些时间才能启动,尤其是在第一次
gateway = DockerizedIBGateway(
    config=gateway_config
)
gateway.start()

# Confirm you are logged in
# 确认您已登录
print(gateway.is_logged_in(gateway.container))

# Inspect the logs
# 检查日志
print(gateway.container.logs())

Note: To supply credentials to the Interactive Brokers Gateway, either pass the username and password to the DockerizedIBGatewayConfig, or set the following environment variables:

注意:要向 Interactive Brokers 网关提供凭据,请将 usernamepassword 传递给 DockerizedIBGatewayConfig,或者设置以下环境变量:

  • TWS_USERNAME
  • TWS_PASSWORD

Overview 概述

The adapter includes several major components:

适配器包括几个主要组件:

  • InteractiveBrokersClient: Executes TWS API requests using ibapi. InteractiveBrokersClient:使用 ibapi 执行 TWS API 请求。
  • HistoricInteractiveBrokersClient: Provides methods for retrieving instruments and historical data, useful for backtesting. HistoricInteractiveBrokersClient:提供检索金融产品和历史数据的方法,对回测很有用。
  • InteractiveBrokersInstrumentProvider: Retrieves or queries instruments for trading. InteractiveBrokersInstrumentProvider:检索或查询金融产品。
  • InteractiveBrokersDataClient: Connects to the Gateway for streaming market data. InteractiveBrokersDataClient:连接到网关以流式传输市场数据。
  • InteractiveBrokersExecutionClient: Handles account information and executes trades. InteractiveBrokersExecutionClient:处理账户信息并执行交易。

The Interactive Brokers Client Interactive Brokers 客户端

The InteractiveBrokersClient serves as the central component of the IB adapter, overseeing a range of critical functions. These include establishing and maintaining connections, handling API errors, executing trades, and gathering various types of data such as market data, contract/instrument data, and account details.

InteractiveBrokersClient 充当 IB 适配器的中心组件,负责监督一系列关键功能。这些功能包括建立和维护连接、处理 API 错误、执行交易以及收集各种类型的数据,例如市场数据、合约/产品数据和账户详细信息。

To ensure efficient management of these diverse responsibilities, the InteractiveBrokersClient is divided into several specialized mixin classes. This modular approach enhances manageability and clarity. The key subcomponents are:

为了确保有效管理这些不同的职责,InteractiveBrokersClient 被划分为几个专门的混入类。这种模块化方法增强了可管理性和清晰度。关键子组件是:

  • InteractiveBrokersClientConnectionMixin: This class is dedicated to managing the connection with TWS/Gateway. InteractiveBrokersClientConnectionMixin:此类专用于管理与 TWS/网关的连接。
  • InteractiveBrokersClientErrorMixin: It focuses on addressing all encountered errors and warnings. InteractiveBrokersClientErrorMixin:它专注于处理遇到的所有错误和警告。
  • InteractiveBrokersClientAccountMixin: Responsible for handling requests related to account information and positions. InteractiveBrokersClientAccountMixin:负责处理与账户信息和头寸相关的请求。
  • InteractiveBrokersClientContractMixin: Handles retrieving contracts (instruments) data. InteractiveBrokersClientContractMixin:处理检索合约(产品)数据。
  • InteractiveBrokersClientMarketDataMixin: Handles market data requests, subscriptions and data processing. InteractiveBrokersClientMarketDataMixin:处理市场数据请求、订阅和数据处理。
  • InteractiveBrokersClientOrderMixin: Oversees all aspects of order placement and management. InteractiveBrokersClientOrderMixin:监督订单下达和管理的所有方面。

tip 提示

To troubleshoot TWS API incoming message issues, consider starting at the InteractiveBrokersClient._process_message method, which acts as the primary gateway for processing all messages received from the API.

要解决 TWS API 传入消息问题,请考虑从 InteractiveBrokersClient._process_message 方法开始,该方法充当处理从 API 接收的所有消息的主要网关。

Symbology 符号

The InteractiveBrokersInstrumentProvider supports two methods for constructing InstrumentId instances, which can be configured via the strict_symbology flag in InteractiveBrokersInstrumentProviderConfig.

InteractiveBrokersInstrumentProvider 支持两种构建 InstrumentId 实例的方法,可以通过 InteractiveBrokersInstrumentProviderConfig 中的 strict_symbology 标志进行配置。

Simplified Symbology 简化符号

When strict_symbology is set to False (the default setting), the system utilizes the following parsing rules for symbology:

strict_symbology 设置为 False(默认设置)时,系统使用以下解析规则进行符号解析:

  • Forex: The format is {symbol}/{currency}.{exchange}, where the currency pair is constructed as EUR/USD.IDEALPRO. 外汇: 格式为 {symbol}/{currency}.{exchange},其中货币对构造为 EUR/USD.IDEALPRO
  • Stocks: The format is {localSymbol}.{primaryExchange}. Any spaces in localSymbol are replaced with -, e.g., BF-B.NYSE. 股票: 格式为 {localSymbol}.{primaryExchange}localSymbol 中的任何空格都将替换为 -,例如 BF-B.NYSE
  • Futures: The format is {localSymbol}.{exchange}. Single digit years are expanded to two digits, e.g., ESM24.CME. 期货: 格式为 {localSymbol}.{exchange}。个位数年份扩展为两位数,例如 ESM24.CME
  • Options: The format is {localSymbol}.{exchange}, with all spaces removed from localSymbol, e.g., AAPL230217P00155000.SMART. 期权: 格式为 {localSymbol}.{exchange},从 localSymbol 中删除所有空格,例如 AAPL230217P00155000.SMART
  • Index: The format is ^{localSymbol}.{exchange}, e.g., ^SPX.CBOE. 指数: 格式为 ^{localSymbol}.{exchange},例如 ^SPX.CBOE

Strict Symbology 严格符号

Setting strict_symbology to True enforces stricter parsing rules that align directly with the fields defined in the ibapi. The format for each security type is as follows:

strict_symbology 设置为 True 将强制执行更严格的解析规则,这些规则与 ibapi 中定义的字段直接一致。每种证券类型的格式如下:

  • CFDs: {localSymbol}={secType}.IBCFD
  • Commodities: {localSymbol}={secType}.IBCMDTY
  • Default for Other Types: {localSymbol}={secType}.{exchange}

This configuration ensures that the symbology is explicitly defined and matched with the Interactive Brokers API requirements, providing clear and consistent instrument identification.

此配置确保符号被显式定义并与 Interactive Brokers API 要求相匹配,从而提供清晰一致的产品标识。

Instruments & Contracts 产品和合约

In IB, a NautilusTrader Instrument is equivalent to a Contract. Contracts can be either a basic contract or a more detailed version (ContractDetails). The adapter models these using IBContract and IBContractDetails classes. The latter includes critical data like order types and trading hours, which are absent in the basic contract. As a result, IBContractDetails can be converted to an Instrument while IBContract cannot.

在 IB 中,NautilusTrader Instrument 等同于 Contract。合约可以是基本合约,也可以是更详细的版本 (ContractDetails)。适配器使用 IBContractIBContractDetails 类对它们进行建模。后者包括基本合约中没有的关键数据,例如订单类型和交易时间。因此,IBContractDetails 可以转换为 Instrument,而 IBContract 不能。

To search for contract information, use the IB Contract Information Center.

要搜索合约信息,请使用 IB 合约信息中心

It's typically suggested to utilize strict_symbology=False (which is the default setting). This provides a cleaner and more intuitive use of InstrumentId by employing load_ids in the InteractiveBrokersInstrumentProviderConfig, following the guidelines established in the Simplified Symbology section. In order to load multiple Instruments, such as Options Instrument without having to specify each strike explicitly, you would need to utilize load_contracts with provided instances of IBContract.

通常建议使用 strict_symbology=False(默认设置)。通过按照简化符号部分中建立的指南在 InteractiveBrokersInstrumentProviderConfig 中使用 load_ids,这可以更清晰、更直观地使用 InstrumentId。为了加载多个Instrument,例如期权产品,而无需显式指定每个行权价,您需要使用提供的 IBContract 实例来利用 load_contracts

for_loading_instrument_expiry = IBContract(
    secType="IND",
    symbol="SPX",
    exchange="CBOE",
    build_options_chain=True,
    lastTradeDateOrContractMonth='20240718',
)

for_loading_instrument_range = IBContract(
    secType="IND",
    symbol="SPX",
    exchange="CBOE",
    build_options_chain=True,
    min_expiry_days=0,
    max_expiry_days=30,
)

Note: The secType and symbol should be specified for the Underlying Contract.

注意:应为基础合约指定 secTypesymbol

Some more examples of building IBContracts:

构建 IBContracts 的更多示例:

from nautilus_trader.adapters.interactive_brokers.common import IBContract

# Stock 股票
IBContract(secType='STK', exchange='SMART', primaryExchange='ARCA', symbol='SPY')

# Bond 债券
IBContract(secType='BOND', secIdType='ISIN', secId='US03076KAA60')

# Option 期权
IBContract(secType='STK', exchange='SMART', primaryExchange='ARCA', symbol='SPY', lastTradeDateOrContractMonth='20251219', build_options_chain=True)

# CFD 差价合约
IBContract(secType='CFD', symbol='IBUS30')

# Future 期货
IBContract(secType='CONTFUT', exchange='CME', symbol='ES', build_futures_chain=True)

# Forex 外汇
IBContract(secType='CASH', exchange='IDEALPRO', symbol='EUR', currency='GBP')

# Crypto 加密货币
IBContract(secType='CRYPTO', symbol='ETH', exchange='PAXOS', currency='USD')

Historical Data & Backtesting 历史数据和回测

When developing strategies with the IB adapter, the first step usually involves acquiring historical data for backtesting. The HistoricInteractiveBrokersClient offers methods to request and save this data.

使用 IB 适配器开发策略时,第一步通常涉及获取历史数据以进行回测。HistoricInteractiveBrokersClient 提供了请求和保存此数据的方法。

Here's an example of retrieving and saving instrument and bar data. A more comprehensive example is available here.

以下是检索和保存产品和K线数据的示例。此处 提供了更全面的示例。

import datetime
from nautilus_trader.adapters.interactive_brokers.common import IBContract
from nautilus_trader.adapters.interactive_brokers.historic import HistoricInteractiveBrokersClient
from nautilus_trader.persistence.catalog import ParquetDataCatalog


async def main():
    contract = IBContract(
        secType="STK",
        symbol="AAPL",
        exchange="SMART",
        primaryExchange="NASDAQ",
    )
    client = HistoricInteractiveBrokersClient()

    instruments = await client.request_instruments(
        contracts=[contract],
    )

    bars = await client.request_bars(
        bar_specifications=["1-HOUR-LAST", "30-MINUTE-MID"],
        end_date_time=datetime.datetime(2023, 11, 6, 16, 30),
        tz_name="America/New_York",
        duration="1 D",
        contracts=[contract],
    )

    catalog = ParquetDataCatalog("./catalog")
    catalog.write_data(instruments)
    catalog.write_data(bars)

Live Trading 实时交易

Engaging in live or paper trading requires constructing and running a TradingNode. This node incorporates both InteractiveBrokersDataClient and InteractiveBrokersExecutionClient, which depend on the InteractiveBrokersInstrumentProvider to operate.

进行实时或模拟交易需要构建和运行 TradingNode。此节点包含 InteractiveBrokersDataClientInteractiveBrokersExecutionClient,它们依赖于 InteractiveBrokersInstrumentProvider 运行。

InstrumentProvider Instrument适配器

The InteractiveBrokersInstrumentProvider class functions as a bridge for accessing financial instrument data from IB. Configurable through InteractiveBrokersInstrumentProviderConfig, it enables the customization of various instrument type parameters. Additionally, this provider offers specialized methods to build and retrieve the entire futures and options chains.

InteractiveBrokersInstrumentProvider 类充当从 IB 访问金融产品数据的桥梁。可以通过 InteractiveBrokersInstrumentProviderConfig 进行配置,它可以自定义各种产品类型参数。此外,此提供程序还提供专门的方法来构建和检索整个期货和期权链。

from nautilus_trader.adapters.interactive_brokers.config import InteractiveBrokersInstrumentProviderConfig


instrument_provider_config = InteractiveBrokersInstrumentProviderConfig(
    build_futures_chain=False,  # Set to True if fetching futures 如果获取期货,则设置为 True
    build_options_chain=False,  # Set to True if fetching options 如果获取期权,则设置为 True
    min_expiry_days=10,         # Relevant for futures/options with expiration 与到期的期货/期权相关
    max_expiry_days=60,         # Relevant for futures/options with expiration 与到期的期货/期权相关
    load_ids=frozenset(
        [
            "EUR/USD.IDEALPRO",
            "BTC/USD.PAXOS",
            "SPY.ARCA",
            "V.NYSE",
            "YMH24.CBOT",
            "CLZ27.NYMEX",
            "ESZ27.CME",
        ],
    ),
    load_contracts=frozenset(
        [
            IBContract(secType='STK', symbol='SPY', exchange='SMART', primaryExchange='ARCA'),
            IBContract(secType='STK', symbol='AAPL', exchange='SMART', primaryExchange='NASDAQ')
        ]
    ),
)

Data Client 数据客户端

InteractiveBrokersDataClient interfaces with IB for streaming and retrieving market data. Upon connection, it configures the market data type and loads instruments based on the settings in InteractiveBrokersInstrumentProviderConfig. This client can subscribe to and unsubscribe from various market data types, including quote ticks, trade ticks, and bars.

InteractiveBrokersDataClient 与 IB 交互以流式传输和检索市场数据。连接后,它会配置市场数据类型并根据 InteractiveBrokersInstrumentProviderConfig 中的设置加载产品。此客户端可以订阅和取消订阅各种市场数据类型,包括报价、交易和K线。

Configurable through InteractiveBrokersDataClientConfig, it enables adjustments for handling revised bars, trading hours preferences, and market data types (e.g., IBMarketDataTypeEnum.REALTIME or IBMarketDataTypeEnum.DELAYED_FROZEN).

可以通过 InteractiveBrokersDataClientConfig 进行配置,它可以调整修订K线的处理、交易时间偏好和市场数据类型(例如 IBMarketDataTypeEnum.REALTIMEIBMarketDataTypeEnum.DELAYED_FROZEN)。

from nautilus_trader.adapters.interactive_brokers.config import IBMarketDataTypeEnum
from nautilus_trader.adapters.interactive_brokers.config import InteractiveBrokersDataClientConfig


data_client_config = InteractiveBrokersDataClientConfig(
    ibg_port=4002,
    handle_revised_bars=False,
    use_regular_trading_hours=True,
    market_data_type=IBMarketDataTypeEnum.DELAYED_FROZEN,  # Default is REALTIME if not set 默认情况下为 REALTIME(如果未设置)
    instrument_provider=instrument_provider_config,
    dockerized_gateway=dockerized_gateway_config,
)

Execution Client 执行客户端

The InteractiveBrokersExecutionClient facilitates executing trades, accessing account information, and processing order and trade-related details. It encompasses a range of methods for order management, including reporting order statuses, placing new orders, and modifying or canceling existing ones. Additionally, it generates position reports, although fill reports are not yet implemented.

InteractiveBrokersExecutionClient 促进了执行交易、访问账户信息以及处理订单和交易相关细节。它包含一系列订单管理方法,包括报告订单状态、下达新订单以及修改或取消现有订单。此外,它还会生成头寸报告,但成交报告尚未实现。

from nautilus_trader.adapters.interactive_brokers.config import InteractiveBrokersExecClientConfig
from nautilus_trader.config import RoutingConfig


exec_client_config = InteractiveBrokersExecClientConfig(
    ibg_port=4002,
    account_id="DU123456",  # Must match the connected IB Gateway/TWS 必须与连接的 IB 网关/TWS 匹配
    dockerized_gateway=dockerized_gateway_config,
    instrument_provider=instrument_provider_config,
    routing=RoutingConfig(
        default=True,
    )
)

Full Configuration 完整配置

Setting up a complete trading environment typically involves configuring a TradingNodeConfig, which includes data and execution client configurations. Additional configurations are specified in LiveDataEngineConfig to accommodate IB-specific requirements. A TradingNode is then instantiated from these configurations, and factories for creating InteractiveBrokersDataClient and InteractiveBrokersExecutionClient are added. Finally, the node is built and run.

设置完整的交易环境通常涉及配置 TradingNodeConfig,其中包括数据和执行客户端配置。在 LiveDataEngineConfig 中指定了附加配置以适应 IB 的特定要求。然后从这些配置中实例化一个 TradingNode,并添加用于创建 InteractiveBrokersDataClientInteractiveBrokersExecutionClient 的工厂。最后,构建并运行节点。

For a comprehensive example, refer to this script.

有关综合示例,请参阅此 脚本

from nautilus_trader.adapters.interactive_brokers.common import IB_VENUE
from nautilus_trader.adapters.interactive_brokers.factories import InteractiveBrokersLiveDataClientFactory
from nautilus_trader.adapters.interactive_brokers.factories import InteractiveBrokersLiveExecClientFactory
from nautilus_trader.config import LiveDataEngineConfig
from nautilus_trader.config import LoggingConfig
from nautilus_trader.config import TradingNodeConfig
from nautilus_trader.live.node import TradingNode


# ... [continuing from prior example code] ...

# Configure the trading node
# 配置交易节点
config_node = TradingNodeConfig(
    trader_id="TESTER-001",
    logging=LoggingConfig(log_level="INFO"),
    data_clients={"IB": data_client_config},
    exec_clients={"IB": exec_client_config},
    data_engine=LiveDataEngineConfig(
        time_bars_timestamp_on_close=False,  # Use opening time as `ts_event`, as per IB standard 使用开始时间作为 `ts_event`,按照 IB 标准
        validate_data_sequence=True,         # Discards bars received out of sequence 丢弃乱序接收的K线
    ),
)

node = TradingNode(config=config_node)
node.add_data_client_factory("IB", InteractiveBrokersLiveDataClientFactory)
node.add_exec_client_factory("IB", InteractiveBrokersLiveExecClientFactory)
node.build()
node.portfolio.set_specific_venue(IB_VENUE)

if __name__ == "__main__":
    try:
        node.run()
    finally:
        # Stop and dispose of the node with SIGINT/CTRL+C
        # 使用 SIGINT/CTRL+C 停止和处理节点
        node.dispose()