實驗室

M/08 · 穩健投資組合建構

最小變異數投資組合的宇宙飽和

最小變異數投資組合的樣本外波動率、MaxDD 與 CVaR-95 如何隨策略宇宙規模 N 縮放,橫跨 Ledoit–Wolf、Huber 穩健與樣本共變異數估計器。

數學原理

給定一個訓練視窗上策略報酬的 N × T 矩陣 R(每欄為一根 K 棒、每列為一個 策略),具完全投資的最小變異數投資組合為

在大 N 時,Σ̂ 的條件數主導投資組合在未見資料上的 行為:樣本共變異數的最小特徵值偏低(在 q = N/T 時的 Marchenko–Pastur 扭曲),因此 Σ̂⁻¹ 會放大 相應的方向,而所得的 w* 便追逐雜訊。 此處比較三種補救方法。

Ledoit–Wolf 收縮

F 是一個低參數目標(常數相關或純量單位矩陣); Ledoit–Wolf 2004 的閉式解從資料本身給出 α* 的一致估計。

Huber 式穩健 M 估計器

其中 ψ 為 Huber 的有界影響函數。該估計器迭代至 收斂;在大致呈高斯且置中的報酬上,它在數值上與 樣本共變異數一致,這解釋了為何下方的 LW 與 Huber 曲線 在視覺上難以區分。

飽和

在獨立性下,樣本外投資組合變異數以 O(N⁻¹) 縮放。在相關 的因子結構下,速率較慢,而獨立方向的有效數目 為增益設下上限。實證飽和點 N* 是增添策略 不再實質移動樣本外度量的宇宙規模。

實證設定

我們在 10 個 USDT 加密交易對上以 30 分鐘 解析度執行深度滾動前推分析。最大的宇宙是 AVAX,在 T_train = 1,240 根 K 棒上有 N = 49,068 個候選策略(q = N/T ≈ 39.6,遠高於 Marchenko–Pastur 範圍)。對每個錨點 N ∈ {25, 100, 500, 2,000} 我們抽樣 N 個策略, 在訓練視窗上擬合每個估計器、建構 w*,並在保留視窗上評估 vol_oos、 MaxDD_oos 與 CVaR-95_oos。

具體而言,在 AVAX(LW)上樣本外波動率從 N = 25 的 σ ≈ 149.5 下降至 N = 100 的 σ ≈ 116.7、N = 500 的 σ ≈ 84.5 與 N = 2,000 的 σ ≈ 70.4, 53% 的縮減,其中三分之二在 N = 500 即已捕捉。CVaR-95 遵循 相同的形狀,由 −18.8 降至 −7.1。在 BTC(LW)上曲線 更為陡峭:σ 由 87.0(N = 25)走至 25.6(N = 2,000)。

Loading saturation curves…

方法比較

在小 N 時三個估計器明顯不同:樣本共變異數有較低的 樣本外波動率(例如 AVAX N = 500:σ_sample ≈ 73.0 vs σ_LW ≈ 84.5),因為 當滿秩仍可達成時,無偏的樣本估計勝過 收縮後的估計。隨著 N 增長,q = N/T 跨越條件數門檻,而 樣本反矩陣變得不穩定;對於 N ≳ 5,000,LW 與 Huber 在每個資產上都超越。 MaxDD 較為特異:即使在大 N 時樣本有時也在 MaxDD 上勝出 (AVAX N = 2,000:MaxDD_sample ≈ −222 vs MaxDD_LW ≈ −311), 我們將其歸因於樣本投資組合在測試視窗期間集中於少數 條件良好的特徵方向。

Fig. 1:三個估計器的樣本外投資組合波動率 vs N。N ≈ 500–1,000 附近的拐點在各資產間一致;將宇宙加倍超過 N = 5,000 在 vol_oos 上僅產生次個百分點的改善。
Fig. 2:樣本外 CVaR-95 飽和。相同的 N* ≈ 500 平台出現:一旦投資組合具有足夠廣度可分散,尾部風險縮減便追蹤波動率縮減。
Fig. 3:方法比較。LW 與 Huber 在各 N 上幾乎完全重疊;樣本在小 N 時分歧(較低波動率),並在一部分資產上於 MaxDD 上維持略佳。
Fig. 4:30 資產語料庫 10 個深度滾動前推分區的飽和曲線疊加。N* 拐點是資產特定的(BTC 較早飽和,AVAX/ETH 較晚),但其質性形狀在公司檢視過的每個其他分區上都是普遍的。

為何這很重要

實務上的要點是依邊際遞減來編列你的策略挖掘 投入。超過一個資產的 N* 後,額外的策略會增加 營運成本卻買不到樣本外風險縮減;在其之下,投資組合 則波動率無效率。匯出的曲線讓交易檯能挑選與其風險目標 相一致的最小宇宙,而 LW/Huber 的收斂意味著 廉價的收縮估計器便已足夠,沉重的穩健流程 在此資料上鮮少賺得其運算預算。

可重現性

DaruFinance / strategy-robust-portfolio

Python · 開源參考實作

最小調用

import json
from strategy_robust_portfolio import build_min_variance, sweep_universe

# returns_train: T x N strategy returns matrix (in-sample)
# returns_test:  T' x N strategy returns matrix (out-of-sample)
weights = build_min_variance(
    returns_train,
    method="lw",        # one of {"lw", "robust", "sample"}
    rho=1e-3,           # correlation regulariser added to the diagonal
)

# Saturation sweep over universe size N
curve = sweep_universe(
    returns_train, returns_test,
    n_grid=[25, 100, 500, 2000, 10000, 49068],
    methods=["lw", "robust", "sample"],
    seed=0,
)
print(json.dumps(curve.summary(), indent=2))

參考文獻

  1. [1]Ledoit, O. & Wolf, M. (2004). A well-conditioned estimator for large-dimensional covariance matrices. Journal of Multivariate Analysis 88(2), 365–411.
  2. [2]Maronna, R. A. (1976). Robust M-estimators of multivariate location and scatter. The Annals of Statistics 4(1), 51–67.
  3. [3]Rockafellar, R. T. & Uryasev, S. (2000). Optimization of conditional value-at-risk. Journal of Risk 2(3), 21–41.
  4. [4]Bun, J., Bouchaud, J.-P. & Potters, M. (2017). Cleaning large correlation matrices: tools from random matrix theory. Physics Reports 666, 1–109.