1.
Visión
descriptiva de la volatilidad usando índices
La volatilidad, junto al rendimiento y la liquidez forman
variables básicas al momento los agentes tomar decisiones orientadas a
optimizar sus decisiones. En los mercados financieros la volatilidad suele
medirse a partir de las desviaciones o varianza del cambio porcentual del
índice o precio (rendimientos), aunque esta medida asume varios retos que
veremos brevemente adelante. En finanzas existen diversos tipos de riesgo:
riesgo de mercado, de reinversión, operacionales, de crédito… por tanto la
medición del riesgo requerirá definir con anterioridad que se desea medir y
como. Además en el caso de los activos específicos cuentan con riesgos
sistemáticos que se recogen dentro de un índice de mercado (no diversificable
dentro del mismo mercado) y un riesgo no sistemático o propio de cada activo.
Ejemplo 1.
Calculo de la volatilidad sobre el índice DowJone
En el siguiente ejemplo se utiliza la cotización de
cierre diaria, del DowJone correspondientes a los meses abril-junio de 2014.
Luego de cargar los datos se calcula la tasa de crecimiento o rendimiento del
activo sobre el cual se calcula la varianza y desviación, que representan las
volatilidad del indicice.[1]
indice
= xlsread('DowJoneAbr14Jun14.xlsx')
plot(indice(:,1))
title('Grafico 1. Evoulución del Dow Jone, Abril-Junio 2014')
|
format bank
indice = xlsread('DowJoneAbr14Jun14.xlsx')
rendimiento = 100.0*(indice(2:end,1)./indice(1:end-1,1)-1.0)
var(rendimiento) %Varianza
std(rendimiento) %Desviación Estándar
|
Se pueden realizar algunas notas aclaratorias sobre el
comando anterior, [xlsread] permite cargar la base
de datos al sistema y [rendimiento] calcula el
rendimiento del índice como el cociente entre el valor presente y el valor
pasado, basado en dos vectores tomado sobre el índice el primer vector captura
los valores actuales y va de la segunda observación a la última en la primera
columna de la matriz índice [indice(2:end,1)], el
segundo vector va desde la primera observación hasta la penúltima en la misma
matriz [indice(1:end-1,1)] y representa los valores
retardado. A este cociente le resta uno tal como se hace común mente.
El próximo comando (se anexa al final del documento),
aunque un poco cutre, permite obtener una tabla con un resumen estadístico de
los índices ('DJONE', 'SP500', 'IBMEX', 'NIKKE', 'IBEX35')
Tabla 1. Resumen estadístico valores de
índice a nivel
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'Estadístico' 'DJONE' 'SP500' 'IBMEX' 'NIKKE' 'IBEX35'
'Estadístico' 'DJONE' 'SP500' 'IBMEX' 'NIKKE' 'IBEX35'
----------------------------------------------------------------------------------------
'Media' [16923.31] [1958.98]
[ 43069.15] [15231.53] [10916.05]
'Varianza' [14459.18] [ 326.15]
[514025.52] [20656.12] [46200.55]
'Dst.Est.' [ 120.25]
[ 18.06] [
716.96] [ 143.72]
[ 214.94]
'Coef.Var.' [ 140.74]
[ 108.47] [ 60.07]
[ 105.98] [
50.79]
'Asimetria' [ -0.07]
[ -0.59] [
-0.14] [ -0.33]
[ -0.56]
'Curtosis' [ 2.03] [
2.34] [ 2.47]
[ 1.85] [
2.09]
----------------------------------------------------------------------------------------
Es importante recordar que una mayor varianza no permite,
por si sola, definir cuál de los índices ha sido más volátil. Sin Embargo el
uso de desviaciones típicas como porcentaje de la media ['Coef.Var.'] si permite realizar este tipo de argumentos,
por el hecho de expresar todos los valores en medidas comparables. Para obtener
los valores en rendimientos, ahora no de un vector, sino de una matriz completa
de datos, se modifica levemente el comando anterior y se puede obtener la misma
tabla, pero sobre los rendimientos y anexando el test de normalidad de Jarque
Bera ['Jarque-Bera'].[2]
rendimientos = 100.0*(indices(2:end,:)./indices(1:end-1,:)-1.0)
|
Observe que la única diferencia con el comando anterior
de rendimientos es que se sustituye el 1 por los dos puntos (parte sombreada)
esto le indica al programa que no solo realice el cálculo en la primera
columna, sino que lo repita en todas. Otros lenguajes de programación como R,
permiten hacer este tipo de operaciones. Una vez calculado el rendimiento de
todos los índices se repite la tabla anterior ahora sobre el rendimiento.
Tabla 2. Resumen estadístico valores de
índice en rendimiento
--------------------------------------------------------------------------
'Estadístico' 'DJONE' 'SP500'
'IBMEX' 'NIKKE' 'IBEX35'
--------------------------------------------------------------------------
'Media' [ 0.07] [ 0.09]
[ 0.20] [ 0.05] [ -0.08]
'Varianza' [ 0.19] [ 0.17]
[ 0.39] [ 0.42] [
0.60]
'Dst.Est.' [ 0.44] [ 0.41]
[ 0.63] [ 0.65] [
0.77]
'Coef.Var.' [ 0.15] [ 0.23]
[ 0.32] [ 0.07] [
-0.10]
'Asimetria' [-0.73] [-0.44]
[ 0.61] [ 0.34] [
0.04]
'Curtosis' [ 3.26] [ 3.28]
[ 3.56] [ 2.95] [
3.10]
'Jarque-Bera' [ 0.00] [ 0.00]
[ 0.00] [ 0.00] [
0.00]
--------------------------------------------------------------------------
Es importante resaltar que el cuadro anterior representa
datos de un periodo de tiempo relativamente corto, por lo que la volatilidad
puede estar afectada por una condición particular a ese periodo y no a condiciones
estructurales de los mercados, por lo que para periodos suficientemente largos,
las conclusiones pueden cambiar considerablemente. En ocasiones también es
necesario obtener estimación de la volatilidad, por ventadas. Matlab permite
obtener este usando un bucle que vaya rotando la ventana de acción y se ejecute
por cada columna.
n = 15.0 %tamaño de la ventana;
for j=1:5
for i = 1:((length(indices)-n))
ventana_std(i,j) = std(indices(i:i+n,j));
end
end
ventana_std
|
El comando anterior[3]
es un bucle anidado que corre el primer for y luego el segundo. En palabras el
primer for [for j=1:5] le indica al
programa que camine por columna y luego el segundo por observaciones [for i = 1:((length(indices)-n))]
teniendo en cuenta la amplitud de la ventada. Es decir que en la primera
secuencia de cálculo, j=1 indicando la columna e i estará caminando desde 1
hasta el máximo del vector menos la longitud de ventanas deseada (n=15), en
este caso de 15 por lo que ira hasta end-15 observaciones. Ya
dentro del bucle para la primera secuencia, la sentencia de cálculo de la
volatilidad [ventana_std(i,j) = std(indices(i:i+n,j))]
guarda dos elementos claves [ventana_std(i,j)] que permite
que los datos se guarden en una matriz y no uno encima de otro y [indices(i:i+n,j)]
que se va moviendo en el rango sobre el cual se calcula la volatilidad, en la
primera observación será (1:1+15, 1) es decir en una
ventana con las primeras 15 observaciones, luego (2:2+15, 1)…
hasta que recorre todas las opciones de la primera columna, luego lo repetirá
pero ira cambiando el 1 por 2,3 así hasta 5 indicando el cambio de columna.
En ocasiones es importante que estos datos sean los más
comparables posibles, por ende es interesante comparar (en ventanas, como en el
comando anterior) el coeficiente de variación, ya que presenta la desviación en
proporción a la media, para obtenerlo solo habría que modificar la línea [4]
sustituyéndola por la fórmula:
ventana_coefVar(i,j)= std(indices(i:i+(n-1),j))./mean(indices(i:i+(n-1),j));
|
Observe que la idea se repite, lo importante es
especificar la forma en cómo se ira moviendo los rangos de datos. Siguiendo la
idea de hacer las variables comparables es frecuente que estas se tipifiquen o
se normalicen que no es más que restar la media a cada observación y dividir
entre la desviación estándar. Este procedimiento se puede realizar en Matlab
con relativa facilidad.
indices
= xlsread('indicesJun14Jul14.xlsx',1)
format
short
des.sta=std(indices)
for j=1:5
for i = 1:length(indices)
normalize(i,j)
= indices(i,j) - mean(indices(:,j));
normalize_indices(i,j) =
normalize(i,j)/ des.sta(j);
normalize_indices
end
end
|
En caso que se desee llamar un vector de dentro de una
matriz, no se necesita usar bucle y sustituyen la [i=:] y [j=nocol] es decir j será igual al
número de columna que se desea extraer. En el caso de un vector la notación se
simplifica considerablemente.
x=1:10;
xtipificada = x-mean(x)./std(x)
|
Este tipo de variables además de utilizarse para hacer
las series comparables, es útil al momento de realizar análisis de
correlaciones. Cuando se presentan los datos en función de la media se resuelve
un problema importante en términos de comparabilidad aunque sigue presente el
problema de la no estacionariedad de los índices. Por lo que es necesario
trabajar con una transformación que si lo sea, por lo general la rentabilidad
logarítmica. Para obtener la rentabilidad logarítmica de un vector o matriz se
realizan los siguientes cálculos.
%En el caso de un vector
DJONE =
indices(:,1);
rlogDJONE = log(DJONE(2:end)./DJONE(1:end-1))*100.0
|
%En el caso de una matriz de datos
Rlog_indices =
log(indices(2:end,:)./indices(1:end-1,:))*100.0
|
La volatilidad se comúnmente utilizada para para
determinar estrategias de cobertura, por tanto definirla mal daría lugar a estrategias
inadecuadas, además del uso extendido de la matriz de varianza covarianzas en
la gestión de riesgo. Por lo que es importante tener buena medida de la
volatilidad y considerar las limitaciones de la estimación de la volatilidad muestra.
Entre esta se encuentra: el sesgo al estimar las desviaciones, la posible
presencia de tendencias deterministas o estocásticas y cualquier cambio de
nivel en las variables hace perder representatividad a las medidas de tendencia
centrales.
Por ultimo dos comandos que suelen ser útiles en una gran
cantidad de aplicaciones financieras son la matriz de correlaciones y la de
varianza covarianzas. Ambas son cuadradas y simétricas. En el caso de la
primera se obtiene con el comando [cov] y arroja una matriz
donde la diagonal principal muestra las varianzas de cada serie y los elementos
fuera de la diagonal principal la covarianza entre las series. En tanto que la
matriz de correlaciones se llama usando [corr]
esta muestra la correlaciones entre las series, siendo la diagonal principal
igual a 1 porque representa la relación lineal de la serie con ella misma.
cov(indices)
0.1446 0.0186 0.7690
0.1050 -0.1142
0.0186 0.0033 0.1108
0.0205 -0.0102
0.7690 0.1108
5.1403 0.5547 -0.7333
0.1050 0.0205 0.5547
0.2066 -0.0347
-0.1142 -0.0102 -0.7333
-0.0347 0.4620
corr(indices)
1.0000 0.8568
0.8920 0.6077 -0.4418
0.8568 1.0000 0.8555
0.7897 -0.2639
0.8920 0.8555 1.0000
0.5383 -0.4759
0.6077 0.7897 0.5383
1.0000 -0.1125
-0.4418 -0.2639 -0.4759
-0.1125 1.0000
|
2.
Medición de la volatilidad de un activo
financiero
Se puede considerar el cuadrado de la rentabilidad diaria
para utilizarlo como predicción de la volatilidad diaria. En Matlab este se
haría de la forma siguiente, primero se estima el rendimiento como la
diferencia logarítmica y luego cada uno de estos valores [.^] se eleva al cuadrado.
DJONE =
indices(:,1);
R_Djone = log(DJONE(2:end))-log(DJONE(1:end-1));
Vol_Djone = R_Djone.^2 ;
plot(t,
Vol_Djone);
|
1.1. Medidas de Parkinson y Garman-Klass
Frente a las deficiencias encontradas en la volatilidad
como medida de riesgos se han incorporado otras medidas que pueden utilizarse
dependiendo del tipo de información que se maneje. Cuando se dispone del precio
de todas las transacciones diarias de un activo, la formula difiere a cuando no
se tratan de transacciones diaria o cuando se dispone de pocas observaciones.
En nuestro caso disponemos de transacciones diarias (pero la usaremos a modo de
ejemplo como si se tratasen de transacciones hechas en un mismo días, por tanto
la volatilidad anual se obtiene de la siguiente forma:
En la formula anterior la primera raíz sirve para
anualizar la volatilidad y su valor puede variar según la transformación en el
tiempo que se necesite (semanal=52), la segunda raíz permite calcular la
volatilidad diaria usando las variaciones del rendimiento de las operaciones
registradas durante ese día. Además existen otras propuestas para cuando se
disponen de otro tipo de información. Siendo r el rendimiento. En el caso de la
primera raíz, cuando se trate de una volatilidad diferente a diaria, se puede
modificar para obtener la volatilidad anual. Ejemplo 12 en caso que sea mensual,
r es igual a la rentabilidad diaria y T las observaciones.
Ejemplo.
Disponiendo de los datos mensuales de cotización
diaria (aquí se entienden como si fueran todas transacciones hecha en un mismo
día), en fecha de 07/05/2007 al 28/02/2014[4].
Una vez cargada la base solo habría que estimar el
rendimiento y luego colocar la formula mostrada anteriormente. (Esta fórmula se
puede ir modificando según las distintas propuestas)
%Cálculo de la rentabilidad
r = log(azucar(2:end)./azucar(1:end-1))*100.0
%Cálculo de la volatilidad
Vol_azucar = sqrt(12)*sqrt((1./length(r)-1).*sum((r-mean(r)).^2))
%siendo T = length(r)
|
1.1. Volatilidad implícita Vs. Volatilidad histórica
La volatilidad implícita se calcula a partir del precio
de los activos, utilizando la ecuación de Black-Scholes que se presenta a
continuación. Siendo c el precio de mercado de una opción de compra europea y estando todos los parámetros conocidos,
salvo sigma, lo que se intenta es buscar el valor de sigma que iguala el precio
de mercado con el precio teórico. Este valor de sigma es lo que se conoce como
volatilidad implícita. Es decir, se puede determinar la volatilidad implícita a
partir del precio de la opción en ausencia de arbitraje, por lo que depende del
deseo de compra y venta.
De forma llana se tiene una igualdad entre la formula anterior
y el precio de mercado, solo falta el valor de sigma que hace que ambos precios
se igualen.
Ejemplo. Calculo
de la volatilidad implícita de una Call Digital
En el siguiente ejemplo se muestra como calcular la
volatilidad implícita usando la fórmula de BS de una opción europea binaria. (Este
mismo procedimiento se puede aplicar para casi cualquier opción, modificando
los parámetros de la fórmula de cálculo, el payoff de la opción). En este caso
se crean tres funciones que se expone a continuación.
Paso 1. La idea de las dos primeras funciones es calcular
el precio de mercado de una opción que pague a en caso que el precio del
subyacente sea mayor al precio de ejercicio (ST>K) y nada en caso contrario
(payoff). (Este payoff se podría medicar según el tipo de opción sobre la cual
se esté trabajando)
function
f = integrandoCallDig(x,S0,K,r,T,sigma,a)
%Calcula
el precio del subyacente en el momento T
ST =
S0*exp((r-0.5*sigma^2)*T + sigma*sqrt(T)*x);
%Calcula
el Payoff (funcion de pago) de una Call Digital
for i=1:length(ST)
if ST(i)>=K
payoff(i) = a;
else
payoff(i) = 0;
end
end
f = normpdf(x).*payoff;
end
|
function precio =
precioCallDig(S0,K,r,T,sigma,a)
%precioCallDig: Precio de una call
europea Digital
precio = exp(-r*T)*quadl(@(x)integrandoCallDig(x,S0,K,r,T,sigma,a),-10,10);
end
|
En el caso que se estén usando simulaciones por Montecarlo
se utiliza la cuadratura por Montecarlo para sustituir la integral de esta última
formula. (En otro documento se explicara más adelante como se hace).
Paso 2. En el segundo paso se obtiene la estimación de la
volatilidad implícita mediante un bucle while, la idea es ir modificando el
valor de la volatilidad, en la función que calcula el precio teórico (segunda función),
hasta que la diferencia entre el precio teórico y el precio del mercado sea
igual a cero.
function f =
Vol_Imp_CallDig(market,S0,K,r,T,sigma,a)
%Vol_Imp_CallDig:
Volatilidad implicita de una call europea Digital
%Se especifica el formato de salida y se
especifican los valores de
%partidas de la diferencia entre el precio teórico
y el precio de mercado.
format long
pBS = precioCallDig(S0,K,r,T,sigma,a);
V = pBS-market;
%Se crea un bucle (while)que
modifica la volatilidad hasta que el precio de
%la Call obtenido por Black-Scholme,
sea igual al precio de mercado
while 1
if
V<=0
disp('A esta volatilidad los precios se
igualan')
break
end
sigma=sigma+0.0001;
V =
precioCallDig(S0,K,r,T,sigma,a)-market;
f=sigma;
end
|
Una vez creadas y guardadas las funciones en el path o
directorio de Matlab en el que se esté trabajando, se utiliza esta última
función para obtener la volatilidad implícita:
Vol_Imp_CallDig(7.81,100,90,0.1,2,0.001,10)
ans =
0.122000000000002
|
Ahora bien para graficar la volatilidad, el método
recursivo (While) usado anteriormente, solamente funciona en caso que el
vencimiento o los parámetros ofrezcan un precio teórico superior al precio de
mercado. Por tanto con el ejemplo anterior no se puede utilizar vencimientos
superiores a 3. Por tal motivo se modifica (de forma un tanto cutre) el comando,
incluyendo un if anidando (comandos condicionales) que cambie la forma de
igualar ambas expresiones dependiendo de si el valor teórico está por encima o
por debajo del de mercado.
Una idea para graficar la volatilidad implícita a
distintos vencimientos es crear un bucle que vaya cambiando los valores de T en
la fórmula de vencimiento, así se puede obtener la volatilidad implícita vigente
en cada vencimiento.
S0 =
100; K = 90; r = 0.1; T = 2; sigma = 0.001; a=10; market=7.81;
for T = 1:10 %1:2
Vol_implicita(T)
= Vol_Imp_CallDig(market,S0,K,r,T,sigma,a);
end
plot(T,
Vol_implicita)
|
[1] Los
datos usados le corresponden a las 35 observaciones siguientes al 2 de junio de
2014 de cada datos, cotizaciones de cierre.