Correlation Matrix
Correlation Matrix computes the pairwise Pearson correlation of daily returns across up to ten tickers over a 30/90/180/365-day window, color-coded for diversification and pair-trade work.
Correlation Matrix takes two to ten tickers and prints their pairwise Pearson correlation of daily returns over your chosen lookback. Greens cluster names that move together; reds cluster names that move opposite; faint cells are the diversifiers. The first place to check when a portfolio looks "balanced" but every line moves on the same day.

What it is
A server-side correlation engine. It pulls daily closing prices for each symbol over your chosen window, converts to a returns series (p_i − p_{i−1}) / p_{i−1}, runs Pearson across every pair, and returns the matrix. Results are cached per symbol set and window, so reordering tickers in the UI doesn't trigger a refetch.
Values run from −1.00 to +1.00. The cell background bins the strength: dark green ≥ 0.80, medium green ≥ 0.50, faint green ≥ 0.20, transparent in the [−0.20, +0.20] low-correlation band, faint red below, deepening to dark red at ≤ −0.80. The diagonal is always 1.00 and shaded as a no-op.
When to use it
Before sizing up a basket: if every name in your watchlist is +0.85 to SPY, you don't have ten ideas, you have one. After a regime shift to find the names that broke from their cluster — the lagging energy stock that decorrelated from XLE is often the story. For pair trades, hunt the deep-red corners. For sector rotation, drop the eleven SPDR ETFs in and watch which sectors drift apart week-over-week. For options hedging, pick a hedge that's ≤ −0.50 to the position you're protecting.
Open it
- Path:
/correlation - Shortcut: none — accessible from the
§TOOLSgroup in the sidebar - Tier-gate: Free unlocks the matrix with up to five tickers on the 30D and 90D windows. Pro and Terminal expand to ten tickers and unlock the 180D and 1Y windows
How to use it
- Open
/correlation. If a watchlist is active on/dashboard, the first few of its symbols pre-populate automatically. - Type a ticker into the
ADD_SYMBOL…box and hit Enter, or pick from the autocomplete dropdown. Add up to your tier cap. - Click
+ WATCHLISTto bulk-load the active watchlist (capped at the tier maximum). - Remove a ticker by clicking the
×on its chip. - Pick a window:
30D,90D,180D,1Y. Locked windows show a padlock and don't respond to clicks on Free. - The matrix renders as soon as you have two valid symbols. Adding or removing a symbol re-runs the computation; changing the window does the same.
- Read corners first. Top-left to bottom-right diagonal is always 1.00. Off-diagonal greens = move together; reds = move opposite.
Fields
| Column / cell | What it is |
|---|---|
| Row header | Ticker (mono, green) |
| Column header | Same tickers across the top |
| Cell value | Pearson correlation of daily returns over the window, rounded to two decimals |
| Cell background | Color bin — dark green ≥ 0.80, mid 0.50–0.79, faint 0.20–0.49, transparent −0.20 to +0.20, faint red −0.21 to −0.49, mid −0.50 to −0.79, dark red ≤ −0.80 |
| Cell text color | Green ≥ 0.50, red ≤ −0.50, neutral in between |
| Diagonal | Always 1.00, dimmed and shaded — a name is perfectly correlated with itself |
The window options are calendar days, not trading days; trading-day filtering happens behind the scenes.
Limits
- Free tier: max 5 tickers, windows limited to
30Dand90D(correlation.fullTickersandcorrelation.allPeriodsfeature flags) - Pro and Terminal: max 10 tickers, all four windows
- Hard cap: 30 symbols total — requests beyond that are rejected
- Day-count range: clamped to between 30 and 2000 days
- Uses daily closes. Symbols without a covered price feed (some OTC, foreign) return as
0.00across their row and column - Results are cached; refresh by adding/removing a ticker or changing the window
- Returns calculation uses simple period-over-period returns, not log returns — fine for typical equity pairs over months; diverges at extreme single-day moves
- Pearson assumes a roughly linear relationship; nonlinear pairs (e.g., a stock vs. its own put-write yield) will look weaker than they trade
Troubleshooting
Cells render but every value is 0.00. The price history couldn't be loaded for those rows, usually because the symbol isn't in the covered universe — common for delisted, sub-$1 OTC, and foreign-listed names. Swap to a tradable proxy (the ADR, the sector ETF) and the row populates.
§ERR / CORRELATION · feed unavailable. The price feed failed for the whole batch — usually a brief, temporary outage. Refresh in 30 seconds; if it persists, post in the Tapeboard status channel.
30D and 90D work but the other windows show a padlock. You're on Free. The correlation.allPeriods flag unlocks the longer lookbacks on Pro and Terminal.
The matrix doesn't update when I remove a ticker. Confirm the × click registered — the chip should disappear immediately, and the matrix should recompute. If the matrix is stale, change the window once to force a recompute, then change it back.
Correlations look unstable week to week. Pearson over short windows is noisy by design — a single 8% gap can pull a 0.50 to 0.20. Use the 90D or 1Y window for diversification work and the 30D for regime-shift detection. The two answer different questions.
Two ETFs that should be near-identical (e.g., VOO and SPY) print at 0.97 instead of 1.00. Expected — slight tracking error, different rebalance schedules, and tiny intraday price gaps from non-synchronous closes make perfect 1.00 unusual outside of literal duplicates. Anything ≥ 0.95 is "effectively the same exposure" for portfolio purposes.