M/08 · Construção robusta de portfólio
Saturação de universo em portfólios de mínima variância
Como volatilidade OOS, MaxDD e CVaR-95 de um portfólio de mínima variância escalam com o tamanho do universo de estratégias N, nos estimadores Ledoit–Wolf, Huber-robusto e covariância amostral.
A matemática
Dada uma matriz N × T de retornos de estratégias R (cada coluna uma barra, cada linha uma estratégia) em uma janela de treinamento, o portfólio de mínima variância com investimento total é
Em N grande, o condicionamento de Σ̂ domina o comportamento do portfólio em dados não vistos: os menores autovalores da covariância amostral são tendenciosos para baixo (distorção de Marchenko–Pastur em q = N/T), então Σ̂⁻¹ infla as direções correspondentes e o w* resultante persegue ruído. Três remédios são comparados aqui.
Shrinkage Ledoit–Wolf
F é um alvo de baixos parâmetros (correlação constante ou identidade escalar); a forma fechada de Ledoit–Wolf 2004 fornece um estimador consistente de α* a partir dos próprios dados.
M-estimador robusto estilo Huber
com ψ a função de influência limitada de Huber. O estimador é iterado até a convergência; em retornos aproximadamente Gaussianos centrados, coincide numericamente com a covariância amostral, o que explica por que as curvas LW e Huber abaixo são visualmente indistinguíveis.
Saturação
Sob independência, a variância OOS do portfólio escala como O(N⁻¹). Com estrutura de fatores correlacionada, a taxa é mais lenta e um número efetivo de direções independentes limita o ganho. O ponto de saturação empírico N* é o tamanho do universo em que adicionar estratégias deixa de mover materialmente a métrica OOS.
Configuração empírica
Rodamos uma análise walk-forward profunda em 10 pares cripto USDT em resolução de 30 minutos. O maior universo é AVAX com N = 49.068 estratégias candidatas em T_train = 1.240 barras (q = N/T ≈ 39,6, muito acima do regime de Marchenko–Pastur). Para cada âncora N ∈ {25, 100, 500, 2.000} amostramos N estratégias, ajustamos cada estimador na janela de treinamento, construímos w*, e avaliamos vol_oos, MaxDD_oos e CVaR-95_oos na janela de holdout.
Concretamente, em AVAX (LW) a volatilidade OOS cai de σ ≈ 149,5 em N = 25 para σ ≈ 116,7 em N = 100, σ ≈ 84,5 em N = 500 e σ ≈ 70,4 em N = 2.000, uma redução de 53% com dois terços dela capturada por N = 500. CVaR-95 segue a mesma forma, caindo de −18,8 para −7,1. Em BTC (LW) a curva é ainda mais íngreme: σ vai de 87,0 (N = 25) para 25,6 (N = 2.000).
Comparação de métodos
Em N pequeno, os três estimadores diferem visivelmente: a covariância amostral tem menor volatilidade OOS (e.g. AVAX N = 500: σ_sample ≈ 73,0 vs σ_LW ≈ 84,5), porque com posto completo ainda atingível a estimativa amostral não-tendenciosa bate a encolhida. Conforme N cresce, q = N/T cruza o limiar de condicionamento e a inversa amostral se torna instável; LW e Huber ultrapassam em todo ativo para N ≳ 5.000. MaxDD é mais idiossincrático: amostral às vezes vence em MaxDD mesmo em N grande (AVAX N = 2.000: MaxDD_sample ≈ −222 vs MaxDD_LW ≈ −311), o que atribuímos ao portfólio amostral concentrando-se em algumas autodireções bem-condicionadas durante a janela de teste.
Por que isso importa
O takeaway prático é orçar seu esforço de mineração de estratégias contra retornos decrescentes. Passado o N* de um ativo, estratégias adicionais adicionam custo operacional sem comprar redução de risco OOS; abaixo dele, o portfólio é vol-ineficiente. As curvas exportadas permitem que uma mesa escolha o menor universo consistente com seu alvo de risco, e a convergência LW/Huber significa que o estimador de shrinkage barato é suficiente, o pipeline robusto pesado raramente justifica seu orçamento computacional nesses dados.
Reprodutibilidade
DaruFinance / strategy-robust-portfolio
Python · implementação de referência open-source
Invocação mínima
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))
Referências
- [1]Ledoit, O. & Wolf, M. (2004). A well-conditioned estimator for large-dimensional covariance matrices. Journal of Multivariate Analysis 88(2), 365–411.
- [2]Maronna, R. A. (1976). Robust M-estimators of multivariate location and scatter. The Annals of Statistics 4(1), 51–67.
- [3]Rockafellar, R. T. & Uryasev, S. (2000). Optimization of conditional value-at-risk. Journal of Risk 2(3), 21–41.
- [4]Bun, J., Bouchaud, J.-P. & Potters, M. (2017). Cleaning large correlation matrices: tools from random matrix theory. Physics Reports 666, 1–109.

