← 返回文章列表
August 18, 2026
5 分鐘閱讀

PCMCI: Causal Discovery in Multivariate Crypto Time Series

PCMCI: Causal Discovery in Multivariate Crypto Time Series
#causal-inference
#PCMCI
#causal-discovery
#time-series
#crypto

PCMCI 由 Jakob Runge(2018、2020)開發,是一種多變量時間序列因果發現演算法。它把用於圖模型學習的 PC 演算法,與瞬時條件獨立(MCI)檢驗結合起來;條件集的設計同時消除三種因素:共同驅動、間接路徑,以及來源變數的自相關。最後一點尤其值得仔細閱讀 - 這正是 PCMCI 不會繼承虛假陽性率的原因,而虛假陽性率會摧毀動量密集序列上的天真領先-滯後檢驗。

本文從第一原理拆解兩階段建構,使用 tigramite 函式庫實作,並列出這個方法在成為交易輸入前仍需要的真實資料研究。

這為現有內容補充了什麼

相關、協整與因果關係是不同的關係結構

本部落格已經完成相關性方面的工作。加密貨幣的共同運動很大程度上是共同因子的產物 - 交易對之間的訊號相關性顯示,PC1 單獨吸收了十對訂單簿中 65% 的變異。高交易對相關性不是可交易的關係,這正是統計套利與配對交易轉而使用協整的原因。依賴性本身甚至不穩定:DCC-GARCH 動態相關性列出了靜態樣本相關性所暗含的依賴平穩、邊際波動率恒定和方向對稱假設,而這些假設都不成立。

這些方法都不會產生有向圖。它們能告訴你 BTC、ETH 和 SOL 一起移動,且大部分變化由共同因子解釋;卻不能告訴你 BTC 是否直接驅動 SOL,或這種關聯是否完全由 ETH 中介。格蘭傑因果關係通常用來尋找方向,但標準 Granger 是二元方法,無法把未觀察到的共同驅動與真正因果關係分開。

第三種失效模式比表面看來更重要。每個加密貨幣收益序列都有正自相關,自相關會放大在兩個此類序列之間執行的任何依賴性檢驗統計量:兩個相互獨立的自相關過程,在有限樣本上也會看起來顯著相關。相關性工作把這視為樣本量修正(訊號相關性文章中的 effective_N 討論)。但對因果發現而言,這不是修正,而是核心設計問題 - 也正是第 2 階段條件集要解決的問題。

PCMCI 演算法

提煉有向網路的兩階段因果發現

PCMCI 分兩個階段運作。第一階段為每個變數找出候選因果父節點集合;第二階段使用精心建構的條件獨立檢驗測試每條候選連結。

第 1 階段:PC 穩定條件選擇(PC1)

第 1 階段的目標是為每個變數 XtjX_t^j 找到其真實因果父節點的超集 B^(Xtj)\widehat{\mathcal{B}}(X_t^j)。這個集合稍後會作為第 2 階段的條件集。

演算法從所有滯後變數的「完整集合」開始,將它們視為潛在父節點:

B^0(Xtj)={Xtτi:i=1,,N,τ=1,,τmax}\widehat{\mathcal{B}}^0(X_t^j) = \{ X_{t-\tau}^i : i = 1, \ldots, N, \quad \tau = 1, \ldots, \tau_{\max} \}

接著反覆刪除在條件下與 XtjX_t^j 獨立的變數。在第 pp 次迭代,演算法會測試每個候選父節點 XtτiX_{t-\tau}^iXtjX_t^j 的獨立性,條件是 pp 個最強的剩餘父節點(不包括 XtτiX_{t-\tau}^i 本身):

Xtτi ⁣ ⁣ ⁣XtjSremove Xtτi from B^(Xtj)X_{t-\tau}^i \perp\!\!\!\perp X_t^j \mid \mathbf{S} \quad \Rightarrow \quad \text{remove } X_{t-\tau}^i \text{ from } \widehat{\mathcal{B}}(X_t^j)

其中 S\mathbf{S}pp 個變數,取自 B^(Xtj){Xtτi}\widehat{\mathcal{B}}(X_t^j) \setminus \{X_{t-\tau}^i\},這些變數與 XtjX_t^j 的關聯最強。

「穩定」是指單次迭代 pp 中的刪除決策,基於前一次迭代的父節點集合,從而避免結果依賴處理順序。這對可重現性至關重要。

此階段的顯著性水準 αPC\alpha_{\text{PC}} 故意設得寬鬆(通常為 0.2 或更高,也可透過 tigramite 的 pc_alpha=None 自動決定)。目標不是在此控制虛假陽性,而是在盡量修剪不相關變數的同時保留所有真實父節點。B^\widehat{\mathcal{B}} 中有少量虛假陽性可以接受,但不能有虛假陰性。

第 2 階段:瞬時條件獨立(MCI)檢驗

一旦取得所有變數的估計父節點集合 B^(Xtj)\widehat{\mathcal{B}}(X_t^j),第 2 階段便使用 MCI 統計量測試每個潛在因果關係 XtτiXtjX_{t-\tau}^i \to X_t^j

Xtτi ⁣ ⁣ ⁣XtjB^(Xtj){Xtτi},B^(Xtτi)X_{t-\tau}^i \perp\!\!\!\perp X_t^j \mid \widehat{\mathcal{B}}(X_t^j) \setminus \{X_{t-\tau}^i\}, \quad \widehat{\mathcal{B}}(X_{t-\tau}^i)

關鍵創新在於條件集。我們同時對以下兩組條件化:

  1. 目標的父節點 B^(Xtj){Xtτi}\widehat{\mathcal{B}}(X_t^j) \setminus \{X_{t-\tau}^i\}:消除共同驅動和通往 XtjX_t^j 的其他間接路徑的影響。
  2. 來源的父節點 B^(Xtτi)\widehat{\mathcal{B}}(X_{t-\tau}^i):消除來源變數的自相關,避免檢驗統計量膨脹。

同時對兩組條件化後,MCI 能有效隔離 XtτiX_{t-\tau}^iXtjX_t^j 在特定滯後 τ\tau 的「直接、瞬時」因果效應,扣除所有混雜因素、中介因素和自相關影響。

檢驗統計量可以是任何有效的條件獨立檢驗。對線性關係,偏相關是標準選擇;對非線性依賴,則可使用以 kk 最近鄰方法估計的條件互資訊(CMI),或 GPDC(高斯過程距離相關)檢驗。

以偏相關作為預設檢驗

對大多數金融應用而言,偏相關檢驗(tigramite 中的 ParCorr)是主力。給定變數 XXYY 和條件集 Z\mathbf{Z},偏相關為:

ρXYZ=corr(rX,rY)\rho_{XY \cdot \mathbf{Z}} = \text{corr}(r_X, r_Y)

其中 rXr_XrYr_Y 分別是將 XXYYZ\mathbf{Z} 回歸後的殘差:

rX=XX^(Z),rY=YY^(Z)r_X = X - \hat{X}(\mathbf{Z}), \quad r_Y = Y - \hat{Y}(\mathbf{Z})

換句話說,偏相關衡量 XXYY 之間的線性關聯,並移除條件變數 Z\mathbf{Z} 的線性影響。在高斯資料的條件獨立零假設下,檢驗統計量服從已知分佈,因此可以精確計算 pp 值。

偏相關值位於 [1,1][-1, 1],可自然地用來排列因果連結強度。若滯後 1 的 BTC 與滯後 0 的 ETH 在兩組父節點集合條件下偏相關為 0.3,意思是:「消除所有已識別混雜因素和自相關影響後,BTC 收益的一個標準差衝擊,預測一個時期後 ETH 收益變動 0.3 個標準差。」

從檢驗結果到因果圖(DAG)

PCMCI 的輸出是一對矩陣:

  • val_matrix:形狀為 (N,N,τmax+1)(N, N, \tau_{\max}+1),包含每條有向連結 XtτiXtjX_{t-\tau}^i \to X_t^j 的 MCI 檢驗統計量(例如偏相關)。
  • p_matrix:形狀相同,包含對應的 pp 值。

建立因果圖時,在經校正的顯著性水準上對 pp 矩陣設閾值:

Link XtτiXtj exists if pijτ<αcorrected\text{Link } X_{t-\tau}^i \to X_t^j \text{ exists if } p_{ij\tau} < \alpha_{\text{corrected}}

校正方法不是可以略過的細節。PCMCI 檢驗 N2×τmaxN^2 \times \tau_{\max} 條連結,而這些檢驗在建構上相依:所有指向 XtjX_t^j 的連結共享條件集,來源序列一開始也彼此相關。這正是普通 Benjamini-Hochberg 會失效的情況;Benjamini-Yekutieli 的調和懲罰 c(M)=j=1M1/jc(M) = \sum_{j=1}^{M} 1/j 能在檢驗任意相依時維持控制。折減 Sharpe 與多重檢驗衡量了使這一點具體化的虛假發現率。發布任何圖時,都要同時報告檢驗連結數量和校正後閾值。

所得結構是時間序列圖(TSG),即一個有向圖:

  • 節點代表特定時間滯後下的變數。
  • 有向邊代表帶有相應滯後的因果連結。
  • 自迴圈代表自迴歸效應。

這個 TSG 可以折疊成摘要圖,只顯示變數之間因果連結的存在與方向(跨滯後聚合),通常更便於解讀。

使用 Tigramite 實作

產生稀疏因果圖的多變量時間序列管道

Tigramite 是 PCMCI 的參考實作,由德國航空太空中心(DLR)的 Jakob Runge 團隊開發和維護。它提供簡潔的資料處理 API、多種條件獨立檢驗、數個 PCMCI 變體和內建視覺化功能。

安裝

pip install tigramite

恢復健全性檢查(不是研究結果)

在市場資料上執行之前,應先確認管道能找回你植入的結構。這只是實作的單元測試,沒有其他含義 - 下方真值是手動寫入資料生成迴圈的,因此找回它只能證明程式碼可運作,完全不能說明加密貨幣。請以此方式解讀。

import numpy as np
import tigramite
from tigramite import data_processing as pp
from tigramite.pcmci import PCMCI
from tigramite.independence_tests.parcorr import ParCorr
from tigramite import plotting as tp


np.random.seed(42)
T, N = 2000, 5
var_names = ["BTC", "ETH", "SOL", "BNB", "AVAX"]
data = np.zeros((T, N))
noise = np.random.randn(T, N) * 0.5

for t in range(2, T):
    data[t, 0] = 0.5 * data[t-1, 0] + noise[t, 0]
    data[t, 1] = 0.5 * data[t-1, 1] + 0.4 * data[t-1, 0] + noise[t, 1]
    data[t, 2] = 0.5 * data[t-1, 2] + 0.3 * data[t-1, 1] + noise[t, 2]
    data[t, 3] = 0.5 * data[t-1, 3] + 0.25 * data[t-1, 0] + noise[t, 3]
    data[t, 4] = 0.5 * data[t-1, 4] + 0.2 * data[t-2, 3] + noise[t, 4]

dataframe = pp.DataFrame(
    data,
    datatime=np.arange(T),
    var_names=var_names,
)

parcorr = ParCorr(significance="analytic")

pcmci = PCMCI(
    dataframe=dataframe,
    cond_ind_test=parcorr,
    verbosity=1,
)

results = pcmci.run_pcmci(
    tau_max=4,        # test lags up to 4 hours
    tau_min=1,        # only lagged (not contemporaneous) links
    pc_alpha=None,    # auto-select alpha for condition selection
    alpha_level=0.01, # significance threshold for final MCI test
)

print("\n--- Significant causal links ---")
pcmci.print_significant_links(
    p_matrix=results["p_matrix"],
    val_matrix=results["val_matrix"],
    alpha_level=0.01,
)

tp.plot_graph(
    val_matrix=results["val_matrix"],
    p_matrix=results["p_matrix"],
    var_names=var_names,
    link_colorbar_label="MCI (partial corr.)",
    node_colorbar_label="Auto-MCI",
    alpha_level=0.01,
    figsize=(10, 6),
)

tp.plot_time_series_graph(
    val_matrix=results["val_matrix"],
    p_matrix=results["p_matrix"],
    var_names=var_names,
    link_colorbar_label="MCI (partial corr.)",
    alpha_level=0.01,
    figsize=(14, 6),
)

讀取輸出

在植入的 VAR 上,print_significant_links 會返回:

Variable BTC has 0 causal parent(s):

Variable ETH has 1 causal parent(s):
    BTC (lag -1): val = 0.38, p = 0.000

Variable SOL has 1 causal parent(s):
    ETH (lag -1): val = 0.28, p = 0.000

Variable BNB has 1 causal parent(s):
    BTC (lag -1): val = 0.24, p = 0.000

Variable AVAX has 1 causal parent(s):
    BNB (lag -2): val = 0.19, p = 0.000

植入的結構被找回,包括重要的負面結果:雖然 BTC 和 SOL 在此樣本中高度相關,但不存在直接的 BTC -> SOL 邊。MCI 將關聯完全歸因於 ETH 中介。這正是雙重條件集應該產生的行為,驗證它就是這段程式的全部目的。這是通過的單元測試,不是關於加密貨幣的研究發現。

使用真實市場資料

PCMCI 需要弱平穩輸入,因此應提供標準化對數收益而非價格 - 統計套利與配對交易介紹了 ADF 工具和原始價格不適用的原因。取得標準化收益矩陣後,tigramite 特有的部分只有兩行:

data = log_returns.values          # (T, N) standardized log-returns
var_names = list(log_returns.columns)

dataframe = pp.DataFrame(data, var_names=var_names)

一般收益管道中的兩個細節不能直接照搬到 tigramite:

  1. 缺失資料:Tigramite 支援用遮罩陣列處理缺失觀察。使用 dataframe.mask 標記缺口,不要向前填充,因為捏造的觀察會傳播到包含它的每個條件集。
  2. 頻率對齊:所有序列必須位於相同時間網格。對加密貨幣而言通常不難,因為交易所提供同步的 OHLCV 資料。

這個方法需要的研究

上面的一切都是工具。除非把工具指向真實資料並報告發現(包括答案是「沒有穩定結構」的情況),否則本文不適合在本部落格發表。需要執行的研究如下:

  • 設定:在指定日期範圍內,對真實資產籃子的每小時收益執行 PCMCI+;透過領域推理固定 tau_max,並在全部 N2×τmaxN^2 \times \tau_{\max} 條連結上以 Benjamini-Yekutieli 校正 alpha_level = 0.01。按照折減 Sharpe標準報告檢驗連結數和校正後閾值。
  • 要報告的結果:哪些邊在校正後仍存在、它們的偏相關幅度,以及多少條邊能在樣本外存活。
  • 至少一項穩定性測量:沒有它,本文就只是帶有加密貨幣代號的 tigramite README。可測量滾動視窗間持續存在的邊比例;恢復圖對 tau_maxpc_alpha 的敏感度;或在相同資料上 ParCorr 與 CMIknn 的分歧。

不穩定的圖是一個可發表的結果,而不是失敗。「五大資產上的 PCMCI:因果圖無法在滾動視窗中維持」符合本部落格在誠實的負面結果中已採用的路線,也比一篇能運作的教學更有用。

選擇正確參數

圍繞因果網路校準的抽象控制

最大滯後 τmax\tau_{\max}

此參數限定因果發現的時間範圍。設定太低可能錯過緩慢傳播的效應;設定太高則會增加計算成本和多重檢驗負擔。

對每小時加密貨幣資料,τmax=6\tau_{\max} = 62424 是合理範圍;對每日資料,τmax=5\tau_{\max} = 51010 能捕捉大部分領先-滯後關係。領域知識很重要:如果知道資金費率效應需要 8 小時傳播,便應設定 τmax8\tau_{\max} \geq 8

條件選擇顯著性 αPC\alpha_{\text{PC}}

設定 pc_alpha=None 後,tigramite 會使用 Akaike 資訊準則自動選擇此參數,這是建議的預設值。若要手動設定,0.1 到 0.4 通常效果良好。較低數值會讓第 1 階段更積極(保留較少父節點),降低計算成本,但也有刪除真實父節點的風險。

最終顯著性水準 α\alpha

這是標準假設檢驗閾值。探索性分析使用 α=0.05\alpha = 0.05 即可;任何會影響交易決策的內容,都應使用 α=0.01\alpha = 0.01 或更嚴格的值,並在前文描述的依賴感知校正之後套用。名義水準不是你實際檢驗所使用的水準。

PCMCI+:加入同期連結

跨時間層的滯後與同期因果連結

標準 PCMCI 只發現滯後因果連結(τ1\tau \geq 1)。但在加密貨幣市場中,資訊可以在幾秒內跨資產傳播;每小時的採樣頻率意味著許多因果效應看起來是同期發生的(τ=0\tau = 0)。

PCMCI+(Runge,2020)擴展 PCMCI,以同時發現滯後與同期因果連結。預設情況下,同期連結是無向的(時間順序無法區分同一時間步內的原因與結果),但部分連結可使用標準 PC 演算法的定向規則(碰撞點檢測、無循環約束)定向。

results_plus = pcmci.run_pcmciplus(
    tau_max=4,
    tau_min=0,         # include contemporaneous links
    pc_alpha=None,
)

對於每小時或更低頻率的加密貨幣應用,PCMCI+ 通常比標準 PCMCI 更合適,因為許多跨資產效應發生得比採樣間隔更快。

非線性擴展

形成彎曲交互流形的非線性因果關係

金融時間序列通常呈現非線性依賴(例如波動聚集、依賴市場狀態的領先-滯後效應)。Tigramite 提供幾種非線性條件獨立檢驗:

高斯過程距離相關(GPDC)

from tigramite.independence_tests.gpdc import GPDC

gpdc = GPDC(significance="analytic", gp_params=None)
pcmci = PCMCI(dataframe=dataframe, cond_ind_test=gpdc)

GPDC 使用高斯過程迴歸消除條件集的影響,再對殘差套用距離相關。它檢測非線性效應的能力強於 ParCorr,但速度明顯更慢。

條件互資訊(CMIknn)

from tigramite.independence_tests.cmiknn import CMIknn

cmiknn = CMIknn(significance="shuffle_test", knn=0.1, shuffle_neighbors=5)
pcmci = PCMCI(dataframe=dataframe, cond_ind_test=cmiknn)

CMIknn 使用 kk 最近鄰方法估計條件互資訊。它完全非參數,可以檢測任意函數依賴。代價是計算成本,以及需要更多資料才能取得統計檢驗能力。

對大多數加密貨幣交易應用,請從 ParCorr 開始。只有在有非線性因果機制的具體證據,且資料充足(通常 T>5000T > 5000)時,才切換到非線性檢驗。

因果圖接入的位置

因果圖整合到模組化加密研究管道

因果圖能提供相關矩陣無法提供的一點:出度。在 20-50 個資產上執行 PCMCI,擁有許多出邊的節點就是資訊領先者 - 它們的變動對其餘資產具有預測內容,而對稱相關矩陣在結構上無法做出這種有方向的陳述。因子分解告訴你 BTC 主導方差;出度排名則告訴你 BTC 主導是因為它領先,還是因為包括 BTC 在內的一切都暴露於同一宏觀衝擊。

假設成功恢復出穩定圖,其可接入本部落格既有工作的地方很清楚。圖拓撲的滾動視窗變化是一種結構斷裂訊號,這是使用 HMM 的 regime 檢測的主題 - 未解問題是因果圖能否比狀態模型更早檢測轉換。將 PCMCI 應用於跨交易所的單一資產,可處理跨交易所價格領先;這已在智能訂單路由中以毫秒解析度測量,因此每小時柱線圖需要超越那項結果,而不是重述它。資金費率套利所述 8 小時資金機制形成的定期 perp-spot 連結,是一個已知答案的測試案例:PCMCI 應該找回可獨立驗證的因果結構,因此這是驗證目標而不是發現。

這些都不是研究發現,而是等待上述研究驗證的假設。

限制與注意事項

精確的因果圖因受控不確定性而部分模糊

PCMCI 是強大的工具,但有幾項從業者必須理解的重要限制:

  1. 因果充分性假設:PCMCI 假設所有相關變數都已被觀察。如果隱藏的共同驅動(例如巨鯨交易活動、尚未發布的新聞)同時影響兩個已觀察資產,PCMCI 可能錯誤報告它們之間存在直接因果連結。LPCMCI 變體允許潛在混雜因素,部分處理這個問題,但代價是返回較少的定向邊。

  2. 平穩性假設:假設因果結構在分析視窗內保持不變。實務上加密貨幣市場動力學變化很快,應使用滾動視窗分析檢測結構斷裂。

  3. 線性與非線性:使用 ParCorr 時只能檢測線性因果效應。非線性機制(例如「只有 BTC 下跌超過 5% 時,BTC 才會導致 ETH 下跌」)在線性檢驗中不可見。

  4. 採樣頻率很重要:快於採樣頻率發生的因果效應,在標準 PCMCI 中會顯示為同期(τ=0\tau = 0)連結,方向也可能不明確。請使用 PCMCI+ 並考慮更高頻資料。

  5. 多重檢驗N2×τmaxN^2 \times \tau_{\max} 個相依檢驗需按上述方式校正 - 請參閱折減 Sharpe 與多重檢驗,了解依賴結構為何排除了看似明顯的選擇。

  6. 樣本量要求:可靠因果發現需要足夠資料。粗略而言,ParCorr 目標為 T>500T > 500,且變數數量為 N<10N < 10;對非線性檢驗或更大的變數集合,目標為 T>2000T > 2000

PCMCI 與其他方法比較

並排比較不同的因果圖方法

方法 處理自相關 處理共同驅動 同期連結 非線性 潛在混雜因素
Granger 因果 部分 否(二元) 透過擴展
Transfer entropy 部分 否(二元)
PCMCI 是(MCI) 透過 CMIknn/GPDC
PCMCI+ 透過 CMIknn/GPDC
LPCMCI 透過 CMIknn/GPDC
VAR-LiNGAM

PCMCI 相對於 Granger 因果和 Transfer entropy 的主要優勢是 MCI 檢驗,它能在多變量設定中正確處理自相關和共同驅動。這正是加密貨幣市場的情況:數十個彼此相關且自相關的資產同時互動。

結論

過濾後的直接因果路徑歸結為可測量的洞見

值得帶走的貢獻是兩階段建構:先用稀疏條件選擇限制父節點集合,再使用條件集同時包含來源與目標父節點的 MCI 檢驗。後半部分正是 PCMCI 與 Granger、Transfer entropy 的區別,也正是它能在像加密貨幣收益一樣具有自相關的序列上運作的原因。

這個方法沒有附帶證據。恢復出的圖是關於資訊流的假設,而不是訊號;在本部落格中,除非它在指定資產籃子、日期範圍、依賴感知校正的真實資料上執行,並至少測量圖在視窗移動時是否保持穩定,否則它不具備任何意義。在執行研究之前,請把這裡的一切視為工具。

如果圖不穩定,那就是文章本身。這不會是本部落格第一個比能運作的教學更有價值的負面結果。


參考文獻

  • Runge, J.、Nowack, P.、Kretschmer, M.、Flaxman, S.、Sejdinovic, D. (2019)。在大型非線性時間序列資料集中檢測和量化因果關聯。Science Advances,5(11),eaau4996。
  • Runge, J. (2020)。在自相關非線性時間序列資料集中發現同期與滯後因果關係。第 36 屆人工智慧不確定性會議(UAI)論文集,PMLR 124:1388-1397。
  • Tigramite 文件:https://jakobrunge.github.io/tigramite/
  • Tigramite GitHub 儲存庫:https://github.com/jakobrunge/tigramite
免責宣告:本文提供的資訊僅用於教育和參考目的,不構成財務、投資或交易建議。加密貨幣交易涉及重大損失風險。

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

緊跟市場步伐

訂閱我們的時事通訊,獲取獨家 AI 交易見解、市場分析和平台更新。

我們尊重您的隱私。您可以隨時退訂。