第二階段:核心組件深度解讀

模組 07:數據引擎 — 市場數據高速公路從市場到策略,數據如何被收集、處理和分發

一、數據引擎的職責

flowchart LR
                        subgraph sources["🌍 數據源"]
                        ws["交易所 WebSocket"]
                        rest["REST API"]
                        file["歷史數據文件"]
                        end
                        subgraph dc["📡 DataClient 適配器"]
                        parse["解析原始數據"]
                        normalize["標準化格式"]
                        end
                        subgraph de["📊 DataEngine 數據引擎"]
                        route["路由分發"]
                        aggregate["Bar 聚合"]
                        validate["數據驗證"]
                        end
                        subgraph output["📤 輸出"]
                        cache["💾 Cache"]
                        msgbus["📡 MessageBus"]
                        end
                        sources --> dc --> de --> output
圖 1:數據引擎的完整數據管道
📥

接收

從各種 DataClient 接收標準化後的市場數據(報價、成交、訂單簿)

🔄

聚合

將逐筆成交數據聚合為 K 線 (Bar),定義了 18 種聚合方式(其中 12 種已實現,6 種規劃中)

📤

分發

根據訂閱關係,透過 MessageBus 將數據推送給需要的組件

💾

緩存

將最新數據寫入 Cache,供其他組件隨時查詢

二、訂閱機制

策略不是「拉取」數據,而是「訂閱」數據。數據引擎負責管理所有訂閱關係:

# 在策略的 on_start() 中訂閱數據
def on_start(self):
    # 訂閱報價 — 每次有新報價就調用 on_quote_tick
    self.subscribe_quote_ticks(instrument_id)

    # 訂閱逐筆成交
    self.subscribe_trade_ticks(instrument_id)

    # 訂閱 K 線 — 例如 1 分鐘 K 線
    self.subscribe_bars(BarType.from_str("BTCUSDT.BINANCE-1-MINUTE-LAST"))

    # 訂閱訂單簿(深度 10 檔)
    self.subscribe_order_book_at_interval(
        instrument_id,
        depth=10,
        interval_ms=1000,  # 每秒快照一次
    )

三、Bar 聚合 — 18 種定義(12 種已實現)

K 線不一定是按時間分的。NautilusTrader 定義了多種聚合方式(✅ = 已實現,⚠️ = 規劃中未實現):

類別聚合方式說明適用場景
⏱️ 時間MILLISECOND每 N 毫秒超高頻策略
SECOND每 N 秒超短線
MINUTE每 N 分鐘日內交易
HOUR每 N 小時波段交易
DAY每 N 天中期趨勢
WEEK每 N 週長期趨勢
MONTH每 N 月宏觀分析
📊 活動量TICK每 N 筆成交高頻策略
VOLUME每 N 單位成交量量價分析
VALUE每 N 金額成交大額流動性分析
📉 不平衡TICK_IMBALANCE ⚠️買賣筆數不平衡達閾值訂單流分析(規劃中)
VOLUME_IMBALANCE ⚠️買賣量不平衡達閾值大單偵測(規劃中)
VALUE_IMBALANCE ⚠️買賣金額不平衡達閾值資金流向分析(規劃中)
🏃 連續TICK_RUNS ⚠️連續同向成交筆數達閾值動量偵測(規劃中)
VOLUME_RUNS ⚠️連續同向成交量達閾值趨勢確認(規劃中)
VALUE_RUNS ⚠️連續同向成交金額達閾值機構行為分析(規劃中)
📈 價格RENKO磚形圖(價格移動固定幅度)趨勢過濾、噪音消除
📅 年度YEAR每 N 年超長期分析
# Bar 類型格式:{品種ID}-{數量}-{聚合方式}-{價格來源}-{聚合來源}
# 聚合來源:INTERNAL(本地聚合)或 EXTERNAL(交易所提供)
bar_type_1min  = BarType.from_str("BTCUSDT.BINANCE-1-MINUTE-LAST-INTERNAL")
bar_type_tick  = BarType.from_str("BTCUSDT.BINANCE-100-TICK-LAST-INTERNAL")
bar_type_vol   = BarType.from_str("BTCUSDT.BINANCE-1000-VOLUME-LAST-INTERNAL")
bar_type_renko = BarType.from_str("BTCUSDT.BINANCE-50-RENKO-MID-INTERNAL")

# ✨ 新功能:Composite Bar(Bar-to-Bar 聚合)
# 從 1 分鐘 K 線聚合出 5 分鐘 K 線,使用 @ 語法
bar_type_5min = BarType.from_str("BTCUSDT.BINANCE-5-MINUTE-LAST-INTERNAL@1-MINUTE-EXTERNAL")
💡 為什麼時間以外的聚合方式很重要?

時間 K 線在波動很低的時段會產生很多「空洞」的 K 線(幾乎沒有成交)。成交量 K 線和 Tick K 線則只在有實際交易發生時才形成,能更真實地反映市場活動。

四、數據客戶端 (DataClient)

DataClient 是連接外部數據源的適配器。每個交易所或數據供應商都有自己的 DataClient 實現:

flowchart LR
                        subgraph clients["DataClient 實現 (接入層)"]
                        direction TB
                        binance_dc["Binance Client"]
                        ib_dc["IB Client"]
                        sim_dc["Backtest Client"]
                        end

                        de["📊 DataEngine<br/>數據引擎主體"]

                        clients ==> de

                        style de fill:#0f1419,stroke:#4fc3f7,stroke-width:2px
                        style clients fill:#0f1419,stroke:#ab47bc,stroke-width:1px
圖 2:不同的 DataClient 都接入同一個 DataEngine

五、互動練習

🧠 練習:設計數據訂閱

你的策略需要以下數據,寫出對應的訂閱代碼:

  1. BTC/USDT 的即時報價(用於判斷買賣價差)
  2. 每 500 筆成交一根的 Tick K 線(用於高頻信號)
  3. 5 分鐘 K 線(用於趨勢判斷)
def on_start(self):
    btc_id = InstrumentId.from_str("BTCUSDT.BINANCE")

    # 1. 即時報價
    self.subscribe_quote_ticks(btc_id)

    # 2. 每 500 筆成交的 Tick K 線
    self.subscribe_bars(
        BarType.from_str("BTCUSDT.BINANCE-500-TICK-LAST")
    )

    # 3. 5 分鐘 K 線
    self.subscribe_bars(
        BarType.from_str("BTCUSDT.BINANCE-5-MINUTE-LAST")
    )

六、本模組重點回顧

📋 關鍵點
  1. 數據引擎負責接收、聚合、驗證和分發所有市場數據
  2. 訂閱模式:策略訂閱感興趣的數據,引擎自動推送
  3. 18 種 Bar 聚合定義(其中 12 種已實現):時間、成交量、Tick、Renko 等多種方式
  4. DataClient:統一介面,不同實現連接不同數據源