What (One-liner)
N×N correlation matrix over N symbols' daily returns, with three estimators: Pearson / Ledoit-Wolf shrinkage / OAS shrinkage. The Batch Signals multi-select helper and a portfolio-diversification diagnostic.
How to use
In Batch Signals / Canvas, drag portfolio_correlation, fill the symbols list (≥2) plus optional period (default '6mo') and optional method (default 'pearson'). Output is the N×N matrix plus a shrinkage coefficient (LW/OAS).
Typical usage:
symbols=[SPY, QQQ, IWM, EFA, TLT, GLD, DBC], period=1y, method=ledoit_wolf
→ 7×7 PSD correlation matrix + shrinkage_coef ≈ 0.08Core formulas
# Preprocessing:
returns = fetch_daily_pct_change(symbols, period) # 60s cached
X = returns.values # (T, N)
# Method branch:
if method == "pearson":
M = np.corrcoef(X.T)
shrinkage = null
elif method == "ledoit_wolf":
cov, coef = sklearn.covariance.ledoit_wolf(X)
M = diag_normalize(cov, clip=[-1, 1])
shrinkage = coef
elif method == "oas":
cov, coef = sklearn.covariance.oas(X)
M = diag_normalize(cov, clip=[-1, 1])
shrinkage = coef
# matrix round(4) on outputAssumptions & applicability
Assumptions: daily frequency + yfinance auto_adjust + at least 2 symbols + 60s cache + 100-symbol hard cap.
Fits: US equity/ETF/FX diversification diagnostics, covariance ahead of risk parity, quarterly-review correlation snapshots.
Does not fit: tick data, >100 symbols, <2 symbols, non-linear dependence, time-varying correlation, copulas.
Input / Output contract
{symbols: list, period: str, method: 'pearson'|'ledoit_wolf'|'oas'} → {symbols, period, n_observations, matrix, dropped_symbols, truncated, method, shrinkage, windows}.
Matrix round(4); shrinkage is null for pearson.
Known limitations
- Pearson goes rank-deficient at large N/T (use LW/OAS when N/T ≥ 0.5)
- Matrix round(4) hides fine-grained shrinkage differences
- 100-symbol hard cap (flagged via truncated)
- Cache TTL 60s (freshness vs coalescing)
- Symbol alias map hardcoded
- Zero-variance columns fall back to 1.0 (already filtered by _fetch_returns; defence-in-depth)
- No automatic method recommendation based on the N/T ratio
References
Pearson (1895) original + Ledoit-Wolf (2004) shrinkage + Chen et al. (2010) OAS + Fama-French (1993) factor-model background. Full citations in the frontmatter.
Golden Test
tests/golden/fixtures/tier2/portfolio_correlation/ — a 3-method parametrized regression over synthetic 3-symbol returns, 1e-10 tolerance post-round(4), 9 tests:
matches_reference[pearson]/[ledoit_wolf]/[oas]— 3 methods byte-equaldeterminism— 5 reruns identicaldiagonal_is_one— diagonal = 1.0 contract for every methodmatrix_symmetric— symmetry contractrejects_single_symbol— < 2 → errorrejects_unknown_method— invalid method → errorshrinkage_comparison— OAS > LW on small T/N, ordering contract
The reference replays a synthetic 3-symbol series (seed=42) with _fetch_returns monkey-patched, bypassing yfinance.
Changelog
- 1.0.0 (2026-04-20) — First Active (Tier 2 batch 5)

