How to build a correlation matrix heatmap for a portfolio
Quick answer
To build a correlation matrix heatmap, convert prices to returns first (correlating price levels gives spurious results), compute the Pearson correlation of each pair, and plot the N x N grid with a diverging colour scale fixed to the full -1 to +1 range and centred on zero. Order the assets by clustering so blocks appear, and label the lookback window - correlations shift with market regime, as stocks and bonds did when their correlation turned positive through 2022.
A correlation matrix heatmap turns the pairwise relationships between a portfolio's holdings into a single colour grid: one row and one column per asset, each cell shaded by how closely those two assets move together. Done right, it shows where your diversification actually is, and where you only think you have it. Done wrong, it quietly lies, and the most common way to get it wrong is in the very first step.
Correlate returns, not prices
The mistake that ruins most homemade correlation matrices is feeding in price levels. Two rising assets show a high correlation whether or not their day-to-day moves have anything in common, simply because both series trend; the correlation of two independent random walks is spurious and usually large. Always convert to returns first, the percentage change from one period to the next, and correlate those. In pandas that is two lines: returns = prices.pct_change().dropna(), then corr = returns.corr().
Each cell is then a Pearson correlation, the covariance of two return series divided by the product of their standard deviations, bounded between -1 and +1. Rounding can nudge a value a hair past those limits, so clamp to the valid range before plotting.
Choose the colour scale deliberately
Correlation runs from -1 to +1 with a meaningful midpoint at zero, so the heatmap needs a diverging colour scale centred on zero, not the default sequential ramp most charting libraries reach for. Use one hue for negative and another for positive, neutral at zero, and fix the scale to the full -1 to +1 range rather than letting it auto-fit to the data. Auto-fitting makes a matrix of values between 0.6 and 0.9 look like it spans the whole range, exaggerating differences that are not there. The diagonal is always 1 by construction, so many people grey it out to push the eye toward the off-diagonal cells that carry the information.
Order the assets so blocks appear
Left in input order, a correlation matrix is a wall of colour with no structure. Reorder the rows and columns so similar assets sit together, by asset class, or by hierarchical clustering on the correlation distances, and clusters resolve into visible blocks: equities correlating tightly with one another, bonds forming their own block, a commodity or two standing apart. The reordering changes nothing in the numbers; it makes the structure legible.
One number, one moment in time
A correlation matrix is a single snapshot over whatever window you chose, and correlations move. The textbook case is stocks and bonds: for two decades they were reliably negatively correlated, which is what made the classic 60/40 portfolio work, and then through 2022 they fell together as inflation and rate fears hit both at once, and the correlation turned positive. A matrix computed over a long window would have averaged that shift away. State the window on the chart ("60-day correlations, as of 24 June 2026"), and for anything you rely on, pair the static matrix with a rolling-correlation line so a regime change is visible rather than buried.
The window, and what correlation misses
Two more choices matter. The lookback window, typically 30, 60 or 90 days, trades responsiveness against noise; document it on the chart so a reader knows what they are looking at. And Pearson correlation only captures linear co-movement, so two assets with a strong non-linear relationship can show a coefficient near zero; if you suspect that, a rank-based measure such as Spearman is the honest alternative.
[QUADESTO-EMBED: portfolio correlation matrix heatmap, returns-based, diverging scale fixed to -1..+1 and centred on zero, hierarchically ordered, hover shows the pair, coefficient and window]
The Quadesto angle
Drop in a table of price or return series and Quadesto builds the correlation heatmap on returns, with a zero-centred diverging scale and clustered ordering by default, alongside the rest of a performance pack like the equity curve and drawdown panel. The free tier embeds it with a Made with Quadesto credit; Pro (£149 a month) removes the attribution and adds branded themes for client and investor reporting.