3 votos

Cálculo del vol implícito mediante vanna volga

Estoy tratando de escribir un R script que tome las calls y puts de 25d junto con ATM y cree un vol. smile.

He intentado utilizar el método propuesto por Castagna y Mercurio para calcular la volatilidad de la vanna-volga. La expresión propuesta, para un Call europeo es:

C(K) = CBS(K)+ w(K1) [CMkt(K1)-CBS(K1)]+w(K3) [CMkt(K3)-CBS(K3)]

donde w1 y w3 se calculan según el código siguiente.

BSoption <- function(type, S, X, t, r, rf, v)
{

  d1 <- (log(S/X) + (r-rf + 0.5 * v^2) * t)/(v * sqrt(t))
  d2 <- d1 - v*sqrt(t)
  if (type == "c"){
    pnorm(d1)*S*exp(-rf*t) - pnorm(d2)*X*exp(-r*t)
  } else {
    pnorm(-d2)*X*exp(-r*t) - pnorm(-d1)*S*exp(-rf*t)
  }
}

vega <- function(S, X, t, r, rf, v)
{
  d1 <- (log(S/X) + (r -rf + 0.5 * v^2) * t)/(v * sqrt(t))
  Np <- (exp(-d1^2/2))/ sqrt(2 * pi) 
  (S * exp(-rf*t)*sqrt(t) * Np)/100
}

implied.vol <-
  function(type, S, X, t, r, rf, market){
    sig <- 0.20
    sig.up <- 1
    sig.down <- 0.001
    count <- 0
    err <- BSoption(type, S, X, t, r, rf, sig) - market 

    ## repeat until error is sufficiently small or counter hits 1000
    while(abs(err) > 0.00001 && count<1000){
      if(err < 0){
        sig.down <- sig
        sig <- (sig.up + sig)/2
      }else{
        sig.up <- sig
        sig <- (sig.down + sig)/2
      }
      err <- BSoption(type, S, X, t, r, rf, sig) - market
      count <- count + 1
    }

    ## return NA if counter hit 1000
    if(count==1000){
      return(NA)
    }else{
      return(sig)
    }
  }

S <- 0.906
X <- seq(0.7,1.2,0.01)
t <- 1
r <- 0.0507
rf <- 0.047#-log(0.9945049)/t
ATMcost <- BSoption("c",S,XATM,t,r,rf,vATM)

v25p <- 0.13575#vv.inputs$Vol[vv.inputs$Skew == -0.25]
vATM <- 0.132#vv.inputs$Vol[vv.inputs$Skew == 0.0]
v25c <- 0.13425#vv.inputs$Vol[vv.inputs$Skew == 0.25]

X25p <- 0.8350575#BSStrikeFromDelta("p",S,v25p,t,r,rf,0.25)
XATM <- S
X25c <- 1.000846#BSStrikeFromDelta("c",S,t,r,v25c,rf,0.25)

w1 <- (vega(S,X,t,r,rf,vATM)/vega(S,X25p,t,r,rf,v25p))*((log(XATM/X)*log(X25c/X))/(log(XATM/X25p)*log(X25c/X25p)))
w2 <- (vega(S,X,t,r,rf,vATM)/vega(S,XATM,t,r,rf,vATM))*((log(X/X25p)*log(X25c/X))/(log(XATM/X25p)*log(X25c/XATM)))
w3 <- (vega(S,X,t,r,rf,vATM)/vega(S,X25c,t,r,rf,v25c))*((log(X/X25p)*log(X/XATM))/(log(X25c/X25p)*log(X25c/XATM)))

VV.price <- ATMcost + w1*(BSoption("c",S,X25p,t,r,rf,v25p)-BSoption("c",S,X25p,t,r,rf,vATM)) + w3*(BSoption("c",S,X25c,t,r,rf,v25c)-BSoption("c",S,X25c,t,r,rf,vATM))

VV.vol <- 0
for(i in 1:length(X)){
  VV.vol[i] <- implied.vol("c",S,X[i],t,r,rf,VV.price[i])
}
plot(X,VV.price)
plot(X,VV.vol)

Como puede ver, calculo el precio vanna-volga de la opción, que es consistente con las comillas dadas pero, cuando trazo la "sonrisa" de la volatilidad, en realidad no es una sonrisa en absoluto y no estoy seguro de dónde me estoy equivocando.

Cualquier ayuda es muy apreciada.

0voto

s_a Puntos 108

En la línea de abajo todo lo que tuve que hacer fue reemplazar X[i] con XATM porque el método vanna volga crea un precio para una opción que satisface la cobertura vega,vanna,volga ATM por lo que siempre estás obteniendo vol. con strike ATM.

VV.vol[i] <- implied.vol("c",S,X[i],t,r,rf,VV.price[i])

0 votos

Si esto resolvió tu problema, entonces puedes aceptar tu propia respuesta.

0voto

s_a Puntos 108

En realidad, la mejor manera de responder a esta pregunta era utilizar el documento original de Mercurio y Castagna, que contiene una prueba y una explicación de la mejor manera de calcular el vol implícito.

Vea el documento aquí:

http://www.fabiomercurio.it/consistentfxsmile.pdf

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X