模組 15:實盤部署進階對帳、容錯、控制器 — 讓你的交易系統 7×24 穩定運行
一、實盤與回測的根本差異
❌ 回測世界:數據完美、網路零延遲、交易所永不出錯、程序永不崩潰。
✅ 實盤世界:網路會斷、交易所會拒單、API 會限速、程序會崩潰、訂單會卡住。NautilusTrader 的 live/
模組就是為了對付這些「現實世界的混亂」。
flowchart TB
subgraph live["🚀 實盤專屬機制"]
direction LR
recon["🔄 Reconciliation<br/>訂單對帳"]
retry["🔁 Retry<br/>自動重試"]
ctrl["🎮 Controller<br/>交易控制器"]
filter["📅 Filters<br/>交易日曆"]
heartbeat["💓 Heartbeat<br/>心跳檢測"]
end
recon --> |"確保一致性"| safe["✅ 穩定運行"]
retry --> |"容錯"| safe
ctrl --> |"全局控制"| safe
filter --> |"避免非交易時段"| safe
heartbeat --> |"及時發現斷線"| safe
style live fill:#0f1419,stroke:#4fc3f7,stroke-width:2px
style safe fill:#0f1419,stroke:#4caf50,stroke-width:2px
二、Reconciliation — 訂單對帳
對帳是實盤中最重要的機制。它確保本地系統的訂單/持倉狀態與交易所完全一致。
什麼時候需要對帳?
程序崩潰重啟
崩潰期間交易所可能執行了你的掛單
網路中斷恢復
斷線期間錯過了訂單成交回報
每日定時啟動
隔夜可能有倉位變化、強制平倉
對帳流程
sequenceDiagram
participant NT as NautilusTrader
participant EX as Exchange
NT->>EX: 1. 請求所有 open orders
EX-->>NT: 返回 open orders list
NT->>NT: 2. 比對本地訂單狀態
NT->>EX: 3. 請求帳戶餘額和持倉
EX-->>NT: 返回帳戶狀態
NT->>NT: 4. 比對本地 Portfolio
Note over NT: 5. 生成差異報告
NT->>NT: 6. 自動修正本地狀態
# 啟用對帳
from nautilus_trader.live.config import LiveExecEngineConfig
exec_config = LiveExecEngineConfig(
reconciliation=True, # 啟用對帳
inflight_check_interval_ms=2000, # 每 2 秒檢查飛行中訂單
inflight_check_threshold_ms=5000, # 超過 5 秒未確認 → 告警
)
# 對帳會在啟動時自動執行,無需手動觸發
# 超時由 timeout_reconciliation 控制(預設 30s)三、Retry — 自動重試
當訂單提交失敗時(網路超時、API 限速),系統會自動重試:
| 場景 | 行為 | 注意 |
|---|---|---|
| 網路超時 | 等待後重試 | 使用指數退避避免打爆 API |
| API 限速 (429) | 等待限速窗口後重試 | 搭配 RiskEngine 的 max_order_submit_rate |
| 交易所拒絕 | 不重試,記錄錯誤 | 餘額不足、參數錯誤等 |
| 連接斷開 | 等待重連後重試 | Heartbeat 機制會觸發重連 |
四、Trading Controller — 交易控制器
Controller 是一個全局控制器,可以管理多個策略的生命週期:
from nautilus_trader.trading.controller import Controller
from nautilus_trader.config import ControllerConfig
class MyController(Controller):
"""管理多個策略的啟停"""
def on_start(self):
self.log.info("Controller 啟動")
# 可以在這裡根據條件決定啟動哪些策略
def on_stop(self):
self.log.info("Controller 停止")
def on_trading_state_changed(self, state):
"""當交易狀態改變時(如從 ACTIVE 變為 HALTED)"""
if state == TradingState.HALTED:
self.log.warning("交易暫停!取消所有掛單")
for strategy in self.trader.strategies():
strategy.cancel_all_orders(strategy.instrument_id)
def create_actor(self, actor_config):
"""動態創建 Actor"""
pass
def create_strategy(self, strategy_config):
"""動態創建策略"""
pass
Strategy:負責一個策略的交易邏輯。
Controller:負責管理多個 Strategy 的啟停、動態增刪策略。像是「策略的經理人」。
五、Trading Filters — 交易過濾器
避免在非交易時段或特殊日子下單:
from nautilus_trader.trading.filters import (
NewsImpactFilter, # 新聞事件過濾
ForexSessionFilter, # 外匯交易時段
EconomicNewsEventFilter, # 經濟數據發布
)
# 在策略中使用
class MyStrategy(Strategy):
def on_bar(self, bar):
# 跳過非交易時段
if not self._is_trading_hours(bar.ts_event):
return
# 跳過重大新聞前後 30 分鐘
if self._near_news_event(bar.ts_event, buffer_minutes=30):
return
# 正常交易邏輯...
self._check_entry_signal(bar)
六、Emulated Orders — 模擬訂單
有些交易所不支持某些訂單類型(如 Trailing Stop)。NautilusTrader 的 OrderEmulator 可以在本地模擬這些訂單:
| 訂單類型 | 交易所是否原生支持 | Emulator 模擬 |
|---|---|---|
| Market Order | ✅ 所有交易所 | 不需要模擬 |
| Limit Order | ✅ 所有交易所 | 不需要模擬 |
| Stop Market | ⚠️ 大部分支持 | 可選 |
| Trailing Stop | ❌ 部分不支持 | ✅ Emulator 模擬 |
| Market-If-Touched | ❌ 部分不支持 | ✅ Emulator 模擬 |
from nautilus_trader.common.config import OrderEmulatorConfig
emulator_config = OrderEmulatorConfig()
# 在 TradingNodeConfig 中啟用
config = TradingNodeConfig(
emulator=emulator_config,
# ... 其他配置
)
# 然後在策略中正常使用 Trailing Stop
# 如果交易所不支持,Emulator 會在本地模擬它
order = self.order_factory.trailing_stop_market(
instrument_id=self.instrument_id,
order_side=OrderSide.SELL,
quantity=Quantity.from_str("1.0"),
trailing_offset=Decimal("50"),
trailing_offset_type=TrailingOffsetType.BASIS_POINTS,
trigger_type=TriggerType.LAST_TRADE,
emulation_trigger=TriggerType.LAST_TRADE, # ← 指定模擬觸發
)七、互動練習
你的策略在凌晨 3 點崩潰了,凌晨 5 點自動重啟。期間有一筆限價買入單在凌晨 4 點成交了。重啟後會發生什麼?
如果開啟了 reconciliation=True:
- 重啟時系統向交易所請求所有訂單和持倉
- 發現交易所報告:限價單已 FILLED + 持倉 +1
- 本地狀態:限價單 SUBMITTED(未更新)
- 對帳器自動修正:
- 生成
OrderFilled事件 - 更新本地持倉
- 更新 Portfolio 餘額
- 生成
- 策略收到
on_order_filled回調 - 策略可以繼續正常運作
如果沒開對帳(reconciliation=False):
- ❌ 本地以為單子還掛著
- ❌ 不知道已經有持倉
- ❌ 可能重複下單 → 災難!
你有 3 個策略同時運行。週末和美國假期不想交易。設計一個 Controller 的 on_start 邏輯。
設計思路:
def on_start(self):
now = self.clock.utc_now()
# 檢查是否為週末
if now.weekday() >= 5: # 6=週六, 7=週日
self.log.warning("週末,不啟動策略")
return
# 檢查是否為美國假期
us_holidays = [...] # 預定義的假期列表
if now.date() in us_holidays:
self.log.warning(f"假期 {now.date()},不啟動策略")
return
# 啟動所有策略
for strategy in self.trader.strategies():
strategy.start()
self.log.info(f"啟動策略: {strategy.id}")
# 設定收盤前自動平倉定時器
self.clock.set_timer(
name="close_positions",
interval=timedelta(minutes=5),
callback=self._check_close_time,
)你想用 Trailing Stop,但不確定交易所是否支持。用 Emulator 和 Native 各有什麼優缺點?
Native(交易所原生支持):
- ✅ 0 延遲 — 觸發和執行都在交易所端
- ✅ 不依賴你的程序 — 即使你斷線也會執行
- ❌ 不是所有交易所都支持
Emulated(本地模擬):
- ✅ 適用於任何交易所 — 不管交易所是否支持
- ✅ 更靈活 — 可以自定義觸發邏輯
- ❌ 有延遲 — 觸發後還要發送訂單到交易所
- ❌ 依賴程序 — 如果程序崩潰,模擬訂單消失
優先使用 Native,只有在交易所不支持時才用 Emulated
如果用 Emulated,確保有 save_state=True 保存狀態
八、本模組重點回顧
- Reconciliation:啟動時自動對帳,確保本地和交易所狀態一致
- Retry:訂單提交失敗自動重試,使用指數退避
- Controller:全局管理多個策略的啟停和生命週期
- Trading Filters:過濾非交易時段和重大新聞事件
- OrderEmulator:在本地模擬交易所不支持的訂單類型
- Heartbeat:定期心跳檢測,斷線自動重連