c#
featured
Finanzas
Volatilidad implícita con ecuaciones de Black-Scholes (ejemplo, algoritmo y código en c# y Java)
agosto 18, 2017Robert Red
En esta entrada se describe la manera en que se obtiene la volatilidad implícita de opciones Put y Call utilizando las ecuaciones de Black-Scholes y resolviendo con un algoritmo Newton-Raphson.
Las ecuaciones de Black-Scholes derivadas por Fisher Black y Myron Scholes en 1973 para valuar una opción Europea son:
\begin{eqnarray}
c & = & S \Phi(d_1) - K e^{-rT} \Phi(d_2)\\
p & = & K e^{-rT} \Phi(-d_2) - S \Phi(-d_1)
\end{eqnarray}
en donde
\begin{eqnarray}
d_1 & = & \frac{\ln(S/K)+(r+\sigma^2/2)T}{\sigma\sqrt{T}}\\
d_2 & = & \frac{\ln(S/K)+(r-\sigma^2/2)T}{\sigma\sqrt{T}}\\
& = & d_1 - \sigma\sqrt{T}
\end{eqnarray}
Y las variables involucradas son:
1. $c$, es el precio de la opción call;
2. $p$, es el precio de la opción put;
3. $S$, es el precio del subyacente;
4. $K$, es el precio de ejercicio;
5. $r$, es la tasa de interés libre de riesgo;
6. $T$, son los días que faltan para el vencimiento (anualizados, $Días/365$);
7. $\Phi$, es la función de distribución acumulada de una variable aleatoria normal estándar.
El objetivo es obtener el valor de $\sigma$ de las ecuaciones $d_1$ y $d_2$ sin embargo no es posible hacer un despeje que permita obtenerlo directamente, además de que estas ecuaciones están acopladas a los precios de las opciones call y put. Es importante observar que se tiene una volatilidad implícita para calls y una para puts por lo que se denotan como $\sigma_c$ y $\sigma_p$, respectivamente.
Para poder encontrar los valores de $\sigma_c$ y $\sigma_p$ se utiliza el algoritmo de Newton-Raphson, este método permite encontrar los ceros (raíces) de una función $f(x)$ mediante el proceso iterativo dado por
\begin{equation}
x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}
\end{equation}
deteniendo las iteraciones una vez que se cumpla que $|x_{n+1}-x_n|<\epsilon$, en donde comúnmente se elige $\epsilon=1E^{-5}$. Para utilizar este algoritmo se definen las funciones
\begin{eqnarray}
f(\sigma_c) & = & S \Phi(d_1) - K e^{-rT} \Phi(d_2) - c\\
g(\sigma_p) & = & K e^{-rT} \Phi(-d_2) - S \Phi(-d_1) - p
\end{eqnarray}
De esta forma basta con encontrar los ceros (raíces) de $f(\sigma_c)$ y $g(\sigma_p)$. Para poder implementar el proceso recursivo es necesario calcular la primera derivada de dichas funciones, se tiene que
\begin{eqnarray} f'(\sigma_c) & = & S \Phi'(d_1)d'_1 - K e^{-rT} \Phi'(d_2)d'_2\\ g'(\sigma_p) & = & -K e^{-rT}\Phi'(-d_2)d'_2 +S \Phi'(-d_1)d'_1 \end{eqnarray}
Observe que, al ser $\Phi(d_1)$ la función de distribución normal acumulada estándar, su derivada es $\phi(d_1)$, la función de densidad, de la misma manera se tiene que $\Phi'(d_2)=\phi(d_2)$, $\Phi'(-d_2)=\phi(-d_2)$ y $\Phi'(-d_1)=\phi(-d_1)$, por otro lado, es necesario calcular las derivadas de $d_1$ y de $d_2$. Se inicia con la derivada de $d_1$ que es igual a
\begin{eqnarray} d'_1 & = & \frac{\partial}{\partial \sigma} \frac{\ln(S/K)+(r+\sigma^2/2)T}{\sigma\sqrt{T}}\\ & = & \frac{\sigma\sqrt{T}\frac{\partial}{\partial \sigma}\left(\ln(S/K)+(r+\sigma^2/2)T\right)-\left(\ln(S/K)+(r+\sigma^2/2)T\right)\frac{\partial}{\partial \sigma}\sigma\sqrt{T}}{\left(\sigma\sqrt{T}\right)^2}\\ & = & \frac{\sigma\sqrt{T}(\sigma T)-\left(\ln(S/K)+(r+\sigma^2/2)T\right)\sqrt{T}}{\sigma^2 T}\\ & = & \frac{\sigma^2 T^{3/2}-\ln(S/K)T^{1/2}+rT^{3/2}+\frac{\sigma^2}{2}T^{3/2}}{\sigma^2 T}\\ & = & \sqrt{T}-\frac{\ln(S/K)\sigma^{-2}}{\sqrt{T}}+r\sigma^{-2}\sqrt{T}+\cfrac{1}{2}\sqrt{T}\\ & = & \left(\cfrac{3}{2}-\ln(S/K)\sigma^{-2}T^{-1}+r\sigma^{-2}\right)\sqrt{T} \end{eqnarray}
Continuando con la derivada de $d_2$ y dado que $d_2=d_1 - \sigma\sqrt{T}$ se tiene que \begin{equation} d'_2 = d'_1-\sqrt{T} \end{equation} En resumen, se tiene \begin{eqnarray} f(\sigma_c) & = & S \Phi(d_1) - K e^{-rT} \Phi(d_2) - c\\ f'(\sigma_c) & = & S \phi(d_1)d'_1 - K e^{-rT} \phi(d_2)d'_2\\ g(\sigma_p) & = & K e^{-rT} \Phi(-d_2) - S \Phi(-d_1) - p\\ g'(\sigma_p) & = & -K e^{-rT}\phi(-d_2)d'_2 +S \phi(-d_1)d'_1\\ d'_1 & = & \left(\frac{3}{2}-\ln(S/K)\sigma^{-2}T^{-1}+r\sigma^{-2}\right)\sqrt{T}\\ d'_2 & = & d'_1-\sqrt{T} \end{eqnarray}
Y con estas ecuaciones ya es posible implementar el método recursivo de Newton-Raphson para encontrar el cero (raíz) de $f(\sigma_c)$ y de $g(\sigma_p)$, dichos ceros son igual a la volatilidad implícita, $\sigma_c$, de una opción call y la volatilidad implícita, $\sigma_p$, de una opción put. Un paso muy importante es definir el punto inicial $\sigma_0$ en donde empieza a iterar el algoritmo, pues de éste depende la convergencia del mismo, para esto se utiliza el valor inicial de Manaster y Koehler que se define como
\begin{equation} \sigma_0=\max\left(0.01, \sqrt{2\left|\ln(S/K)\right|/T+r}\right) \end{equation} Como la finalidad de este blog es mostrar con mayor detalle los procedimientos, el siguiente paso consiste en realizar un ejemplo de cómo se calcula la volatilidad implícita para una opción call con datos reales, para esto vamos a la página de la Chicago Board Options Exchange ( CBOE) y vemos, por ejemplo, las opciones de Apple y cuyo símbolo financiero es AAPL, tenemos que los datos para una opción call son:
\begin{eqnarray} f'(\sigma_c) & = & S \Phi'(d_1)d'_1 - K e^{-rT} \Phi'(d_2)d'_2\\ g'(\sigma_p) & = & -K e^{-rT}\Phi'(-d_2)d'_2 +S \Phi'(-d_1)d'_1 \end{eqnarray}
Observe que, al ser $\Phi(d_1)$ la función de distribución normal acumulada estándar, su derivada es $\phi(d_1)$, la función de densidad, de la misma manera se tiene que $\Phi'(d_2)=\phi(d_2)$, $\Phi'(-d_2)=\phi(-d_2)$ y $\Phi'(-d_1)=\phi(-d_1)$, por otro lado, es necesario calcular las derivadas de $d_1$ y de $d_2$. Se inicia con la derivada de $d_1$ que es igual a
\begin{eqnarray} d'_1 & = & \frac{\partial}{\partial \sigma} \frac{\ln(S/K)+(r+\sigma^2/2)T}{\sigma\sqrt{T}}\\ & = & \frac{\sigma\sqrt{T}\frac{\partial}{\partial \sigma}\left(\ln(S/K)+(r+\sigma^2/2)T\right)-\left(\ln(S/K)+(r+\sigma^2/2)T\right)\frac{\partial}{\partial \sigma}\sigma\sqrt{T}}{\left(\sigma\sqrt{T}\right)^2}\\ & = & \frac{\sigma\sqrt{T}(\sigma T)-\left(\ln(S/K)+(r+\sigma^2/2)T\right)\sqrt{T}}{\sigma^2 T}\\ & = & \frac{\sigma^2 T^{3/2}-\ln(S/K)T^{1/2}+rT^{3/2}+\frac{\sigma^2}{2}T^{3/2}}{\sigma^2 T}\\ & = & \sqrt{T}-\frac{\ln(S/K)\sigma^{-2}}{\sqrt{T}}+r\sigma^{-2}\sqrt{T}+\cfrac{1}{2}\sqrt{T}\\ & = & \left(\cfrac{3}{2}-\ln(S/K)\sigma^{-2}T^{-1}+r\sigma^{-2}\right)\sqrt{T} \end{eqnarray}
Continuando con la derivada de $d_2$ y dado que $d_2=d_1 - \sigma\sqrt{T}$ se tiene que \begin{equation} d'_2 = d'_1-\sqrt{T} \end{equation} En resumen, se tiene \begin{eqnarray} f(\sigma_c) & = & S \Phi(d_1) - K e^{-rT} \Phi(d_2) - c\\ f'(\sigma_c) & = & S \phi(d_1)d'_1 - K e^{-rT} \phi(d_2)d'_2\\ g(\sigma_p) & = & K e^{-rT} \Phi(-d_2) - S \Phi(-d_1) - p\\ g'(\sigma_p) & = & -K e^{-rT}\phi(-d_2)d'_2 +S \phi(-d_1)d'_1\\ d'_1 & = & \left(\frac{3}{2}-\ln(S/K)\sigma^{-2}T^{-1}+r\sigma^{-2}\right)\sqrt{T}\\ d'_2 & = & d'_1-\sqrt{T} \end{eqnarray}
Y con estas ecuaciones ya es posible implementar el método recursivo de Newton-Raphson para encontrar el cero (raíz) de $f(\sigma_c)$ y de $g(\sigma_p)$, dichos ceros son igual a la volatilidad implícita, $\sigma_c$, de una opción call y la volatilidad implícita, $\sigma_p$, de una opción put. Un paso muy importante es definir el punto inicial $\sigma_0$ en donde empieza a iterar el algoritmo, pues de éste depende la convergencia del mismo, para esto se utiliza el valor inicial de Manaster y Koehler que se define como
\begin{equation} \sigma_0=\max\left(0.01, \sqrt{2\left|\ln(S/K)\right|/T+r}\right) \end{equation} Como la finalidad de este blog es mostrar con mayor detalle los procedimientos, el siguiente paso consiste en realizar un ejemplo de cómo se calcula la volatilidad implícita para una opción call con datos reales, para esto vamos a la página de la Chicago Board Options Exchange ( CBOE) y vemos, por ejemplo, las opciones de Apple y cuyo símbolo financiero es AAPL, tenemos que los datos para una opción call son:
| Subyacente | Ejercicio | Bid | Ask | Emisión | Vencimiento |
|---|---|---|---|---|---|
| 157.5 | 155 | 3.50 | 3.60 | 18-ago-17 | 25-ago-17 |
Como se puede ver, no se tiene el precio de la opción call, lo que se tiene son el Bid y el Ask, como convención se utiliza como precio $c$ al promedio del Bid y el Ask, entonces, para el ejemplo se tiene
\begin{eqnarray}
c & = & \frac{Bid+Ask}{2}\\
& = & \frac{3.50+3.60}{2}\\
& = & 3.55
\end{eqnarray}
Otro dato que se necesita es el valor de $T$, que es igual al número de días para el vencimiento anualizados, según los datos la opción se emite el 18 de agosto de 2017 y vence el 25 de agosto de 2017 por lo que restan 7 días para el vencimiento, para anualizar estos días se divide por 365 por lo que
\begin{eqnarray} T & = & \frac{7}{365}\\ & = & 0.01917808 \end{eqnarray}
Por último como tasa de interés libre de riesgo se toma la del departamento del tesoro de USA que es $r=1.24$ anual por lo que, al convertirla a los siete días para el vencimiento, queda como
\begin{eqnarray} r & = & \frac{1.24}{365}(7)\\ & = & 0.02378082 \end{eqnarray}
Ya se tienen todos los datos que se necesitan para calcular la volatilidad implícita $\sigma_c$ de una opción call de Apple, los datos son \begin{eqnarray} S & = & \frac{7}{365}\\ K & = & 0.01917808\\ c & = & 3.55\\ T & = & 0.01917808\\ r & = & 0.02378082 \end{eqnarray} Con estos valores, la condición inicial para el proceso iterativo es
\begin{eqnarray} \sigma_0 & = & \max\left(0.01, \sqrt{2\left|\ln(S/K)\right|/T+r}\right)\\ & = & \max\left(0.01, \sqrt{2\left|\ln(157.5/155)\right|/0.01917808+0.02378082}\right)\\ & = & \max\left(0.01, 1.31002628\right)\\ & = & 1.31002628 \end{eqnarray}
Y utilizando esta condición inicial se comienza con las iteraciones, para $n=1$ se tiene
\begin{eqnarray} \sigma_1 & = & \sigma_0-\frac{f(x\sigma_0)}{f'(\sigma_0)}\\ & = & 1.31002628-\frac{f(0.865128687)}{f'(0.865128687)}\\ & = & 1.31002628-\frac{9.07228416}{8.55945785}\\ & = & 0.25011287 \end{eqnarray}
Se repite el procedimiento hasta que se cumpla que $|\sigma_{n+1}-\sigma_n|<\epsilon=1E^{-5}$. En este caso se obtiene que, después de 4 iteraciones, el método converge y la volatilidad implícita para la opción call de Apple es $$\sigma_c=0.232722$$
De manera análoga se calcula la volatilidad implícita para la opción put de Apple cuyos datos son:
Otro dato que se necesita es el valor de $T$, que es igual al número de días para el vencimiento anualizados, según los datos la opción se emite el 18 de agosto de 2017 y vence el 25 de agosto de 2017 por lo que restan 7 días para el vencimiento, para anualizar estos días se divide por 365 por lo que
\begin{eqnarray} T & = & \frac{7}{365}\\ & = & 0.01917808 \end{eqnarray}
Por último como tasa de interés libre de riesgo se toma la del departamento del tesoro de USA que es $r=1.24$ anual por lo que, al convertirla a los siete días para el vencimiento, queda como
\begin{eqnarray} r & = & \frac{1.24}{365}(7)\\ & = & 0.02378082 \end{eqnarray}
Ya se tienen todos los datos que se necesitan para calcular la volatilidad implícita $\sigma_c$ de una opción call de Apple, los datos son \begin{eqnarray} S & = & \frac{7}{365}\\ K & = & 0.01917808\\ c & = & 3.55\\ T & = & 0.01917808\\ r & = & 0.02378082 \end{eqnarray} Con estos valores, la condición inicial para el proceso iterativo es
\begin{eqnarray} \sigma_0 & = & \max\left(0.01, \sqrt{2\left|\ln(S/K)\right|/T+r}\right)\\ & = & \max\left(0.01, \sqrt{2\left|\ln(157.5/155)\right|/0.01917808+0.02378082}\right)\\ & = & \max\left(0.01, 1.31002628\right)\\ & = & 1.31002628 \end{eqnarray}
Y utilizando esta condición inicial se comienza con las iteraciones, para $n=1$ se tiene
\begin{eqnarray} \sigma_1 & = & \sigma_0-\frac{f(x\sigma_0)}{f'(\sigma_0)}\\ & = & 1.31002628-\frac{f(0.865128687)}{f'(0.865128687)}\\ & = & 1.31002628-\frac{9.07228416}{8.55945785}\\ & = & 0.25011287 \end{eqnarray}
Se repite el procedimiento hasta que se cumpla que $|\sigma_{n+1}-\sigma_n|<\epsilon=1E^{-5}$. En este caso se obtiene que, después de 4 iteraciones, el método converge y la volatilidad implícita para la opción call de Apple es $$\sigma_c=0.232722$$
De manera análoga se calcula la volatilidad implícita para la opción put de Apple cuyos datos son:
| Subyacente | Ejercicio | Bid | Ask | Emisión | Vencimiento |
|---|---|---|---|---|---|
| 157.5 | 155 | 0.96 | 1.03 | 18-ago-17 | 25-ago-17 |
En este caso se obtiene que
$$\sigma_p=0.234789.$$
Estos resultados se obtuvieron con el programa hecho en Visual Studio c# 2012. El código se puede obtener en el siguiente enlace
De igual manera se proporciona el programa hecho en Java bajo la plataforma NeatBeans 8.2. El código se puede obtener en el siguiente enlace
Finalmente, podemos verificar el resultado en Matlab (R2014B) utilizando la función
Volatility = blsimpv(Price, Strike, Rate, Time, Value, Limit, Yield, Tolerance, Class)
con la que se obtiene
>> Volatility = blsimpv(157.5, 155, 0.02378082, 0.01917808, 3.55, 0.5, 0, [], {'Call'})
Volatility =
0.2327
>> Volatility = blsimpv(157.5, 155, 0.02378082, 0.01917808, 0.9950, 0.5, 0, [], {'Put'})
Volatility =
0.2348
Referencias:
[1] The complete guide to option pricing formulas, Espen gaarder haug, 2nd edition, McGraw-Hill. (descargar)
[2] Numerical methods that work, Forma S. Acton, Mathematicval Asociation of America. (descargar)