Interactive exploration of how portfolio weights, individual volatilities, and correlations determine portfolio risk and diversification benefits
When managing a portfolio of multiple assets, risk depends not only on each asset’s volatility but critically on the correlations between them. The portfolio variance for \(n\) assets is (Christoffersen 2012, chap. 7)
where \(w_t\) is the vector of portfolio weights, \(\Sigma_{t+1}\) is the covariance matrix, \(\sigma_{i,t+1}\) are individual volatilities, and \(\rho_{ij,t+1}\) are pairwise correlations.
Under the assumption of multivariate normality, portfolio VaR and ES at tail probability \(p\) follow directly:
where \(\Phi_p^{-1}\) is the \(p\)-quantile of the standard normal distribution (i.e., the inverse CDF) and \(\phi(\cdot)\) is the standard normal PDF.
Note
VaR and subadditivity. Under multivariate normality, VaR is subadditive: the portfolio VaR never exceeds the weighted sum of individual VaRs. This means diversification always reduces VaR in this setting. However, VaR is not a coherent risk measure in general (Artzner et al. 1999), and subadditivity can fail for non-normal distributions. ES, being a coherent risk measure, is always subadditive regardless of the distribution. This is one reason we display both measures side by side below.
The undiversified VaR is the weighted sum of individual asset VaRs, \(\text{VaR}_{\text{undiv}} = w_1 \cdot \text{VaR}_1 + w_2 \cdot \text{VaR}_2\). This corresponds to the portfolio risk when assets are perfectly correlated (\(\rho = 1\)), i.e., when there is no diversification at all. The diversification benefit is the difference between this undiversified value and the actual portfolio risk:
It is always non-negative under normality (since \(\sigma_{PF} \leq w_1 \sigma_1 + w_2 \sigma_2\) for \(\rho \leq 1\)) and equals zero only when \(\rho = 1\). The same logic applies to ES.
// ============================================================// MATH UTILITIES// ============================================================normalCDF = x => {const a1 =0.254829592, a2 =-0.284496736, a3 =1.421413741const a4 =-1.453152027, a5 =1.061405429, p =0.3275911const sign = x <0?-1:1const z =Math.abs(x) /Math.sqrt(2)const t =1.0/ (1.0+ p * z)const y =1- (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t *Math.exp(-z * z)return0.5* (1+ sign * y)}
normalPDF = x =>Math.exp(-x * x /2) /Math.sqrt(2*Math.PI)
Portfolio risk as a function of weights and correlation
Explore how portfolio risk depends on the allocation between two assets, their individual volatilities, and the correlation between them. The gap between the diversified portfolio risk and the undiversified (weighted-sum) risk is the diversification benefit.
Tip
How to experiment
Start with the default settings and observe the gap between the portfolio \(\sigma\) curve and the straight undiversified line. Then drag the correlation slider toward +1 and watch the gap vanish. Set it to \(-1\) and notice the portfolio volatility can reach zero at a specific weight. Try increasing one asset’s volatility while keeping the other low to see how the optimal diversification weight shifts.
{const h = prWLegendconst current = prSweepW.filter(d => d.isCurrent)const rhom1 = prSweepW.filter(d => d.rho===-1&&!d.isCurrent)const rho0 = prSweepW.filter(d => d.rho===0&&!d.isCurrent)const rho1 = prSweepW.filter(d => d.rho===1&&!d.isCurrent)const marks = [ Plot.ruleY([0], { stroke:"#eee" }) ]if (!h.has("rhom1") && prRho !==-1) marks.push(Plot.line(rhom1, { x:"w1",y:"sigma",stroke:"#2e7d32",strokeWidth:1,strokeDasharray:"4 3" }))if (!h.has("rho0") && prRho !==0) marks.push(Plot.line(rho0, { x:"w1",y:"sigma",stroke:"#999",strokeWidth:1,strokeDasharray:"4 3" }))if (!h.has("undiv") && prRho !==1) marks.push(Plot.line(rho1, { x:"w1",y:"sigma",stroke:"#d62728",strokeWidth:1.5,strokeDasharray:"4 3" }))if (!h.has("current")) marks.push(Plot.line(current, { x:"w1",y:"sigma",stroke:"#2f71d5",strokeWidth:2.5 }))// Current point marks.push(Plot.dot([{ x: prW1,y: prCalc.pfSig*100 }], { x:"x",y:"y",r:6,fill:"#2f71d5",stroke:"white",strokeWidth:2 }))// Vertical line at current w1 marks.push(Plot.ruleX([prW1], { stroke:"#2f71d5",strokeWidth:1,strokeDasharray:"2 3",strokeOpacity:0.5 }))return Plot.plot({height:400,marginLeft:60,marginRight:20,x: { label:"w₁ (weight of asset 1)",domain: [0,1],grid:false },y: { label:"Portfolio σ (%)",grid:true }, marks })}
html`<p style="color:#666;font-size:0.85rem;">Portfolio standard deviation as a function of the weight in asset 1. The <span style="color:#d62728;font-weight:700;">dashed red line</span> is the undiversified case (ρ = 1), where portfolio σ is the weighted average of individual σ values. The <span style="color:#2f71d5;font-weight:700;">blue curve</span> shows the actual portfolio σ at the current correlation. The gap between them is the diversification benefit.</p>`
html`<p style="color:#666;font-size:0.85rem;">Portfolio standard deviation at the current weights (w₁ = ${fmt(prW1,2)}) as a function of correlation. Risk increases monotonically with correlation. At ρ = +1 there is no diversification benefit; at ρ = −1 perfect hedging is possible.</p>`
{const r = prCalcconst types = ["Asset 1","Asset 2","Undiversified","Portfolio"]const colors = { "Asset 1":"#aaa","Asset 2":"#ccc","Undiversified":"#e67e22","Portfolio":"#2f71d5" }const barData = [ { measure:"VaR",type:"Asset 1",value: r.w1* r.var1*100 }, { measure:"VaR",type:"Asset 2",value: r.w2* r.var2*100 }, { measure:"VaR",type:"Undiversified",value: r.undivVaR*100 }, { measure:"VaR",type:"Portfolio",value: r.pfVaR*100 }, { measure:"ES",type:"Asset 1",value: r.w1* r.es1*100 }, { measure:"ES",type:"Asset 2",value: r.w2* r.es2*100 }, { measure:"ES",type:"Undiversified",value: r.undivES*100 }, { measure:"ES",type:"Portfolio",value: r.pfES*100 } ]// Compute bar positions manually: grouped bars within each measureconst measures = ["VaR","ES"]const barWidth =0.18const bars = []for (const d of barData) {const mx = measures.indexOf(d.measure)const tx = types.indexOf(d.type)const x = mx + (tx -1.5) * barWidth bars.push({ x,x1: x - barWidth/2,x2: x + barWidth/2,y: d.value,type: d.type,measure: d.measure }) }return Plot.plot({height:380,marginLeft:60,marginBottom:40,x: { label:null,domain: [-0.5,1.5],ticks: [0,1],tickFormat: d => measures[d] },y: { label:"% of portfolio value",grid:true },marks: [ Plot.ruleY([0]), Plot.rectY(bars, {x1:"x1",x2:"x2",y:"y",fill: d => colors[d.type],fillOpacity:0.85 }), Plot.text(bars, {x:"x",y:"y",text: d => d.type,dy:-8,fontSize:9,fill: d => colors[d.type],fontWeight: d => d.type==="Portfolio"?700:500 }) ] })}
html`<p style="color:#666;font-size:0.85rem;">Weighted individual contributions, undiversified (sum of weighted individual measures), and actual portfolio VaR and ES. The diversification benefit is the difference between the undiversified and portfolio values. Under normality, both VaR and ES show positive diversification benefits whenever ρ < 1.</p>`
{const r = prCalcreturnhtml`<table class="table" style="width:100%;"><thead><tr> <th>Measure</th> <th>Asset 1 (w₁ = ${fmt(r.w1,2)})</th> <th>Asset 2 (w₂ = ${fmt(r.w2,2)})</th> <th>Undiversified</th> <th style="color:#2f71d5;">Portfolio</th> <th>Diversification benefit</th></tr></thead><tbody><tr><td style="font-weight:500;">σ (%)</td> <td>${fmt(r.s1*100,3)}%</td> <td>${fmt(r.s2*100,3)}%</td> <td>${fmt(r.undivSig*100,3)}%</td> <td style="font-weight:700;">${fmt(r.pfSig*100,3)}%</td> <td>${fmt(r.divBenSig*100,3)}%</td></tr><tr><td style="font-weight:500;">VaR (${fmt(r.p*100,1)}%)</td> <td>${fmt(r.var1*100,3)}%</td> <td>${fmt(r.var2*100,3)}%</td> <td>${fmt(r.undivVaR*100,3)}%</td> <td style="font-weight:700;">${fmt(r.pfVaR*100,3)}%</td> <td>${fmt(r.divBenVaR*100,3)}% (${fmt(r.divBenVaRPct,1)}%)</td></tr><tr><td style="font-weight:500;">ES (${fmt(r.p*100,1)}%)</td> <td>${fmt(r.es1*100,3)}%</td> <td>${fmt(r.es2*100,3)}%</td> <td>${fmt(r.undivES*100,3)}%</td> <td style="font-weight:700;">${fmt(r.pfES*100,3)}%</td> <td>${fmt(r.divBenES*100,3)}% (${fmt(r.divBenESPct,1)}%)</td></tr><tr><td style="font-weight:500;">Covariance</td> <td colspan="5">${fmt(r.cov12*10000,6)} (σ₁₂ = σ₁ × σ₂ × ρ₁₂ = ${fmt(r.s1*100,1)}% × ${fmt(r.s2*100,1)}% × ${fmt(r.rho,2)})</td></tr><tr><td style="font-weight:500;">Portfolio variance</td> <td colspan="5">${fmt(r.pfVar*10000,6)}</td></tr></tbody></table><p style="color:#666;font-size:0.85rem;">All risk measures assume multivariate normality and a ${fmt(r.p*100,1)}% tail probability. Under this assumption, both VaR and ES are proportional to portfolio σ and therefore always exhibit positive diversification benefits when ρ < 1.</p>`}
References
Artzner, Philippe, Freddy Delbaen, Jean-Marc Eber, and David Heath. 1999. “Coherent Measures of Risk.”Mathematical Finance 9 (3): 203–28.
Christoffersen, Peter F. 2012. Elements of Financial Risk Management. 2nd ed. Academic Press.