Compute the implied correlation of a Portfolio

hey guys I need a bit of math help. I am trying to compute the implied correlation of an ETF as i am trying to find expensive/cheap ivol. I was hoping someone could cross check my code or dummy example before I go and bet.

I am using the CBOE implied correlation formula to back out the IC from option prices.
Screen Shot 2021-03-08 at 11.54.00 AM.png


Weights of Components:
w1 = .3
w2 = .4
w3 = .3

Ivols of Components:
v1 = .25
v2 = .35
v3 = .18

Ivol of Index:
vIndex = .21


Once plugged into my code (above formula) the result is an implied correlation of 36%

Code:
v = c(.25, .35, .18)
w = c(.3, .4, .3)
varIndex = .21^2

#create vector and matrix for top and bottom summations
top.sum = vector()
bottom.sum = matrix(nrow = length(v), ncol = length(v))

#loop over inputs
for(i in 1:length(v)){
  top.sum[i] = w[i]^2 * v[i]^2
  for(j in 1:length(v)){
    bottom.sum[i,j] = w[i]*w[j]*v[i]*v[j]
  }
}

#print top and bottom summations
top.sum
bottom.sum

#get the upper right corner of our matrix
mat = bottom.sum[upper.tri(bottom.sum)]

#print implied correlation
(varIndex - sum(top.sum))/(2 * sum(mat))

Thank you for your time
 
Last edited:
hey guys I need a bit of math help. I am trying to compute the implied correlation of an ETF as i am trying to find expensive/cheap ivol. I was hoping someone could cross check my code or dummy example before I go and bet.

I am using the CBOE implied correlation formula to back out the IC from option prices.
View attachment 254026

Weights of Components:
w1 = .3
w2 = .4
w3 = .3

Ivols of Components:
v1 = .25
v2 = .35
v3 = .18

Ivol of Index:
vIndex = .21


Once plugged into my code (above formula) the result is an implied correlation of 36%

Code:
v = c(.25, .35, .18)
w = c(.3, .4, .3)
varIndex = .21^2

#create vector and matrix for top and bottom summations
top.sum = vector()
bottom.sum = matrix(nrow = length(v), ncol = length(v))

#loop over inputs
for(i in 1:length(v)){
  top.sum[i] = w[i]^2 * v[i]^2
  for(j in 1:length(v)){
    bottom.sum[i,j] = w[i]*w[j]*v[i]*v[j]
  }
}

#print top and bottom summations
top.sum
bottom.sum

#get the upper right corner of our matrix
mat = bottom.sum[upper.tri(bottom.sum)]

#print implied correlation
(varIndex - sum(top.sum))/(2 * sum(mat))

Thank you for your time

Is this "stock market chess"?

If so, suggest you focus on "checkers".

KISS, baby... as always.
:)
 
Once plugged into my code (above formula) the result is an implied correlation of 36%


This result is way off. You can see this intuitively as weighted component vol is .229.
For large baskets, as n -> inf, implied corr will converge on basket-vol / weighted-component-vol. This overstates corr for small baskets. Rule of thumb iv**3 / crossprod(w**3,v**3) yields a guess of .77/

Explicitly calculating it corr comes in around .75:

rho = (iv**2 - crossprod(w**2,v**2) / sum(outer(v,v) * outer(w,w) - eye(3) * diag(outer(v,v) * outer(w,w)))
 
This result is way off. You can see this intuitively as weighted component vol is .229.
0.3 * 0.25 + 0.4 * 0.35 + 0.3 * 0.18 ~ 0.27 no?

Code:
import numpy as np

w = np.array([.3, .4, .3])
v = np.array([.25,.35,.18])
V = .21

x = np.outer(v,v) * np.outer(w,w)
e = np.eye(len(v))
o = np.ones(len(v))
r = (np.power(V,2) - np.sum(e * x, axis=(0,1))) / np.sum(x * (o - e), axis=(0,1))
print(r)
V_ =
this gives me 0.36 and I can recover the index vol using a very basic version:
Code:
vw = v * w
r = 0.36
np.sqrt(sum([
    (vw[i]**2 if i==j else vw[i]*vw[j]*r) 
        for i in range(3) 
            for j in range(3)
]))
which gives me 0.2099
 
Back
Top