第四階段:進階擴展

模組 14:配置系統深潛掌握 NautilusTrader 的每一個配置參數,建立可重現、可調優的交易系統

一、為什麼配置系統如此重要?

💡 為什麼不直接在代碼裡寫死參數?

❌ 如果把參數寫在策略代碼裡:每次改參數都要改代碼 → 版本管理混亂 → 回測和實盤可能用了不同參數 → 災難。

✅ 用配置系統:參數集中管理、可序列化、可版本控制。NautilusConfig 基於 msgspec,所有配置都是 frozen(不可變) 的,確保運行期間不會被意外修改。

二、配置層級架構

NautilusTrader 的配置是樹狀結構,最頂層的配置包含所有子系統的配置:

flowchart TD
                        root["🔧 TradingNodeConfig / BacktestEngineConfig"]
                        kernel["NautilusKernelConfig"]
                        cache["CacheConfig"]
                        msgbus["MessageBusConfig"]
                        data["DataEngineConfig"]
                        exec["ExecEngineConfig"]
                        risk["RiskEngineConfig"]
                        log["LoggingConfig"]
                        port["PortfolioConfig"]
                        emu["OrderEmulatorConfig"]
                        stream["StreamingConfig"]
                        ctrl["ControllerConfig"]

                        root --> kernel
                        kernel --> cache
                        kernel --> msgbus
                        kernel --> data
                        kernel --> exec
                        kernel --> risk
                        kernel --> log
                        kernel --> port
                        kernel --> emu
                        kernel --> stream
                        kernel --> ctrl

                        style root fill:#0f1419,stroke:#4fc3f7,stroke-width:2px
                        style kernel fill:#0f1419,stroke:#ab47bc,stroke-width:2px
圖 1:配置的樹狀層級 — 一個頂層配置包含所有子系統配置
⚠️ frozen 不可變

所有的 Config 類都標記了 frozen=True,一旦創建就不能修改。這是刻意設計:確保在系統運行期間參數不會被意外改變。如果你需要改參數,必須重新創建配置並重啟系統。

三、NautilusKernelConfig — 核心配置

這是整個系統的核心配置,所有 TradingNodeConfig 和 BacktestEngineConfig 都繼承自它。

參數類型預設值說明
environmentEnvironment—運行環境:BACKTEST / SANDBOX / LIVE
trader_idTraderId“TRADER-001”交易員 ID,格式必須是 NAME-TAG
instance_idUUID4None (自動)實例 UUID,用於區分多個並行運行的實例
load_stateboolFalse啟動時是否從數據庫載入策略狀態
save_stateboolFalse停止時是否將策略狀態存入數據庫
loop_debugboolFalseasyncio 事件循環是否開啟 debug 模式

超時參數(實盤必調)

參數預設值說明
timeout_connection120s等待所有客戶端連接並初始化的超時
timeout_reconciliation30s等待執行狀態對帳的超時(實盤啟動時很重要)
timeout_portfolio10s等待 Portfolio 初始化保證金和未實現盈虧的超時
timeout_disconnection10s等待所有客戶端斷開連接的超時
timeout_post_stop10s停止後等待殘留事件的超時
timeout_shutdown5s最終關閉時等待待處理任務取消的超時

四、子系統配置詳解

4.1 CacheConfig — 緩存配置

from nautilus_trader.cache.config import CacheConfig

cache_config = CacheConfig(
    database=DatabaseConfig(
        type="redis",
        host="localhost",
        port=6379,
    ),
    timestamps_as_iso8601=True,   # 時間戳格式
    buffer_interval_ms=100,       # 批量寫入間隔
)
💡 為什麼需要 Redis 緩存?

❌ 不用外部緩存:程序崩潰後所有狀態丟失,重啟後策略不知道自己有多少持倉、有哪些未完成訂單。

✅ 用 Redis:狀態持久化,崩潰重啟後可以恢復 — 設定 load_state=True 即可自動從 Redis 載入之前的狀態。

4.2 MessageBusConfig — 消息總線配置

from nautilus_trader.common.config import MessageBusConfig

msgbus_config = MessageBusConfig(
    database=DatabaseConfig(
        type="redis",
        host="localhost",
        port=6379,
    ),
    stream_per_topic=True,        # 每個主題一個 Redis Stream
    autotrim_size=10000,          # 每個 Stream 最多保留 10000 條消息
    types_filter=[                # 只持久化特定事件類型
        "OrderFilled",
        "PositionChanged",
    ],
)

4.3 LoggingConfig — 日誌配置

from nautilus_trader.common.config import LoggingConfig

logging_config = LoggingConfig(
    log_level="INFO",              # 控制台日誌級別
    log_level_file="DEBUG",        # 文件日誌級別(更詳細)
    log_directory="./logs",        # 日誌文件目錄
    log_file_name="nautilus",      # 日誌文件名
    log_file_format=None,          # 日誌格式(None=預設)
    log_colors=True,               # 控制台彩色輸出
    log_component_levels={
        # 為特定組件設定不同日誌級別
        "RiskEngine": "WARNING",   # 風控引擎只記錄警告以上
        "DataEngine": "INFO",      # 數據引擎記錄所有信息
    },
    bypass_logging=False,          # 完全跳過日誌(極致性能模式)
)
⚠️ Rust 高性能日誌

NautilusTrader 的日誌系統底層是 Rust 實現的,這是它能在高頻場景下運行的關鍵。Python 的 logging 模組在每秒數萬條日誌時會顯著拖慢系統,但 Rust 日誌器幾乎沒有性能損失。

4.4 LiveDataEngineConfig / LiveExecEngineConfig

from nautilus_trader.live.config import (
    LiveDataEngineConfig,
    LiveExecEngineConfig,
    LiveRiskEngineConfig,
)

data_engine = LiveDataEngineConfig(
    qos=True,                     # 數據品質保證(檢查重複、順序)
)

exec_engine = LiveExecEngineConfig(
    reconciliation=True,          # 啟用訂單對帳(強烈建議開啟)
    inflight_check_interval_ms=2000,  # 檢查「飛行中」訂單的間隔
    inflight_check_threshold_ms=5000, # 訂單超過此時間未確認則告警
)

risk_engine = LiveRiskEngineConfig(
    bypass=False,                 # 是否跳過風控(生產環境請勿設 True!)
    max_order_submit_rate="100/00:00:01",     # 每秒最多提交 100 單
    max_order_modify_rate="100/00:00:01",     # 每秒最多修改 100 單
)

五、完整的實盤配置範例

"""完整的 TradingNode 配置 — 生產級別"""
from nautilus_trader.live.node import TradingNode
from nautilus_trader.live.config import (
    TradingNodeConfig,
    LiveDataEngineConfig,
    LiveExecEngineConfig,
    LiveRiskEngineConfig,
)
from nautilus_trader.cache.config import CacheConfig
from nautilus_trader.common.config import (
    DatabaseConfig,
    LoggingConfig,
    MessageBusConfig,
)
from nautilus_trader.adapters.binance.config import (
    BinanceLiveDataClientConfig,
    BinanceLiveExecClientConfig,
)

config = TradingNodeConfig(
    trader_id="LIVE-001",

    # === 緩存 ===
    cache=CacheConfig(
        database=DatabaseConfig(type="redis", host="localhost", port=6379),
    ),

    # === 消息總線 ===
    message_bus=MessageBusConfig(
        database=DatabaseConfig(type="redis", host="localhost", port=6379),
        types_filter=["OrderFilled", "PositionChanged"],
    ),

    # === 日誌 ===
    logging=LoggingConfig(
        log_level="INFO",
        log_level_file="DEBUG",
        log_directory="./logs",
    ),

    # === 引擎配置 ===
    data_engine=LiveDataEngineConfig(qos=True),
    exec_engine=LiveExecEngineConfig(
        reconciliation=True,
        inflight_check_interval_ms=2000,
    ),
    risk_engine=LiveRiskEngineConfig(
        max_order_submit_rate="50/00:00:01",
    ),

    # === 適配器 ===
    data_clients={
        "BINANCE": BinanceLiveDataClientConfig(
            api_key="your-key",
            api_secret="your-secret",
            account_type="USDT_FUTURE",
        ),
    },
    exec_clients={
        "BINANCE": BinanceLiveExecClientConfig(
            api_key="your-key",
            api_secret="your-secret",
            account_type="USDT_FUTURE",
        ),
    },

    # === 超時 ===
    timeout_connection=60.0,
    timeout_reconciliation=30.0,

    # === 狀態持久化 ===
    load_state=True,
    save_state=True,
)

node = TradingNode(config=config)
node.trader.add_strategy(my_strategy)
node.run()

六、回測 vs 實盤 配置對比

項目BacktestEngineConfigTradingNodeConfig
環境BACKTESTLIVE / SANDBOX
數據源BacktestDataConfig (Catalog)LiveDataClientConfig (適配器)
交易所BacktestVenueConfig (模擬)LiveExecClientConfig (真實)
引擎DataEngineConfigLiveDataEngineConfig (多了 qos 等)
Redis通常不需要強烈建議(狀態持久化)
對帳不需要reconciliation=True
策略代碼✅ 完全不變

七、StreamingConfig — 串流數據導出

from nautilus_trader.common.config import StreamingConfig

streaming = StreamingConfig(
    catalog_path="./catalog",    # 自動存入 DataCatalog
    fs_protocol="file",          # 文件系統協議
    include_types=[              # 只存這些數據類型
        "OrderFilled",
        "PositionChanged",
        "Bar",
    ],
)

# 在 TradingNodeConfig 中使用
config = TradingNodeConfig(
    streaming=streaming,
    # ... 其他配置
)

這樣在實盤運行時,指定的事件和數據會自動寫入 Parquet,回頭就能用 DataCatalog 做離線分析。

八、互動練習

🧠 練習 1:配置參數選擇

你的策略連接 Binance 交易所,但啟動時經常超時。你應該調整哪個超時參數?

調整 timeout_connection(預設 120s)

如果 120s 還不夠,可能原因:

  1. 網路延遲高 → 增加到 180s 或 300s
  2. 訂閱的品種太多 → 適配器需要更多時間初始化
  3. Binance API 限速 → 降低初始訂閱量

另外要檢查:

  • timeout_reconciliation(對帳超時)
  • timeout_portfolio(Portfolio 初始化超時)
💡 總結

如果只是偶爾超時,優先增加 timeout_connection
如果經常超時,需要檢查網路和訂閱邏輯

🧠 練習 2:Redis 配置決策

以下場景,你是否需要配置 Redis?為什麼?

  1. 只做歷史回測
  2. 實盤運行一個策略,白天手動重啟
  3. 7×24 自動化運行多個策略
  1. 只做回測 → ❌ 不需要
    回測是一次性運行,不需要狀態持久化
  2. 白天手動重啟 → ⚠️ 建議配置
    重啟後需要知道有哪些未完成訂單和持倉
    設定 load_state=True, save_state=True
  3. 7×24 自動化 → ✅ 必須配置
    • CacheConfig 用 Redis 存狀態
    • MessageBusConfig 用 Redis 存事件流
    • 崩潰重啟後自動恢復
    • 支持多實例分析歷史事件
🧠 練習 3:找出配置錯誤

以下生產配置有 3 個風險,找出來:

config = TradingNodeConfig(
    trader_id="LIVE-001",
    risk_engine=LiveRiskEngineConfig(
        bypass=True,                          # (1)
    ),
    exec_engine=LiveExecEngineConfig(
        reconciliation=False,                 # (2)
    ),
    logging=LoggingConfig(
        bypass_logging=True,                  # (3)
    ),
    load_state=False,
    save_state=False,
)

三個嚴重風險:

  1. bypass=True → 🔴 完全跳過風控!
    生產環境絕不能跳過風控,一個 bug 可能導致無限下單
    ✅ 修正:bypass=False
  2. reconciliation=False → 🔴 不對帳!
    重啟後本地訂單狀態和交易所不一致
    可能導致重複下單或遺失持倉追蹤
    ✅ 修正:reconciliation=True
  3. bypass_logging=True → 🟠 完全沒有日誌!
    出問題時無法排查原因
    ✅ 修正:bypass_logging=False,搭配合適的 log_level

九、本模組重點回顧

📋 關鍵點
  1. 樹狀配置:TradingNodeConfig 包含所有子系統配置(Cache、MessageBus、引擎、日誌)
  2. Frozen 不可變:所有 Config 都是 frozen,運行期間參數不能被修改
  3. Redis 持久化:Cache 和 MessageBus 可配置 Redis,實現狀態恢復和事件流存儲
  4. Rust 日誌:底層 Rust 實現,支持組件級日誌級別控制
  5. 超時參數:6 個超時參數控制系統啟動/關閉流程
  6. StreamingConfig:實盤數據自動寫入 Parquet,事後可做離線分析