📝

Draft article

This draft is visible to admins and superusers only. Sign in with an authorized account.

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

Transfer Entropy: Which Way Does Information Flow Between Crypto Assets?

Transfer Entropy: Which Way Does Information Flow Between Crypto Assets?
#causal-inference
#transfer-entropy
#information-theory
#crypto
#network

本部落格已經確立,加密市場接近單因子市場:配對之間的訊號相關性顯示 PC1(BTC 因子)解釋 65% 的變異,四個因子解釋 90%,因此十個「分散化」配對攜帶的資訊其實只來自三、四個獨立配對。依賴結構也不是固定的:DCC-GARCH將相關矩陣建模為有自身狀態的時間序列,而其 Limitations 章節直白指出:相關性不是因果,也不是方向。

最後這個缺口正是本文要處理的。DCC 告訴你依賴關係何時收緊,卻不能告訴你它指向哪個方向。轉移熵可以:它是無模型、天生不對稱的量,衡量一條序列的過去有多少位元能額外預測另一條序列的未來,超出目標序列自身過去已經解釋的部分。如果 ETH 持續在 AAVE 重新定價前向 AAVE 傳送資訊,轉移熵能看見任何相關矩陣都無法表示的不對稱性。

下文介紹這個量及其估計器,以及比量本身更重要的部分——決定資訊流網路究竟是訊號還是裝飾的零校準與敏感度分析。

已測量的網路

有向資訊網路

狀態:尚未執行。 下方管道已實作,但尚未在本文的真實資料上執行。在此之前,本文是方法說明,而不是結果。本部落格自己的標準——見誠實的負結果折損夏普與多重檢驗——是:未經校準的網路在證明之前都只是噪聲。

這裡必須按以下順序報告四件事,而且任何一件都不能只從文獻中斷言:

  1. 有效 TE 矩陣。 資產宇宙、交易所、日期範圍、bar 大小、每個有序配對的有效 TE 位元數、每對的 p 值,以及通過顯著性篩選的有向圖。用流出強度、流入強度和淨流量表取代「BTC 是主要來源、DeFi 代幣是接收者」這類空泛說法。
  2. 顯著性檢驗的假陽性率,在打亂序列和合成獨立序列上執行完整管道來測量。見下方的零校準
  3. 敏感度掃描,對兩個自由旋鈕交叉測試:n_bins 取 {3, 5},k 取 {1, 2, 3, 5}。如果領先者/跟隨者排名只在網格的一個格子成立,那就是結果。
  4. 隨時間的穩定性。 測量出的排名能否在樣本外持續,還是每個視窗都重新洗牌?回答之前,下游任何內容都不值得撰寫。

工具

穿越狀態空間的資訊路徑

三個基本構件

Shannon 熵衡量隨機變數 XX 的不確定性:

H(X)=i=1np(xi)log2p(xi)H(X) = -\sum_{i=1}^{n} p(x_i) \log_2 p(x_i)

擲硬幣是 1 位元;公平骰子是 log262.58\log_2 6 \approx 2.58 位元;確定性變數是 0。

條件熵衡量知道 XX 後,關於 YY 還剩多少不確定性:

H(YX)=x,yp(x,y)log2p(x,y)p(x)H(Y|X) = -\sum_{x,y} p(x,y) \log_2 \frac{p(x,y)}{p(x)}

XX 決定 YY 時為 0,兩者獨立時則等於 H(Y)H(Y)

互資訊是兩者共享的資訊:

I(X;Y)=H(Y)H(YX)=H(X)H(XY)I(X;Y) = H(Y) - H(Y|X) = H(X) - H(X|Y)

它是對稱的——I(X;Y)=I(Y;X)I(X;Y) = I(Y;X)——而這正是必須打破的對稱性。

轉移熵

Schreiber(2000)提出的轉移熵,透過以目標自身的過去作條件來打破對稱性。它衡量來源 XX 的過去在多大程度上降低目標 YY 未來的不確定性,超出 YY 自身過去已經解釋的部分

Yt(k)Y_t^{(k)} 表示長度為 kk 的歷史 (Yt1,,Ytk)(Y_{t-1}, \dots, Y_{t-k}),令 Xt(l)X_t^{(l)} 表示長度為 ll 的來源歷史:

TXY=p(Yt+1,Yt(k),Xt(l))log2p(Yt+1Yt(k),Xt(l))p(Yt+1Yt(k))T_{X \to Y} = \sum p(Y_{t+1}, Y_t^{(k)}, X_t^{(l)}) \log_2 \frac{p(Y_{t+1} \mid Y_t^{(k)}, X_t^{(l)})}{p(Y_{t+1} \mid Y_t^{(k)})}

等價地,可寫成條件熵之差:

TXY=H(Yt+1Yt(k))H(Yt+1Yt(k),Xt(l))T_{X \to Y} = H(Y_{t+1} \mid Y_t^{(k)}) - H(Y_{t+1} \mid Y_t^{(k)}, X_t^{(l)})

XX 的過去在 YY 自身過去之外沒有額外預測力,則 TXY=0T_{X \to Y} = 0;若有,大小就是流動的預測資訊位元數。

關鍵性質:

  • 非負: TXY0T_{X \to Y} \geq 0
  • 不對稱: 一般而言 TXYTYXT_{X \to Y} \neq T_{Y \to X}。這正是重點。
  • 非參數: 不作模型假設,線性和非線性依賴都能捕捉。
  • 單位: 使用 log2\log_2 時為位元,使用 ln\ln 時為納。

淨轉移熵給出主導方向:

TXYnet=TXYTYXT_{X \to Y}^{\text{net}} = T_{X \to Y} - T_{Y \to X}

正值表示 XXYY 淨傳送,負值表示 YY 領先。

轉移熵與 Granger 因果

線性與非線性因果機制

Granger 因果(GC)詢問 XX 的過去是否改善對 YY 的線性自回歸預測。這不是統計套利與配對交易中介紹的 Engle-Granger 協整檢驗——姓氏相同,概念無關。Engle-Granger 詢問兩條非平穩序列的線性組合是否平穩;Granger 因果詢問一條序列是否有助於預測另一條。本部落格讀者很容易混淆兩者,值得明說。

高斯過程的理論等價

Barnett、Barrett 和 Seth(2009)證明,對聯合高斯過程而言,Granger 因果與轉移熵只差一個單調轉換

TXY=12ln(1+FXY)T_{X \to Y} = \frac{1}{2} \ln\left(1 + F_{X \to Y}\right)

其中 FXYF_{X \to Y} 是 Granger 因果統計量(對數似然比)。對線性高斯資料,兩種方法得到的因果結構完全相同。因此轉移熵與其說是 GC 的競爭者,不如說是它的非參數推廣:在 GC 假設成立之處,它會精確退化為 GC。

兩者分歧之處

性質 Granger 因果 轉移熵
模型假設 線性 VAR 無(無模型)
非線性依賴 無法捕捉 可以捕捉
分布假設 高斯(F 檢驗)
樣本需求 中等
計算 快(OLS) 慢(密度估計)
解釋 預測改善 資訊傳遞(位元)

這個差距在原理上對加密市場很重要:報酬厚尾、波動率聚集、關係依賴市場狀態,而線性 VAR 會把這些都壓平。差距是否足以改變真實資料上的領先者排名,是本文必須回答而不能假設的實證問題。

Dimpfl 和 Peter(2013)報告,轉移熵能在金融序列中偵測到 Granger 因果遺漏的流動,尤其是在壓力期間;Keskin 和 Aste(2020)報告了加密市場中由非線性 TE 得出的更豐富網路。本文引用兩者作為動機,而不是這個資料集的證據。

有效轉移熵:偏差修正

偏差修正後的資訊流

這部分最容易出錯。有限樣本中的原始 TE 估計具有向上偏差:即使輸入兩條獨立序列,也會純粹因經驗聯合分布的抽樣噪聲而估計出 TXY>0T_{X \to Y} > 0。聯合狀態數越多,偏差越大;而狀態數會隨 k+lk + l 指數增長。

有效轉移熵扣除這個偏差:

TXYeff=TXYE ⁣[TXsurrogateY]T_{X \to Y}^{\text{eff}} = T_{X \to Y} - \mathbb{E}\!\left[T_{X_{\text{surrogate}} \to Y}\right]

其中 surrogate 會破壞 XX 的時間結構,同時保留其邊際分布。請注意這代表什麼、不代表什麼:**surrogate 平均值是估計器自身偏差的估計,我們將它扣除。**它不是信賴區間,有效 TE 也不是「帶誤差條的 TE」。同一組 surrogate 既可作為 p 值的零分布,也可用於偏差扣除,但這是兩種分開的用途。

Surrogate 以 block bootstrap 生成,使 XX 在區塊內的自相關得以保留;區塊重採樣的一般機制與理由見回測的蒙地卡羅與 bootstrap

實作

轉移熵研究管道

資料:單一交易所、指定連續日期範圍內主要 USDT 永續合約的每小時對數報酬。統計套利與配對交易已涵蓋標準 OHLCV 抓取和對數報酬構造,這裡不重複。

離散化——以及洩漏警告

轉移熵需要離散狀態。分位數分箱是通常選擇,也通常是未來資訊洩漏的地方。

import numpy as np
import pandas as pd

def discretize_trailing(series, n_bins=3, warmup=500):
    """Discretize using bin edges estimated on a TRAILING window only.

    Computing quantile edges over the full sample is whole-series
    normalization leakage: every bar's label depends on the entire
    future distribution. See the look-ahead bias taxonomy.
    """
    x = np.asarray(series, dtype=float)
    out = np.full(len(x), -1, dtype=int)
    qs = np.linspace(0, 1, n_bins + 1)[1:-1]
    for t in range(warmup, len(x)):
        edges = np.quantile(x[:t], qs)      # strictly past data
        out[t] = np.digitize(x[t], edges)
    return out

對於描述性主張——「在這段期間,資訊朝這個方向流動」——天真的全樣本版本可以接受;對任何可交易主張,它都受到污染。這個區分正是前視偏差分類的主題。如果使用全樣本邊界,請明說,並在「訊號」一詞之前停下。

從零計算轉移熵

from collections import Counter

def transfer_entropy(source, target, k=1, l=1):
    """Transfer entropy T_{source -> target} in bits.

    source, target : 1-D integer arrays of discrete states
    k : history length for the target
    l : history length for the source
    """
    source = np.asarray(source)
    target = np.asarray(target)
    n = len(target)
    max_lag = max(k, l)

    y_future = target[max_lag:]
    y_past = np.column_stack([target[max_lag - i - 1:n - i - 1] for i in range(k)])
    x_past = np.column_stack([source[max_lag - i - 1:n - i - 1] for i in range(l)])
    N = len(y_future)

    yf = y_future.tolist()
    yp = [tuple(row) for row in y_past]
    xp = [tuple(row) for row in x_past]

    c_yf_yp_xp = Counter(zip(yf, yp, xp))
    c_yp_xp = Counter(zip(yp, xp))
    c_yf_yp = Counter(zip(yf, yp))
    c_yp = Counter(yp)

    te = 0.0
    for (yf_val, yp_val, xp_val), count in c_yf_yp_xp.items():
        p_joint = count / N
        p_yf_given_yp_xp = count / c_yp_xp[(yp_val, xp_val)]
        p_yf_given_yp = c_yf_yp[(yf_val, yp_val)] / c_yp[yp_val]
        if p_yf_given_yp > 0 and p_yf_given_yp_xp > 0:
            te += p_joint * np.log2(p_yf_given_yp_xp / p_yf_given_yp)

    return te

block bootstrap 零分布下的有效 TE

def effective_transfer_entropy(source, target, k=1, l=1,
                               n_shuffles=200, block_size=5, rng=None):
    """Effective TE plus a surrogate p-value.

    Returns dict: te, ete, p_value, null_mean, null_std
    """
    rng = rng or np.random.default_rng(0)
    te_observed = transfer_entropy(source, target, k, l)

    n = len(source)
    n_blocks = int(np.ceil(n / block_size))
    null_tes = np.empty(n_shuffles)

    for b in range(n_shuffles):
        starts = rng.integers(0, n, size=n_blocks)
        shuffled = np.concatenate(
            [np.take(source, range(s, s + block_size), mode='wrap')
             for s in starts]
        )[:n]
        null_tes[b] = transfer_entropy(shuffled, target, k, l)

    null_mean = null_tes.mean()
    return {
        'te': te_observed,
        'ete': max(te_observed - null_mean, 0.0),
        'p_value': (np.sum(null_tes >= te_observed) + 1) / (n_shuffles + 1),
        'null_mean': null_mean,
        'null_std': null_tes.std(),
    }

配對矩陣

def compute_te_matrix(disc_returns, k=1, n_shuffles=200):
    cols = list(disc_returns.columns)
    m = len(cols)
    te_matrix = np.zeros((m, m))
    pval_matrix = np.ones((m, m))

    for i in range(m):
        for j in range(m):
            if i == j:
                continue
            r = effective_transfer_entropy(
                disc_returns[cols[i]].values,
                disc_returns[cols[j]].values,
                k=k, n_shuffles=n_shuffles,
            )
            te_matrix[i, j] = r['ete']
            pval_matrix[i, j] = r['p_value']

    return (pd.DataFrame(te_matrix, index=cols, columns=cols),
            pd.DataFrame(pval_matrix, index=cols, columns=cols))

快速路徑

pyinform 封裝了最佳化的 C 實作:

from pyinform.transferentropy import transfer_entropy as te_pyinform

te_btc_to_eth = te_pyinform(btc_disc, eth_disc, k=2)
te_eth_to_btc = te_pyinform(eth_disc, btc_disc, k=2)

零校準

零分布校準

這是分析中價值最高、卻最常被跳過的部分。在相信測量網路中的任何邊之前,對真實答案已知為零的資料執行完整管道——離散化、有效 TE、surrogate 檢驗、顯著性篩選:

  1. 打亂的真實報酬。 破壞跨序列的時序關係,同時保留各序列的邊際分布。
  2. 合成獨立序列。 模擬 MM 條由構造保證沒有跨序列依賴、但具有厚尾和波動率聚集的獨立過程。

接著報告檢驗在 α=0.05\alpha = 0.05 下標記的有序配對比例。如果該比例不接近 0.05,檢驗就沒有校準,真實網路中的每條邊都值得懷疑。

多重檢驗會使問題更嚴重。 8 個資產的宇宙有 8×7=568 \times 7 = 56 個有序配對檢驗,20 個資產則有 380 個。Bonferroni、Holm、Benjamini-Yekutieli FDR 等修正已在折損夏普與多重檢驗中完整推導,並附有校準研究:樸素檢驗的 FDR 為 1.000,而 BHY 為 0.007。

但不要停在原始 Bonferroni,因為這 56 個檢驗並不是 56 次獨立觀察。加密資產彼此高度相關——本部落格測得 PC1 佔 65% 的變異——這正是該文 Act 5 記錄的相關網格失效模式:把相關網格的原始格子數當成試驗數,會過度折損並錯誤拒絕真正的優勢。那裡的交付物是有效試驗數估計的區間,而非一個點:寬鬆端是平均相關性公式 Neff=N/(1+(N1)ρˉ)N_{\text{eff}} = N/(1 + (N-1)\bar\rho),中間則是特徵值估計器(participation ratio、PCA-95%、Kaiser)。報告 TE 網格的有效-NN 區間,並檢查倖存的邊在整個區間內是否穩定。

敏感度:兩個自由旋鈕

資訊景觀敏感度控制

以下兩個旋鈕通常按經驗法則設定,之後再也不檢查。它們應該被掃描,並在每個格子報告領先者/跟隨者排名。

歷史長度 kk

kk 控制條件中包含多少目標自身的過去。太小,會把目標自身的自相關歸因於來源;太大,聯合分布變得過於稀疏而無法估計——聯合狀態數是 Ak+l+1|\mathcal{A}|^{k+l+1},所以 3 個分箱、k=2k=2l=1l=1 時有 34=813^4 = 81 個狀態,而 k=5k=5 會在只有幾千個觀測值的情況下增加到 37=21873^7 = 2187

傳統起點是:小時資料使用 k{1,2}k \in \{1, 2\},日資料使用 k{1,,5}k \in \{1, \dots, 5\},也可用等價 VAR lag 的 AIC/BIC 交叉檢查。把它們當成要掃描的網格,不是答案。

離散化

  • 3 個分箱(下/平/上):穩健、資料有限時也能工作,只捕捉方向結構。
  • 5 個分箱:捕捉幅度,需要實質更多資料。
  • 分位數邊界:大致等量佔用,沒有空分箱——但要注意上面的洩漏警告。
  • 序數/符號編碼:置換熵風格,對單調變換穩健。

連續的基於核的 TE 完全避免離散化損失,但代價是頻寬選擇和大幅增加的計算量。

掃描

for n_bins in (3, 5):
    for k in (1, 2, 3, 5):
        disc = discretize_all(returns, n_bins=n_bins)
        te_df, p_df = compute_te_matrix(disc, k=k)
        rank = net_flow_ranking(te_df, p_df)
        report(n_bins, k, rank)

問題不是「排名是什麼」,而是「每個格子的排名是否相同」。如果某資產只有在 k=2k=2nbins=3n_{\text{bins}}=3 時才是淨來源,那種不穩定性就是結果,應當如此報告。

混雜:條件轉移熵

條件資訊流

XXYY 都由潛在因子 ZZ 驅動,配對 TE 會報告一條完全由共同驅動因素造成的虛假流。在單因子市場中,這不是邊角案例,而是預設情況。條件轉移熵將它條件化排除:

TXYZ=H(Yt+1Yt(k),Zt(l))H(Yt+1Yt(k),Xt(l),Zt(l))T_{X \to Y | Z} = H(Y_{t+1} \mid Y_t^{(k)}, Z_t^{(l)}) - H(Y_{t+1} \mid Y_t^{(k)}, X_t^{(l)}, Z_t^{(l)})

任何「SOL 向 AVAX 傳送資訊」的主張,都應在以 BTC 為條件後重新檢驗。如果流動消失,配對結果只是換了服裝的市場因子。

te_sol_avax_given_btc = te_pyinform(sol_disc, avax_disc, k=2,
                                    condition=btc_disc)

條件化不是免費的:每個條件變數都會將聯合狀態空間乘以 Al|\mathcal{A}|^{l},因此在相同 kk 下,條件 TE 需要的資料遠多於配對版本。

穩定性,以及這些結果是否可交易

跨市場狀態的穩定因果橋

資訊流不是靜態的——這個市場的其他東西也不是。這是使用 HMM 的狀態偵測的開場前提,也是這裡每個估計都必須使用視窗,而不能只擬合一次的原因。不過,滾動視窗版本的分析繼承的是已知結果,而不是發現新結果:加密依賴在危機中收緊,早已有數字證據。配對之間的訊號相關性將平均訊號相關性從盤整市場的 0.15 列到恐慌時的 0.90,NeffN_{\text{eff}} 從 4.2 降到 1.1;DCC-GARCH應用 3 將平均配對相關性轉成 risk-off 狀態訊號,使用尾隨分位數標記,並明確提醒「這是風險訊號,不是 alpha 訊號」。

Freeman 的 TE 流出強度集中度,是對另一個矩陣的另一個純量,但動作相同:將 d×dd \times d 的依賴物件壓成一個數字,觀察它上升。因此標準不是「集中度是否在回撤前上升」,而是在相同視窗、相同回撤下,集中度是否勝過平均配對相關性作為 risk-off 訊號,必須正面比較。

def network_centralization(G):
    """Freeman centralization of out-strength. High = one dominant source."""
    if G.number_of_nodes() < 2:
        return 0.0
    s = [sum(d['weight'] for _, _, d in G.out_edges(v, data=True)) for v in G.nodes()]
    total = sum(s)
    if total == 0:
        return 0.0
    n = len(s)
    return sum(max(s) - x for x in s) / ((n - 1) * total)

在任何下游應用值得撰寫之前,必須回答兩個問題:

  1. 領先者排名能否在樣本外持續? 在視窗 tt 上擬合網路,在視窗 t+1t+1 上檢查排名。報告跨視窗的排名相關性。每週重新洗牌的排名描述的是噪聲。
  2. TE 篩選器是否為 lead-lag 交易增加任何東西? 正確實驗是單一受控比較:使用統計套利與配對交易距離法中相同的滾動 z-score 進出場機制,執行兩次,唯一差異是是否存在 TE 顯著性篩選器,並計入費用。

本文尚未執行兩者。 沒有 lead-lag 回測,沒有資訊動量投資組合,也沒有狀態偵測比較。假想資訊動量部位的權重構造工具見比較投資組合最佳化演算法——但請注意,對原始位元淨強度使用 softmax 是尺度任意的,在它有意義之前需要正規化論證。本文不發布未測試的策略程式碼。

成本

計算流限制

TE 每個配對是 O(N)O(N),但常數由聯合狀態數 Ak+l+1|\mathcal{A}|^{k+l+1} 和 surrogate 數量決定。對 MM 個資產和 BB 次 bootstrap 重複,需要 M(M1)BM(M-1)B 次 TE 評估——50 個資產、200 個 surrogate 就是 490,000 次。每次評估成本完全取決於硬體、pyinform 版本和 NN;請在自己的機器上測量,不要相信引用數字。若太慢,有三個槓桿:

  • 平行化。 每個配對獨立——使用 joblibmultiprocessing
  • 預先篩選。 先計算原始 TE,只對超過閾值的配對執行 surrogate。(注意這會使顯著性檢驗以通過篩選為條件,必須納入校正。)
  • 縮小宇宙。 先分群,再計算群代表之間的 TE。

摘要

已解析的方向性資訊網路

轉移熵是有原則、無模型的有向資訊流量,填補了本部落格工具箱中的真實缺口:DCC-GARCH 說依賴何時收緊,TE 說它指向哪裡。對高斯過程,它透過 T=12ln(1+F)T = \tfrac{1}{2}\ln(1 + F) 精確退化為 Granger 因果,因此它是推廣而非競爭者。

然而,它目前還不是結果。本文管道已實作,也列舉了失效模式——surrogate 修正有限樣本偏差、全序列分箱造成前視洩漏、56 個檢驗構成的相關網格會破壞樸素多重檢驗修正、單因子市場中的共同驅動混雜,以及可能決定答案的自由參數。每一項都是不信任未校準 TE 網路的理由。在沒有零校準、敏感度掃描和樣本外穩定性檢查的情況下發布網路,就是把失效模式當成發現來發布。

參考文獻

  • Schreiber, T. (2000)。"Measuring Information Transfer." Physical Review Letters,85(2),461-464。
  • Barnett, L., Barrett, A.B., Seth, A.K. (2009)。"Granger Causality and Transfer Entropy Are Equivalent for Gaussian Variables." Physical Review Letters,103(23),238701。
  • Marschinski, R., Kantz, H. (2002)。"Analysing the information flow between financial time series." European Physical Journal B,30(2),275-281。
  • Dimpfl, T., Peter, F.J. (2013)。"Using Transfer Entropy to Measure Information Flows Between Financial Markets." Studies in Nonlinear Dynamics & Econometrics,17(1),85-102。
  • Keskin, Z., Aste, T. (2020)。"Information-theoretic measures for nonlinear causality detection: application to social media sentiment and cryptocurrency prices." Royal Society Open Science,7(9),200863。
  • Jang, S.M. 等人(2022)。"Using transfer entropy to measure information flows between cryptocurrencies." Physica A,586,126476。
  • Nicola, G. 等人(2020)。"Network Analysis of Multivariate Transfer Entropy of Cryptocurrencies in Times of Turbulence." Entropy,22(7),760。
免責宣告:本文提供的資訊僅用於教育和參考目的,不構成財務、投資或交易建議。加密貨幣交易涉及重大損失風險。

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 交易見解、市場分析和平台更新。

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