0% encontró este documento útil (0 votos)
809 vistas194 páginas

Machine Learning For Financial Risk Management With Python Algorithms Espanol

Este documento presenta un resumen del libro "Aprendizaje automático para la gestión de riesgos financieros con Python" de Abdullah Karasan. Explica que el libro explora cómo los modelos de aprendizaje automático pueden mejorar el rendimiento predictivo y la medición de riesgos en las finanzas. Consiste en 10 capítulos que cubren temas como los conceptos básicos de gestión de riesgos, tipos de riesgos, y cómo el aprendizaje automático puede usarse para mitigar las pérdidas financier

Cargado por

Ciro Carballo
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
809 vistas194 páginas

Machine Learning For Financial Risk Management With Python Algorithms Espanol

Este documento presenta un resumen del libro "Aprendizaje automático para la gestión de riesgos financieros con Python" de Abdullah Karasan. Explica que el libro explora cómo los modelos de aprendizaje automático pueden mejorar el rendimiento predictivo y la medición de riesgos en las finanzas. Consiste en 10 capítulos que cubren temas como los conceptos básicos de gestión de riesgos, tipos de riesgos, y cómo el aprendizaje automático puede usarse para mitigar las pérdidas financier

Cargado por

Ciro Carballo
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 194

Machine Translated by Google

Machine Translated by Google

Aprendizaje automático para finanzas


Gestión de riesgos con Python
Algoritmos para modelar el riesgo

Con los libros electrónicos de lanzamiento anticipado, obtiene libros en su forma


más antigua (el contenido sin editar y sin editar del autor mientras escribe)
para que pueda aprovechar estas tecnologías mucho antes del lanzamiento oficial de
estos títulos.

Abdullah Karasan
Machine Translated by Google

Aprendizaje automático para la gestión de riesgos financieros con Python por Abdullah

Karasan

Copyright © 2022 Abdullah Karasan. Reservados todos los derechos.

Impreso en los Estados Unidos de América.

Publicado por O'Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA
95472.

Los libros de O'Reilly se pueden comprar para uso educativo, comercial o promocional
de ventas. También hay ediciones en línea disponibles para la mayoría de los
títulos (http://oreilly.com). Para obtener más información, comuníquese con nuestro departamento
de ventas corporativo/institucional: 800­998­9938 o [email protected].

Editora de adquisiciones: Michelle Smith

Editora de desarrollo: Michele Cronin

Editor de producción: Daniel Elfanbaum

Diseñador de interiores: David Futato

Diseñador de portada: Karen Montgomery

Ilustradora: Kate Dullea

Diciembre de 2021: Primera edición

Historial de revisiones para la versión anticipada

2020­02­26: Primer lanzamiento

2021­05­19: Segundo lanzamiento

2021­09­10: Tercer lanzamiento

Ver http://oreilly.com/catalog/errata.csp?isbn=9781492085256 para detalles de lanzamiento.


Machine Translated by Google

El logotipo de O'Reilly es una marca registrada de O'Reilly Media, Inc.


Aprendizaje automático para la gestión de riesgos financieros con Python, la imagen de
portada y la imagen comercial relacionada son marcas comerciales de O'Reilly Media, Inc.

Las opiniones expresadas en este trabajo son las del autor y no representan las
opiniones del editor. Si bien el editor y el autor han realizado esfuerzos de buena fe para
garantizar que la información y las instrucciones contenidas en este trabajo sean
precisas, el editor y el autor renuncian a toda responsabilidad por errores u omisiones,
incluida, entre otras, la responsabilidad por los daños resultantes del uso o
confianza en este trabajo.
El uso de la información y las instrucciones contenidas en este trabajo es bajo su propio
riesgo. Si algún ejemplo de código u otra tecnología que este trabajo contiene o describe está
sujeto a licencias de código abierto o derechos de propiedad intelectual de otros, es su
responsabilidad asegurarse de que su uso cumpla con dichas licencias y/o derechos.

978­1­492­08518­8

[LSI]
Machine Translated by Google

Prefacio

La IA y el aprendizaje automático reflejan la evolución natural de la tecnología a medida que


el aumento de la potencia informática permite a las computadoras clasificar grandes conjuntos de
datos y procesar números para identificar patrones y valores atípicos.

—Roca Negra (2019)

Los modelos financieros tienen una larga historia con muchas tareas realizadas con éxito, pero al mismo
tiempo han sido duramente criticados debido principalmente a la falta de flexibilidad y la falta de inclusión
de estos modelos. La crisis financiera de 2007­2008 alimentó este debate y allanó el camino para innovaciones
y diferentes enfoques en el campo de la modelización financiera.

Por supuesto, esta crisis financiera no es la mera razón que precipita el crecimiento de las aplicaciones
de IA en las finanzas, sino que también hay otros dos factores principales que han estimulado la
adopción de la IA en las finanzas. Dicho esto, la disponibilidad de datos ha mejorado la potencia
informática e intensificado las investigaciones en la década de 1990.

El Consejo de Estabilidad Financiera (2017) enfatiza la validez de este hecho al afirmar:

“Ya existen muchas aplicaciones, o “casos” de uso, de la IA y el aprendizaje automático. La


adopción de estos casos de uso ha sido impulsada tanto por factores de oferta, como los avances
tecnológicos y la disponibilidad de datos e infraestructura del sector financiero, como por factores de
demanda, como las necesidades de rentabilidad, la competencia con otras empresas y las exigencias de
la regulación financiera. "

—FSB

Como subrama del modelado financiero, la gestión de riesgos financieros ha ido evolucionando con la
adopción de la IA en paralelo con un papel cada vez mayor en el proceso de toma de decisiones
financieras. En su célebre libro, Bostrom (2014) denota que existen dos revoluciones importantes en la
historia de la humanidad: la Revolución Agrícola y la Revolución Industrial. Estas dos revoluciones
tienen un impacto tan profundo que cualquier tercera revolución de magnitud similar duplicaría el tamaño
de la economía mundial en dos semanas. Aún más sorprendente, si
Machine Translated by Google

Si la tercera revolución se logra mediante la inteligencia artificial, el impacto sería mucho más
profundo.

Por lo tanto, hay grandes expectativas acerca de que las aplicaciones de IA den forma a la
gestión de riesgos financieros a una escala sin precedentes mediante el uso de big
data y la comprensión de la compleja estructura de los procesos de riesgo.

Con este estudio, mi objetivo es llenar el vacío sobre las aplicaciones basadas en
el aprendizaje automático en finanzas para que se pueda mejorar el rendimiento predictivo y
de medición de los modelos financieros. Dado que los modelos paramétricos sufren un
problema de baja varianza y alto sesgo, los modelos de aprendizaje automático, con su
flexibilidad, pueden abordar este problema. Además, como problema común en finanzas,
cambiar la distribución de los datos siempre supone un obstáculo para la viabilidad del
resultado del modelo, pero los modelos de aprendizaje automático pueden adaptarse a este
patrón cambiante de una manera que los modelos se ajusten mejor. Por lo tanto, existe una
gran necesidad y demanda sobre los modelos de aprendizaje automático aplicables en
finanzas y lo que distingue principalmente a este libro es la inclusión de nuevos enfoques de
modelado basados en el aprendizaje automático en la gestión de riesgos financieros.

En pocas palabras, este libro pretende cambiar el panorama actual de la gestión de riesgos
financieros, que se basa en gran medida en modelos paramétricos. La principal motivación
para este cambio es la experiencia reciente en modelos financieros de alta precisión basados
en modelos de Machine Learning. Por lo tanto, este libro está destinado a aquellos que tienen
algunas ideas iniciales sobre las finanzas y el aprendizaje automático, en el sentido de que
solo proporciono breves explicaciones sobre estos temas.

En consecuencia, el público objetivo del libro incluye, entre otros, analistas de riesgos
financieros, ingenieros financieros, asociados de riesgos, modeladores de riesgos, validadores
de modelos, analistas de riesgos cuantitativos, analistas de carteras y aquellos interesados
en las finanzas y la ciencia de datos.

A la luz de los antecedentes de la audiencia objetivo, tener un nivel introductorio de conocimientos


sobre finanzas y ciencia de datos le permitirá obtener el mayor beneficio que puede obtener del
libro. Sin embargo, esto no significa que personas de diferentes orígenes no puedan
seguir los temas de este libro. Más bien, lectores de diferentes orígenes pueden captar los
conceptos siempre que inviertan suficiente
Machine Translated by Google

tiempo y consulte otros libros sobre finanzas y ciencia de datos junto con este
uno.

El libro consta de diez capítulos.

Capítulo 1

Ofrece una introducción sobre los principales conceptos de gestión de riesgos.


Entonces, cubre riesgos, tipos de riesgos como mercado, crédito, operativo, liquidez,
gestión de riesgos. Después de definir cuál es el riesgo, se analizan los tipos de
riesgos y luego se explica la gestión de riesgos y se abordan las cuestiones de por qué es
importante y cómo se puede utilizar para mitigar las pérdidas. A continuación se analiza
la información asimétrica que puede abordar las fallas del mercado. Para ello, nos
centraremos en la asimetría de la información y la selección adversa.

Capitulo 2

Muestra las aplicaciones de series de tiempo que utilizan modelos tradicionales, a


saber, el modelo de media móvil, el modelo autorregresivo y el modelo de media móvil
integrado autorregresivo. En esta parte, aprendemos cómo utilizar una API para acceder a
datos financieros y cómo emplearla. El objetivo principal de este capítulo es proporcionarnos
un punto de referencia para comparar el enfoque tradicional de series de tiempo con el
desarrollo reciente en el modelado de series de tiempo, que es el enfoque principal del
próximo capítulo.

Capítulo 3

Presenta las herramientas de aprendizaje profundo para el modelado de series


temporales. La red neuronal recurrente y la memoria a corto plazo son dos enfoques
mediante los cuales podemos modelar los datos con dimensión temporal. Además, este
capítulo nos da una idea de la aplicabilidad de los modelos de aprendizaje profundo al
modelado de series de tiempo.

Capítulo 4

Se centra en la predicción de la volatilidad. La mayor integración de los mercados


financieros ha provocado una incertidumbre prolongada en los mercados financieros, que en
Machine Translated by Google

A su vez destaca la importancia de la volatilidad. La volatilidad se utiliza para medir


el grado de riesgo, que es uno de los principales compromisos del área de las
finanzas. El cuarto capítulo trata sobre el novedoso modelado de volatilidad
basado en la regresión de vectores de soporte, la red neuronal, el aprendizaje
profundo y el enfoque bayesiano. Para comparar las prestaciones, también se
emplean los modelos tradicionales de tipo ARCH y GARCH.

Capítulo 5

Emplea modelos basados en aprendizaje automático para mejorar el


rendimiento de la estimación de los modelos tradicionales de riesgo de mercado, a
saber, valor en riesgo (VaR) y déficit esperado (ES). El VaR es un enfoque
cuantitativo para la pérdida potencial de valor razonable debido a movimientos del
mercado que no se superará en un período de tiempo definido y con un nivel
de confianza definido. El déficit esperado, por otro lado, se centra en la cola de
la distribución y se refiere a pérdidas grandes e inesperadas. El modelo
VaR se desarrolla utilizando una matriz de covarianza sin ruido y ES se
desarrolla incorporando la dimensión de liquidez de los datos.

Capítulo 6

Intenta introducir un enfoque integral basado en el aprendizaje automático para


estimar el riesgo crediticio. Los modelos de Machine Learning se aplican en base a
la información crediticia anterior junto con otros. El enfoque comienza con la
clasificación de riesgos, sugerida por el Acuerdo de Basilea, y continúa con
diferentes modelos de estimación bayesiana, modelo de cadena de Markov,
clasificación de vectores de soporte, bosque aleatorio, red neuronal y aprendizaje profundo.
En la última parte del capítulo, se comparará el rendimiento de estos modelos.

Capítulo 7

El modelo de mezcla gaussiana se utiliza para modelar la liquidez, que se cree que
es una dimensión descuidada en la gestión de riesgos. Este modelo nos permite
incorporar diferentes aspectos de los indicadores de liquidez en este capítulo para que
Machine Translated by Google

que seremos capaces de captar el efecto de la liquidez sobre el riesgo financiero de una
manera más sólida.

Capítulo 8

Cubre el riesgo operativo, que puede resultar en una falla debido principalmente a
debilidad interna de la empresa. Existen varias fuentes de riesgos operativos, pero el
riesgo de fraude es uno de los que consume más tiempo y es más perjudicial para las
operaciones de la empresa. Aquí, en este capítulo, el fraude será nuestro enfoque
principal y se desarrollarán nuevos enfoques para tener una aplicación de fraude
de mejor rendimiento basada en modelos de aprendizaje automático.

Capítulo 9

Introduce un enfoque completamente nuevo en la modelización del riesgo de gobierno


corporativo: la caída del precio de las acciones. Muchos estudios encuentran un vínculo
empírico entre la caída del precio de las acciones y el gobierno corporativo. Este
capítulo, utilizando el modelo del Determinante de Covarianza Mínima, intenta
revelar la relación entre los componentes del riesgo de gobierno corporativo y la caída
del precio de las acciones.

Capítulo 10

Hace uso de datos sintéticos para estimar diferentes riesgos financieros. El objetivo de este
capítulo es resaltar el surgimiento de datos sintéticos que nos ayudan a minimizar el impacto
de los datos históricos limitados. Entonces, los datos sintéticos nos permiten tener
datos suficientemente grandes y de alta calidad, lo que mejora la calidad del modelo.
Machine Translated by Google

Parte I. Fundamentos de
Gestión de Riesgos
Machine Translated by Google

Capítulo 1. Fundamentos de la Gestión


de Riesgos

UNA NOTA PARA LOS LECTORES DE PUBLICACIÓN ANTICIPADA

Con los libros electrónicos de lanzamiento anticipado, obtiene libros en su forma más
antigua (el contenido sin editar y sin editar del autor mientras escribe) para que pueda
aprovechar estas tecnologías mucho antes del lanzamiento oficial de estos títulos.

Este será el primer capítulo del libro final. Tenga en cuenta que el repositorio de GitHub se
activará más adelante.

Si tiene comentarios sobre cómo podríamos mejorar el contenido y/


o los ejemplos de este libro, o si nota que falta material en este
capítulo, comuníquese con el editor en [email protected].

En 2007, nadie hubiera pensado que las funciones de riesgo podrían haber cambiado
tanto como lo han hecho en los últimos ocho años. Es una tentación natural esperar que la
próxima década contenga menos cambios.
Sin embargo, creemos que probablemente ocurrirá lo contrario.

—Harle et al. (2016)

La gestión de riesgos es un proceso en constante evolución. La evolución constante es


inevitable debido al hecho de que las prácticas de gestión de riesgos de larga data no pueden seguir
el ritmo de los desarrollos recientes ni ser precursoras de las crisis en desarrollo.
Por lo tanto, es importante monitorear y adoptar los cambios traídos por rupturas estructurales
en un proceso de gestión de riesgos. La adopción de los cambios implica redefinir los
componentes y herramientas de la gestión de riesgos y de eso se trata este libro.

Tradicionalmente, en finanzas, la investigación empírica en finanzas se ha centrado fuertemente en


la inferencia estadística. La econometría se ha construido sobre el fundamento de
Machine Translated by Google

inferencia estadística. Estos tipos de modelos se concentran en la estructura del proceso de


generación de datos subyacente y la relación entre variables.
Sin embargo, no se supone que los modelos de aprendizaje automático definan el proceso
subyacente de generación de datos, sino que se consideran un medio para lograr un fin
con fines de predicción (Lommers et al. 2021). Por lo tanto, los modelos de aprendizaje automático
tienden a estar más centrados en los datos y orientados a la precisión de la predicción.

Además, la escasez e indisponibilidad de datos siempre ha sido un problema en las


finanzas y no es difícil adivinar que los modelos econométricos no pueden funcionar
bien en este caso. Dada la solución de los modelos de aprendizaje automático a la falta de
disponibilidad de datos mediante la generación de datos sintéticos, los modelos de aprendizaje
automático han estado en la cima de la agenda en finanzas y la gestión de riesgos financieros,
por supuesto, no es una excepción.

Antes de entrar en detalles y discutir estas herramientas, vale la pena presentar los principales
conceptos de gestión de riesgos. Así, esta parte del libro presenta conceptos básicos de gestión
de riesgos financieros, a los que me referiré a lo largo del libro. Estos conceptos incluyen
riesgo, tipos de riesgos, gestión de riesgos, rendimientos y algunos conceptos relacionados con
la gestión de riesgos.

Riesgo

El riesgo siempre está presente durante el curso de la vida, pero comprenderlo y evaluarlo
es un poco más difícil que conocerlo debido a su naturaleza abstracta. El riesgo se percibe como
algo peligroso y puede presentarse en forma esperada o inesperada. El riesgo esperado es algo
que se tiene en cuenta, pero el riesgo inesperado apenas puede contabilizarse, por
lo que podría ser devastador.

Como puedes imaginar, no existe un consenso general sobre la definición de riesgo.


Sin embargo, desde el punto de vista financiero, el riesgo se refiere a una posible pérdida
probable o al nivel de incertidumbre al que puede exponerse una empresa. De manera
diferente, McNeil et al. (2015) definen el riesgo como:
Machine Translated by Google

Cualquier evento o acción que pueda afectar negativamente la capacidad de una organización
para lograr sus objetivos y ejecutar sus estrategias o, alternativamente, la probabilidad
cuantificable de pérdida o retornos menores a los esperados.

—Harle et al. (2016)

Estas definiciones se centran en el lado negativo del riesgo, lo que implica que el costo va de la
mano con el riesgo, pero también cabe señalar que no existe necesariamente una relación uno a
uno entre ellos. Por ejemplo, si se espera un riesgo, el costo incurrido es relativamente menor (o
incluso ignorable) que el del riesgo inesperado.

Devolver
Todas las inversiones financieras se realizan para obtener beneficios, lo que también se denomina
rentabilidad. Más formalmente, el rendimiento es la ganancia obtenida por una inversión en un
período de tiempo determinado. Por tanto, el rendimiento se refiere al lado positivo del riesgo. A
lo largo del libro, riesgo y rendimiento se referirán al riesgo a la baja y al alza, respectivamente.

Como se puede imaginar, existe una compensación entre riesgo y rendimiento: cuanto mayor
sea el riesgo asumido, mayor será el rendimiento obtenido. Dado que encontrar una solución
óptima es una tarea formidable, esta compensación es una de las cuestiones más
controvertidas en el ámbito financiero. Sin embargo, Markowitz (1952) propone una solución
intuitiva y atractiva a este problema de larga data. La forma en que definió el riesgo, que
hasta entonces era ambigua, es agradable y clara y condujo a un cambio en el panorama de la
investigación financiera. Markowitz (1952) utilizó la desviación estándar σRi para cuantificar el
riesgo. Esta definición intuitiva permite a los investigadores utilizar las matemáticas y la estadística
en las finanzas. La desviación estándar se puede definir matemáticamente como (Hull, 2012):

σ = √E(R2) − [E(R)] 2

donde los símbolos R y E se refieren al rendimiento anual y a la expectativa, respectivamente.


El libro utiliza el símbolo E numerosas veces ya que el rendimiento esperado representa el
rendimiento del interés. Esto se debe a que al definir el riesgo hablamos de probabilidad.
Cuando se trata de la variación de la cartera, la covarianza entra en escena y la fórmula resulta ser:
Machine Translated by Google

2 2
2 = w aσa 2 + w bσ b + 2wawbCov(ra, rb)
2σp _ _

2 es la varianza y Cov es la matriz de covarianza.


donde w denota peso, σ
Sacar la raíz cuadrada de la varianza obtenida anteriormente nos da la desviación estándar
de la cartera:

σp = √σ2 pag

En otras palabras, el rendimiento esperado de la cartera es un promedio ponderado de los


rendimientos individuales y se puede mostrar como:

E(R) = ∑n wiRi
i = w1R1 + w2R2 + wnRn
Exploremos la relación riesgo­retorno mediante visualización. Para ello, se construye una
cartera hipotética para calcular las estadísticas necesarias con Python.

En [1]: importar statsmodels.api como sm


importar numpy como
np importar plotly.graph_objs como
ir importar matplotlib.pyplot como plt
importar plotly
importar
advertencias advertencias.filterwarnings('ignorar')

En [2]: n_activos = 5
n_simulación = 500

En [3]: devuelve = np.random.randn(n_activos, n_simulación)

En [4]: rand = np.random.rand(n_assets)


pesos = rand/suma(rand)

def port_return(devoluciones):
rets = np.mean(devoluciones, eje=1)
cov = np.cov(rets.T, aweights=weights, ddof=1)
portfolio_returns = np.dot(weights, rets.T)
portfolio_std_dev = np.sqrt(np.dot(pesos, np.dot(cov, pesos))) retorno
portfolio_returns, portfolio_std_dev

En [5]: portfolio_returns, portfolio_std_dev = port_return(devoluciones)


Machine Translated by Google

En [6]: imprimir(portfolio_returns)
imprimir(portfolio_std_dev)
0.005773455631074148
0.016994274496417057

En [7]: cartera = np.array([port_return(np.random.randn(n_assets, i)) para i en rango(1,


101)])

En [8]: best_fit = sm.OLS(cartera[:, 1], sm.add_constant(cartera[:, 0]))\ .fit().fittedvalues

En [9]: fig = go.Figura()


fig.add_trace(go.Scatter(name=' Relación Riesgo­Retorno', x=portfolio[:,0],
y=cartera[:,1], modo='marcadores'))
fig.add_trace(go.Scatter(nombre=' Línea de mejor ajuste', x=portfolio[:,0],
y=mejor_ajuste, modo='líneas'))
fig.update_layout(xaxis_title = 'Retorno', yaxis_title = 'Desviación estándar',

ancho=900, alto=470)
plotly.offline.iplot(fig, filename="images/risk_return.png") fig.show()

Número de activos considerados

Número de simulaciones realizadas

Generar muestras aleatorias a partir de una distribución normal utilizadas como rendimientos.

Generando números aleatorios para calcular pesos.

Calcular pesos

Función utilizada para calcular el rendimiento esperado de la cartera y la desviación


estándar de la cartera.

Llamar al resultado de la función.

Imprimir el resultado del rendimiento esperado de la cartera y la desviación estándar de la


cartera
Machine Translated by Google

Volver a ejecutar la función 100 veces

Para dibujar la línea de mejor ajuste, ejecuto una regresión lineal

Dibujar un diagrama interactivo con fines de visualización.


Machine Translated by Google

Figura 1­1. Relación Riesgo­Retorno

La Figura 1­1, generada mediante el código Python anterior, confirma que el


riesgo y el rendimiento van en conjunto, pero la magnitud de esta
correlación varía según la acción individual y las condiciones del mercado financiero.
Machine Translated by Google

Gestión de riesgos
La gestión del riesgo financiero es un proceso para hacer frente a las incertidumbres
resultantes de los mercados financieros. Implica evaluar los riesgos financieros que
enfrenta una organización y desarrollar estrategias de gestión consistentes con las prioridades
y políticas internas (Horcher, 2011).

Según esta definición, como cada organización enfrenta diferentes tipos de riesgos, la
forma en que una empresa los aborda es completamente única. Toda empresa debe
evaluar adecuadamente y tomar las medidas necesarias contra el riesgo. Sin embargo,
esto no significa necesariamente que una vez que se identifica un riesgo, deba mitigarse tanto
como pueda hacerlo una empresa.

Por lo tanto, la gestión de riesgos no consiste en mitigarlos a toda costa.


Mitigar el riesgo puede requerir sacrificar el rendimiento y puede ser tolerable hasta cierto
nivel, ya que las empresas buscan tanto un mayor rendimiento como una reducción
del riesgo. Por lo tanto, maximizar las ganancias y al mismo tiempo reducir el riesgo
debería ser una tarea delicada y bien definida.

Gestionar el riesgo es una tarea delicada, tiene un coste y, aunque afrontarlo requiere
políticas empresariales específicas, existe un marco general para posibles estrategias de
riesgo. Estos son:

Ignorar: En esta estrategia las empresas aceptan todos los riesgos y sus
consecuencias y prefieren no hacer nada.

Transferencia: esta estrategia implica transferir los riesgos a un tercero


mediante cobertura o alguna otra forma.

Mitigar: Las empresas desarrollan una estrategia para mitigar el riesgo en


parte porque su efecto dañino podría considerarse demasiado para soportar y/
o suprimir el beneficio que conlleva.

Aceptar el riesgo: si las empresas adoptan la estrategia de aceptar el riesgo,


identifican adecuadamente los riesgos y reconocen el beneficio de ellos. En
otras palabras, cuando asumir ciertos riesgos derivados de algunas actividades
aporta valor al accionista, se puede optar por esta estrategia.
Machine Translated by Google

Principales riesgos financieros

Las empresas financieras se enfrentan a diversos riesgos a lo largo de su vida empresarial. Estos
riesgos se pueden dividir en diferentes categorías para identificarlos y evaluarlos de manera más sencilla.
Estos principales tipos de riesgo financiero son el riesgo de mercado, el riesgo de crédito, el riesgo
operativo y el riesgo de liquidez, pero nuevamente esta no es una lista exhaustiva.
Sin embargo, limitamos nuestra atención a los principales tipos de riesgos financieros a lo largo del libro.
Echemos un vistazo a estas categorías de riesgo.

Riesgo de mercado

Este riesgo surge debido a un cambio de factores en el mercado financiero. Para ser más claro, por
ejemplo, un aumento en la tasa de interés podría afectar negativamente a una empresa que tiene una
posición corta.

Se puede dar un segundo ejemplo sobre otra fuente de riesgo de mercado; tipo de cambio.
Una empresa que participa en el comercio internacional, cuyos productos básicos se cotizan en dólares
estadounidenses, está muy expuesta a un cambio en dólares estadounidenses.

Como se puede imaginar, cualquier cambio en el precio de las materias primas podría representar una
amenaza para la sostenibilidad financiera de una empresa. Hay muchos factores fundamentales que
tienen un efecto directo sobre el precio de las materias primas, que son los actores del mercado, los
costos de transporte, etc.

Riesgo crediticio

El riesgo de crédito es uno de los riesgos más generalizados. El riesgo crediticio surge cuando la
contraparte no cumple con la deuda. Por ejemplo, si un prestatario no puede pagar su pago, se realiza el
riesgo crediticio. El deterioro de la calidad crediticia también es una fuente de riesgo a través de la
reducción del valor de mercado de los valores que una organización podría poseer (Horcher,
2011).

Riesgo de liquidez El

riesgo de liquidez se ha pasado por alto hasta la crisis financiera de 2007­2008, que afectó duramente
al mercado financiero. A partir de entonces se intensificaron las investigaciones sobre el riesgo de
liquidez. La liquidez se refiere a la velocidad y facilidad con la que un
Machine Translated by Google

El inversionista ejecuta su transacción. Esta definición también se conoce como riesgo de


liquidez comercial. La otra dimensión del riesgo de liquidez es el riesgo de liquidez de
financiación, que puede definirse como la capacidad de obtener efectivo o la disponibilidad de
crédito para financiar las operaciones de una empresa.

Si una empresa no puede convertir sus activos en efectivo en un corto período de tiempo,
entra en la categoría de riesgo de liquidez y es bastante perjudicial para la gestión
financiera y la reputación de la empresa.

Riesgo operacional

La gestión del riesgo operativo va más allá de ser una tarea clara y previsible y explota una gran
cantidad de recursos de una empresa debido a la naturaleza compleja e interna del riesgo.
Ahora las preguntas son: ¿Cómo hacen las empresas financieras un buen trabajo para gestionar
el riesgo? ¿Asignan recursos necesarios para esta tarea? ¿Se mide adecuadamente la
importancia del riesgo para la sostenibilidad de una empresa?

Como sugiere el nombre, el riesgo operativo surge cuando las operaciones inherentes a una
empresa o industria representan una amenaza para las operaciones diarias, la rentabilidad o la
sostenibilidad de esa empresa. El riesgo operativo incluye actividades fraudulentas, incumplimiento
de regulaciones o procedimientos internos, pérdidas por falta de capacitación, etc.

Bueno, ¿qué pasa si una empresa se expone a uno o más de uno de estos riesgos sin estar
preparada? Aunque no es frecuente, conocemos la respuesta por los acontecimientos
históricos, la empresa podría incumplir y toparse con un gran cuello de botella financiero.

Gran colapso financiero ¿Qué

importancia tiene la gestión de riesgos? Esta cuestión puede abordarse en un libro de cientos de
páginas pero, de hecho, el aumento de la gestión de riesgos en las instituciones financieras
habla por sí solo. En particular, después de la crisis financiera global, la gestión de riesgos
se caracteriza como un “fracaso colosal de la gestión de riesgos” (Buchholtz y Wiggins,
2019). De hecho, la crisis financiera mundial que surgió en 2007­2008 es sólo la punta del
iceberg. Numerosos fracasos
Machine Translated by Google

en la gestión de riesgos allanan el camino para este colapso del sistema financiero.
Para comprender este colapso, debemos volver a profundizar en los fracasos pasados de la
gestión de riesgos financieros. Un fondo de cobertura llamado Long­Term Capital
Management (LTCM) presenta un ejemplo vívido de colapso financiero.

LCTM forma un equipo con académicos y profesionales de primer nivel. Esto provocó una
entrada de fondos a la empresa y comenzó a cotizar con mil millones de dólares. En 1998,
LCTM controlaba más de 100 mil millones de dólares e invirtió fuertemente en algunos
mercados emergentes, incluida Rusia. Así, el impago de la deuda rusa afectó
1 hacia la calidad y recibió un duro golpe,
profundamente a la cartera de LCTM debido a su fuga
lo que llevó a LCTM a la quiebra (Allen, 2003).

Metallgesellschaft (MG) es otra empresa que ya no existe debido a una mala gestión de los
riesgos financieros. MG operaba principalmente en los mercados del gas y el petróleo.
Debido a la alta exposición a los precios del gas y el petróleo, MG necesitaba fondos
tras la gran caída de los precios del gas y el petróleo. El cierre de la posición corta generó
pérdidas de alrededor de 1,5 mil millones de dólares.

Amaranth Advisors (AA) es otro fondo de cobertura que quebró debido a sus fuertes inversiones
en un mercado único y a no evaluar correctamente los riesgos derivados de sus inversiones.
En 2006, AA atrajo aproximadamente 9 mil millones de dólares en activos bajo administración,
pero perdió casi la mitad debido a la caída de los futuros y opciones del gas natural. El
incumplimiento de AA se atribuye a los bajos precios del gas natural y a modelos de riesgo
engañosos (Chincarini, 2008).

En pocas palabras, el artículo de Stulz titulado "Fallos en la gestión de riesgos: ¿qué son y
cuándo suceden?" (2008) resumen las principales fallas en la gestión de riesgos
que resultan en incumplimiento:

1) Medición errónea de riesgos conocidos

2) No tener en cuenta los riesgos

3) Falla en comunicar los riesgos a la alta dirección

4) Fallo en el seguimiento de riesgos

5) Fracaso en la gestión de riesgos

6) No utilizar métricas de riesgo adecuadas


Machine Translated by Google

Por lo tanto, la crisis financiera global no fue el único evento que llevó a los reguladores e instituciones a
rediseñar su gestión de riesgos financieros. Más bien, es la gota que llenó el vaso y, tras la crisis,
tanto los reguladores como las instituciones adoptaron las lecciones aprendidas y mejoraron sus
procesos.
Con el tiempo, esta serie de acontecimientos condujo a un aumento en la gestión del riesgo financiero.

Asimetría de información en la gestión de riesgos financieros Aunque teóricamente es intuitiva,

la suposición de que un

tomador de decisiones es completamente racional, principal piedra angular de la teoría financiera


moderna, es demasiado perfecta para ser real. Esta idea, por tanto, es atacada por los economistas
conductuales, que creen que la psicología desempeña un papel clave en el proceso de toma de
decisiones.

Tomar decisiones es como hablar en prosa: la gente lo hace todo el tiempo, a sabiendas o
sin saberlo. No sorprende, entonces, que el tema de la toma de decisiones sea compartido por
muchas disciplinas, desde las matemáticas y la estadística, pasando por la economía y las
ciencias políticas, hasta la sociología y la psicología.

—Kahneman y Tversky (1984)

La asimetría de la información y la gestión del riesgo financiero van de la mano, ya que el costo de
financiación y la valoración de las empresas se ven profundamente afectados por la asimetría de la
información. Es decir, la incertidumbre en la valoración de los activos de una empresa podría aumentar
el costo de endeudamiento, lo que representa una amenaza para la sostenibilidad de una empresa
(véanse DeMarzo y Darrell (1995) y Froot, Scharfstein y Stein (1993)).

Por lo tanto, las raíces de los fracasos descritos anteriormente son más profundas, de tal manera
que el mundo hipotético perfecto en el que vive el tomador de decisiones racional es incapaz de
explicarlos. En este punto entran en juego los instintos humanos y el mundo imperfecto y una mezcla de
disciplinas proporciona justificaciones más plausibles. Entonces, resulta que la selección adversa y el
riesgo moral son dos categorías destacadas que explican las fallas del mercado.

Selección adversa
Machine Translated by Google

Es un tipo de información asimétrica en la que una parte intenta explotar su ventaja informativa.
La selección adversa surge cuando el vendedor está mejor informado que los compradores.
Este fenómeno está perfectamente acuñado por Akerlof (1970) como “Los mercados de los
limones”. En este marco, los limones se consideran de baja calidad.

Considere un mercado con limón y automóviles de alta calidad y los compradores saben que es
probable que compren un limón, lo que reduce el precio de equilibrio. Sin embargo, el vendedor
estará mejor informado si el coche es limón o de alta calidad. Entonces, en esta situación,
el beneficio del intercambio podría desaparecer y no se realizará ninguna transacción.

Debido a su complejidad y opacidad, el mercado hipotecario en la era anterior a la crisis es un buen


ejemplo de selección adversa. Más concretamente, los prestatarios sabían más que los
prestamistas sobre su voluntad y capacidad de pago. El riesgo financiero se creó mediante las
titulizaciones de los préstamos, es decir, valores respaldados por hipotecas. A partir de ese
momento, los originadores de los préstamos hipotecarios sabían más sobre los riesgos que las
personas que los vendían a los inversores en los valores respaldados por hipotecas.

Intentemos modelar la selección adversa usando Python. Es fácilmente observable en la industria de


seguros y, por lo tanto, me gustaría centrarme en esta industria para modelar la selección
adversa.

Supongamos que la función de utilidad del consumidor es:

U(x) = miγx

donde x es el ingreso y γ es un parámetro, que toma valores entre 0 y 1.

NOTA
La función de utilidad es una herramienta que se utiliza para representar las preferencias de los consumidores por bienes y
servicios y es cóncava para personas con aversión al riesgo.
Machine Translated by Google

El objetivo final de este ejemplo es decidir si se compra o no un seguro en


función de la utilidad del consumidor.

Para practicar, asumo que el ingreso es de $2 USD y el costo del accidente es de $1,5
USD.

Ahora es el momento de calcular la probabilidad de pérdida, π, que está dada


exógenamente y está distribuida uniformemente.

Como último paso, para encontrar el equilibrio, tengo que definir la oferta y la
demanda de cobertura de seguro. El siguiente bloque de código indica cómo podemos
modelar la selección adversa.

En [10]: importar matplotlib.pyplot como plt


importar numpy como
np plt.style.use('seaborn')

En [11]: def utilidad(x):


retorno(np.exp(x ** gamma))

En [12]: pi = np.random.uniform(0,1,20) pi =
np.sort(pi)

En [13]: print('Las tres mayores probabilidades de pérdidas son {}'.format(pi[­3:]))


Las tres probabilidades más altas de pérdidas son [0.73279622 0.82395421
0,88113894]

En [14]: y = 2 c
= 1,5 Q
=5D
= 0,01
gamma = 0,4

En [15]: suministro def (Q):


retorno(np.media(pi[­Q:]) * c)

En [16]: demanda def (D):


return(np.sum(utilidad(y ­ D) > pi * utilidad(y ­ c) + (1 ­ pi) *
utilidad(y)))

En [17]: plt.figura()
plt.plot([demanda(i) para i en np.arange(0, 1.9, 0.02)], np.arange(0, 1.9,
0,02),
'r', etiqueta = 'demanda de seguro')
plt.plot(rango(1,21), [suministro(j) para j en rango(1,21)],
Machine Translated by Google

'g', etiqueta = 'suministro de seguro')


plt.ylabel(" Costo promedio ")
plt.xlabel("Número de personas")
plt.legend()
plt.savefig('images/adverse_selection.png') plt.show()

Escribir una función para la función de utilidad con aversión al riesgo.

Generación de muestras aleatorias a partir de distribución uniforme.

Eligiendo los últimos tres elementos.

Redacción de una función para el suministro de contratos de seguro.

Redacción de una función para la demanda de contratos de seguro.

La figura 1­2 muestra la curva de oferta y demanda de seguros. Sorprendentemente, ambas curvas
tienen pendiente descendente, lo que implica que a medida que más personas exigen el contrato y
más personas se agregan al contrato, el riesgo que afecta el precio del contrato de seguro disminuye.

La línea recta presenta la oferta de seguro y el costo promedio del contrato y la línea, que muestra una
pendiente descendente gradual, denota la demanda de contratos de seguro. A medida que comenzamos
el análisis con los clientes de riesgo, a medida que se pueden agregar más y más personas al contrato, el
nivel de riesgo disminuye en paralelo con el costo promedio.
Machine Translated by Google

Figura 1­2. Selección adversa

Riesgo moral

Las fallas del mercado también son el resultado de información asimétrica. En una
situación de riesgo moral, una de las partes del contrato asume más riesgo que la otra.
Formalmente, el riesgo moral puede definirse como una situación en la que
una parte más informada se aprovecha de la información privada a su disposición en
detrimento de otros.

Para comprender mejor el riesgo moral, se puede dar un ejemplo sencillo del mercado
crediticio: supongamos que la entidad A exige crédito para utilizarlo en la
financiación del proyecto, que se considera factible de financiar. El riesgo moral
surge si la entidad A utiliza el préstamo para el pago de la deuda crediticia al banco
C, sin previo aviso al banco prestamista. Al asignar crédito, la situación de riesgo moral
que pueden encontrar los bancos surge como resultado de la información
asimétrica, disminuye el apetito crediticio de los bancos y aparece como una de las
razones por las que los bancos ponen tanto trabajo en el proceso de asignación de crédito.
Machine Translated by Google

Algunos argumentan que la operación de rescate emprendida por la FED para LCTM
puede considerarse un riesgo moral en el sentido de que la FED celebra contratos de
mala fe.

Conclusión
Este capítulo presenta los principales conceptos de la gestión de riesgos financieros con el
fin de garantizar que todos estemos en la misma página. Este repaso nos ayuda mucho a lo
largo de este libro porque utilizamos estos términos y conceptos.

Además de eso, en la última parte del primer capítulo se analiza un enfoque conductual,
que ataca la lógica de un agente financiero, de modo que tengamos herramientas más
amplias para dar cuenta de las fuentes de riesgo financiero.

En el próximo capítulo, discutiremos el enfoque de series de tiempo, que es uno de los


principales pilares del análisis financiero en el sentido de que la mayoría de los datos
financieros tienen una dimensión temporal que requiere especial atención y técnica para
manejarlos.

Recursos adicionales
Artículos citados en este capítulo:

Akerlof, George A. "El mercado de los" limones ": incertidumbre sobre la calidad
y el mecanismo del mercado". En Incertidumbre en economía, págs. 235­251.
Academic Press, 1978.

Buchholtz, Alec y Rosalind Z. Wiggins. "Lecciones aprendidas: Thomas


C. Baxter, Jr., Esq". Revista de crisis financieras 1, no. 1 (2019): 202­204.

Chincarini, Ludwig. "Un estudio de caso sobre gestión de riesgos: lecciones


del colapso de Amaranth Advisors LLC". Revista de Finanzas Aplicadas 18,
no. 1 (2008): 152­74.
Machine Translated by Google

DeMarzo, Peter M. y Darrell Duffie. "Incentivos corporativos para coberturas y


contabilidad de coberturas". La revisión de estudios financieros 8, núm. 3
(1995): 743­771.

Froot, Kenneth A., David S. Scharfstein y Jeremy C. Stein. “Gestión de riesgos:


coordinación de las políticas corporativas de inversión y financiación”. El
Diario de Finanzas 48, no. 5 (1993): 1629­1658.

Lommers, Kristof, Ouns El Harzli y Jack Kim. "Enfrentando el aprendizaje


automático con la investigación financiera". Disponible en SSRN 3788349
(2021).

Stulz, René M. "Fallos en la gestión de riesgos: ¿qué son y cuándo ocurren?"


Revista de Finanzas Corporativas Aplicadas 20, no. 4 (2008): 39­48.

Libros citados en este capítulo:

Horcher, Karen A. Fundamentos de la gestión de riesgos financieros. vol. 32.


John Wiley e hijos, 2011.

Casco, Juan. Gestión de riesgos e instituciones financieras,+ Sitio Web.


vol. 733. John Wiley e hijos, 2012.

Kahneman, D. y A. Tversky. “Elecciones, valores y marcos.


Asociacion Americana de Psicologia." (1984): 341­350.

Harle, P., Havas, A. y Samandari, H. (2016). El futuro de la gestión de riesgos


bancarios. Instituto Global McKinsey.

McNeil, Alexander J., Rüdiger Frey y Paul Embrechts.


Gestión cuantitativa de riesgos: conceptos, técnicas y herramientas­
edición revisada. Prensa de la Universidad de Princeton, 2015.

1 El término huida hacia la calidad se refiere a un comportamiento gregario mediante el cual los inversores se mantienen alejados de activos
riesgosos, como las acciones, y toman posiciones largas en activos más seguros, como los bonos emitidos por el gobierno.
Machine Translated by Google

Capítulo 2. Introducción al modelado de series


temporales

UNA NOTA PARA LOS LECTORES DE PUBLICACIÓN ANTICIPADA

Con los libros electrónicos de lanzamiento anticipado, obtiene libros en su forma más antigua (el
contenido sin editar y sin editar del autor mientras escribe) para que pueda aprovechar estas
tecnologías mucho antes del lanzamiento oficial de estos títulos.

Este será el segundo capítulo del libro final. Tenga en cuenta que el repositorio de GitHub se
activará más adelante.

Si tiene comentarios sobre cómo podríamos mejorar el contenido y/


o los ejemplos de este libro, o si nota que falta material en este capítulo,
comuníquese con el editor en [email protected].

El comportamiento del mercado se examina utilizando grandes cantidades de datos pasados, como
cotizaciones de divisas o precios de acciones de alta frecuencia. Es la abundancia de datos lo que hace
posible el estudio empírico del mercado. Aunque no es posible realizar experimentos controlados, es
posible realizar pruebas exhaustivas con datos históricos.

­ Henri Poincaré

Algunos modelos explican mejor algunos fenómenos, ciertos enfoques capturan las características de un
evento de manera sólida. El modelado de series de tiempo es un claro ejemplo de esto porque
la gran mayoría de los datos financieros tienen una dimensión temporal, lo que hace que las
aplicaciones de series de tiempo sean una herramienta necesaria para las finanzas. En términos
simples, el orden de los datos y la correlación entre ellos es importante.

En este capítulo del libro, se analizarán los modelos clásicos de series de tiempo y se comparará el
rendimiento de estos modelos. Además de eso, el análisis de series de tiempo basado en aprendizaje
profundo se introducirá en [Link to Come], que tiene un enfoque completamente diferente en términos
de preparación de datos y estructura del modelo. Los modelos clásicos que se visitarán incluyen el
modelo de media móvil (MA), el modelo autorregresivo (AR) y, finalmente, el modelo de
media móvil integrada autorregresiva.
Machine Translated by Google

modelo (ARIMA). Lo que es común entre estos modelos es la información contenida en las
observaciones históricas. Si estas observaciones históricas se obtienen a partir de términos
de error, se denomina media móvil; si estas observaciones provienen de la propia serie
temporal, resulta ser autorregresiva. El otro modelo, ARIMA, es una extensión de estos modelos.

Aquí hay una definición formal de serie de tiempo:

Una serie de tiempo es un conjunto de observacionesXt , cada una de las cuales se registra
en un tiempo específico t. Una serie de tiempo discreta (el tipo al que está dedicado
principalmente este libro) es aquella en la que el conjunto T0 de tiempos en los que se realizan las
observaciones es un conjunto discreto, como es el caso, por ejemplo, cuando las observaciones
se realizan en tiempos fijos. intervalos de tiempo. Las series de tiempo continuas se obtienen
cuando las observaciones se registran continuamente durante algún intervalo de tiempo.

—Brockwell y Davis (2016)

Observemos cómo se ven los datos con dimensión temporal. La Figura 2­1 muestra los precios del
petróleo para el período 1980­2020 y el siguiente código Python nos muestra una forma de producir
este gráfico.

En [1]: importar quandl


importar matplotlib.pyplot como plt
importar
advertencias
advertencias.filterwarnings('ignorar') plt.style.use('seaborn')

En [2]: aceite = quandl.get("NSE/OIL", authtoken="vEjGTysiCFBuN­z5bjGP",


fecha_inicial="1980­01­01",
fecha_final="2020­01­01")

En [3]: plt.figure(figsize=(10, 6))


plt.plot(oil.Close)
plt.ylabel('$')
plt.xlabel('Fecha')
plt.savefig('images/Oil_Price. png')
plt.mostrar()

Extracción de datos de la base de datos Quandl


Machine Translated by Google

Figura 2­1. Precio del petróleo entre 1980­2020

NOTA
Una API, o interfaz de programación de aplicaciones, es una herramienta diseñada para recuperar datos mediante código.
Usaremos diferentes API a lo largo del libro. En la práctica anterior, se utiliza la API de Quandl .

La API de Quandl nos permite acceder a datos financieros, económicos y alternativos desde el sitio web de Quandl .
Para tener su API de Qnadl, visite el sitio web de Quanld Primero y obtenga su propia clave API siguiendo los pasos
necesarios.

Como se puede entender de la definición proporcionada anteriormente, los modelos de series de


tiempo pueden ser aplicables a diversas áreas como:

Cuidado de la salud

Finanzas

Ciencias económicas

Análisis de red
Machine Translated by Google

Astronomía

Clima

La superioridad del enfoque de series de tiempo proviene de la idea de que la correlación de las
observaciones en el tiempo explica mejor el valor actual. Tener datos con una estructura
correlacionada en el tiempo implica una violación de la famosa distribución idéntica e
independiente, para abreviar el supuesto IID, que está en el corazón de muchos modelos.

LA DEFINICIÓN DE IID

El supuesto IID nos permite modelar la probabilidad conjunta de los datos como el producto
de la probabilidad de las observaciones. Se dice que el proceso Xt es un IID con media 0 2 y
varianza σ :

Xt IID(0, σ 2)

Entonces, debido a la correlación en el tiempo, la dinámica del precio de las acciones


contemporáneas puede entenderse mejor a partir de sus propios valores históricos. ¿Cómo
podemos comprender la dinámica de los datos? Ésta es una cuestión que podemos abordar
elaborando los componentes de las series temporales.

Componente de serie temporal


Las series de tiempo tienen cuatro componentes: tendencia, estacionalidad, ciclicidad y
residual. En Python, podemos visualizar fácilmente los componentes de una serie de tiempo
mediante la función season_decompose :

En [4]: importar yfinance como yf


importar numpy como
np importar pandas
como pd importar
fecha y hora importar
statsmodels.api como sm desde statsmodels.tsa.stattools
importar adfuller desde statsmodels.tsa.seasonal importar season_decompose

En [5]: ticker = '^GSPC'


inicio = datetime.datetime(2015, 1, 1) end =
datetime.datetime(2021, 1, 1)
SP_prices = yf.download(ticker, inicio=inicio, fin=fin, intervalo='1mo').Cerrar
Machine Translated by Google

[*********************100%************************] 1 de 1 completado

En [6]: season_decompose(SP_prices, period=12).plot() plt.savefig('images/


decomposition.png') plt.show()

Denota el ticker del S&P­500

Identificar las fechas de inicio y finalización.

Accediendo al precio de cierre del S&P­500

En el panel superior de la Figura 2­2, vemos el gráfico de datos sin procesar y en el segundo panel se
puede observar la tendencia que muestra un movimiento ascendente. En el tercer panel se exhibe
la estacionalidad y finalmente se presenta el residual exhibiendo fluctuaciones erráticas. Quizás se
pregunte dónde está el componente cíclico: el ruido y el componente cíclico se juntan en el
componente residual.

Figura 2­2. Descomposición de series temporales del S&P­500

Familiarizarse con los componentes de las series temporales es importante para realizar análisis
posteriores, de modo que podamos comprender las características de los datos y proponer una solución adecuada.
Machine Translated by Google

modelo. Comencemos con el componente de tendencia .

Tendencia

Tendencia indica una tendencia general de aumento o disminución durante un período de tiempo determinado. En
términos generales, la tendencia está presente cuando los puntos inicial y final son diferentes o tienen una
pendiente ascendente o descendente en una serie de tiempo.

En [7]: plt.figure(figsize=(10, 6))


plt.plot(SP_prices)
plt.title(' Precios S&P­500')
plt.ylabel('$')
plt.xlabel('Fecha')
plt.savefig('images/SP_price.png') plt.show()

Aparte del período en el que el precio del índice S&P­500 se desploma, vemos una clara tendencia alcista
en la Figura 2­3 entre 2010 y 2020.

Figura 2­3. Precio del S&P­500


Machine Translated by Google

Trazar un diagrama de líneas no es la mera opción utilizada para comprender la tendencia. Más
bien tenemos alguna otra herramienta poderosa para esta tarea. Entonces, llegados a este punto, vale
la pena hablar de dos conceptos estadísticos importantes:

Función de autocorrelación

Función de autorcorrelación parcial

La función de autocorrelación, conocida como ACF, es una herramienta estadística para


analizar la relación entre el valor actual de una serie temporal y sus valores rezagados.
Graficar ACF nos permite observar fácilmente la dependencia serial en una serie de tiempo.

Cov(Xt, Xt−h)
ρˆ(h) =
Var(Xt)

La Figura 2­4 muestra el gráfico de la función de autocorrelación. Las líneas verticales que se
muestran en la Figura 2­4 representan los coeficientes de correlación, la primera línea denota
la correlación de la serie con su rezago 0, es decir, es la correlación consigo misma. La segunda
línea indica la correlación entre el valor de la serie en el momento t­1 y t. A la luz de esto, podemos

concluir que el S&P­500 muestra una dependencia serial. Parece haber una fuerte dependencia
entre el valor actual y los valores rezagados de los datos del S&P­500 porque los coeficientes de
correlación, representados por líneas en el gráfico ACF, decaen lentamente.

En [8]: sm.graphics.tsa.plot_acf(SP_prices,lags=30)
plt.xlabel('Número de retrasos')
plt.savefig('images/acf_SP.png')
plt.show()

Trazar la función de autocorrelación


Machine Translated by Google

Figura 2­4. Gráfico de función de autocorrelación del S&P­500

Ahora, la pregunta es ¿cuáles serían las posibles fuentes de autocorrelaciones? Aquí


son algunas razones:

La fuente principal de autocorrelación es el "arrastre", lo que significa que la


observación anterior tiene un impacto en la actual.

Error de especificación del modelo.

Error de medición, que es básicamente la diferencia entre los valores observados


y reales.

Eliminando una variable, que tiene poder explicativo.

La función de autocorrelación parcial (PACF) es otro método para examinar la


relación entre Xt y Xt−p, p Z. La ACF se considera comúnmente como una
herramienta útil en el modelo MA(q) simplemente porque la PACF no decae
rápidamente sino que se acerca a 0. Sin embargo, el patrón de ACF es más aplicable a MA.
PACF, por otro lado, funciona bien con el proceso AR(p).

PACF proporciona información sobre la correlación entre el valor actual de una serie de
tiempo y sus valores rezagados controlando las otras correlaciones.
Machine Translated by Google

No es fácil entender lo que está pasando a primera vista. Dejame darte un ejemplo. Supongamos
que queremos calcular la correlación parcial Xt y Xt−h.
Para ello, tengo en cuenta la estructura de correlación entre Xt y Xt−1 y Xt−2.

Dicho matemáticamente:

Cov(Xt,Xt−h|Xt−1,Xt−2...Xt−h−1)
ρˆ(h) =
√Var(Xt|Xt−1,Xt−2,...,Xt−h−1)Var(Xt −h|Xt−1,Xt−2,...,Xt−h−1)

donde h es el retraso.

En [9]: sm.graphics.tsa.plot_pacf(SP_prices, retrasos=30)


plt.xlabel('Número de retrasos')
plt.savefig('images/pacf_SP.png')
plt.show()

Trazar la función de autocorrelación parcial

La Figura 2­5 muestra el PACF de los datos brutos del S&P­500. Al interpretar el PACF, nos centramos
en los picos fuera de la región oscura que representan el intervalo de confianza.
La Figura 2­5 muestra algunos picos en diferentes rezagos, pero el rezago 16 está fuera del
intervalo de confianza. Por lo tanto, puede ser prudente seleccionar un modelo con 16 rezagos para
poder incluir todos los rezagos hasta el rezago 16.
Machine Translated by Google

Figura 2­5. Gráfico de función de autocorrelación parcial del S&P­500

Como se analizó, PACF mide la correlación entre los valores actuales de la serie y los valores
rezagados de la misma de una manera para aislar los efectos intermedios.

Estacionalidad La

estacionalidad existe si hay fluctuaciones regulares durante un período de tiempo determinado. Por
ejemplo, los usos de energía pueden mostrar características estacionales. Para ser más específicos,
el consumo de energía sube y baja en determinados períodos a lo largo de un año.

Para mostrar cómo podemos detectar el componente estacional, utilicemos la base de datos
FRED, que incluye más de 500.000 series de datos económicos de más de 80 fuentes que cubren
temas e información relacionados con muchas áreas como la banca, el empleo, los tipos
de cambio, el producto interno bruto y las tasas de interés. , comercio y transacciones
internacionales, etc.

En [10]: desde fredapi importa Fred


importa statsmodels.api como sm

En [11]: fred = Fred(api_key='78b14ec6ba46f484b94db43694468bb1')#inserta tu clave API

En [12]: energía = fred.get_series("CAPUTLG2211A2S",


observación_start="2010­01­01",
Machine Translated by Google

observación_end="2020­12­31")
energía.cabeza(12)
Fuera[12]: 2010­01­01 83.7028
2010­02­01 84.9324
2010­03­01 82.0379
2010­04­01 79.5073
2010­05­01 82.8055
2010­06­01 84.4108
2010­07­01 83.6338
2010­08­01 83.7961
2010­09­01 83.7459
2010­10­01 80.8892
2010­11­01 81.7758
2010­12­01 85.9894
tipo de letra: float64

En [13]: plt.plot(energía)
plt.title(' Utilización de la capacidad energética')
plt.ylabel('$')
plt.xlabel('Fecha')
plt.savefig('imágenes/energía.png')
plt.mostrar()
En [14]: sm.graphics.tsa.plot_acf(energía,lags=30)
plt.xlabel('Número de retrasos')
plt.savefig('images/energy_acf.png')
plt.mostrar()

Acceder a la utilización de la capacidad de energía desde la base de datos de Fred durante el período de
2010­2020.

La Figura 2­6 indica altibajos periódicos durante un período de casi 10 años en cuanto a
tienen una alta utilización de la capacidad en los primeros meses de cada año y luego disminuyen
hacia finales de año confirmando que existe una estacionalidad en la capacidad energética
utilización.
Machine Translated by Google

Figura 2­6. Estacionalidad en la utilización de la capacidad energética

Figura 2­7. ACF de utilización de la capacidad energética


Machine Translated by Google

Ciclicidad ¿Qué

pasa si los datos no muestran movimientos de período fijo? En este punto, el carácter
cíclico entra en escena. Existe cuando surge una variación periódica mayor que la
tendencia. Algunos confunden ciclicidad y estacionalidad en el sentido de que ambos exhiben
expansión y contracción. Sin embargo, podemos pensar en el carácter cíclico como
ciclos económicos, que tardan mucho en completar su ciclo y los altibajos a lo largo de un
largo horizonte. Por tanto, el carácter cíclico se diferencia de la estacionalidad en el sentido
de que no hay fluctuaciones en un período fijo. Un ejemplo de carácter cíclico pueden ser
las compras (o ventas) de viviendas en función del tipo hipotecario. Es decir, cuando se reduce
(o aumenta) la tasa hipotecaria, se genera un impulso para la compra (o venta) de viviendas.

Residual
El residual se conoce como componente irregular de una serie temporal. Técnicamente hablando, el
residual es igual a la diferencia entre las observaciones y los valores ajustados relacionados.
Entonces, podemos considerarlo como un sobrante del modelo.

Como hemos comentado antes, los modelos de series de tiempo carecen de algunos supuestos
básicos, pero eso no significa necesariamente que los modelos de series de tiempo
estén libres de supuestos. Me gustaría destacar el más destacado, que se llama estacionariedad.

Estacionariedad significa que las propiedades estadísticas como la media, la varianza y la


covarianza de la serie temporal no cambian con el tiempo.

Hay dos formas de estacionariedad:

1) Estacionariedad débil: series temporales, Xt , se dice que es estacionario si

Xt tiene varianza finita, E(X2 t ) < ∞, t Z

El valor medio de Xt es constante y depende únicamente del tiempo,


E(Xt) = μ,t Z

La estructura de covarianza, γ(t,t + h), depende únicamente de la diferencia horaria:

γ(h) = γh + γ(t + h,t)

En palabras, las series de tiempo deben tener una varianza finita con una media constante y
una estructura de covarianza que sea función de la diferencia temporal.
Machine Translated by Google

2) Estacionariedad fuerte: Si la distribución conjunta de Xt1, Xt2, . . . Xtk es lo mismo con la


versión desplazada del conjunto Xt1+h, Xt2+h, . . . Xtk+h, se denomina estacionariedad fuerte.
Por lo tanto, una fuerte estacionariedad implica que la distribución de la variable aleatoria de
un proceso aleatorio es la misma con un índice de tiempo cambiante.

La pregunta ahora es ¿por qué necesitamos la estacionariedad? La razón es doble.

Primero, en el proceso de estimación es esencial tener cierta distribución a medida que pasa el tiempo. En otras

palabras, si la distribución de una serie temporal cambia con el tiempo, se vuelve impredecible y no se puede

modelar.

El objetivo final de los modelos de series temporales es la previsión. Para ello primero debemos estimar los

coeficientes, lo que corresponde al aprendizaje en Machine Learning.

Una vez que aprendemos y realizamos un análisis de pronóstico, asumimos que la distribución de los datos en la estimación

permanece igual de manera que tenemos los mismos coeficientes estimados. Si este no es el caso, deberíamos

volver a estimar los coeficientes porque no podemos pronosticar con los coeficientes estimados anteriormente.

Tener un quiebre estructural como una crisis financiera genera un cambio en la distribución.

Debemos ocuparnos de este período con cautela y por separado.

La otra razón para tener datos de estacionariedad es que, por supuesto, algunos modelos estadísticos requieren

datos de estacionariedad, pero eso no significa que algunos modelos solo requieran datos estacionarios. En cambio,

todos los modelos requieren estacionarios, pero si alimenta el modelo con datos no estacionarios, algunos modelos,

por diseño, lo convierten en estacionario y lo procesan. Las funciones integradas en Python facilitan este análisis de la

siguiente manera:

En [15]: stat_test = adfuller(SP_prices)[0:2]


print("La estadística de prueba y el valor p de la prueba ADF son {}".format(stat_test))
El estadístico de prueba y el valor p de la prueba ADF son (0,030295120072926063,
0,9609669053518538)

Prueba de estacionariedad del ADF

Impresión de la estadística de prueba de los primeros cuatro decimales y el valor p de la prueba ADF

La Figura 2­4 a continuación muestra los retrasos que disminuyen lentamente hasta llegar a ser no estacionarios

porque continúa la persistencia de la alta correlación entre los retrasos de las series temporales.
Machine Translated by Google

Existen, en general, dos formas de entender la no estacionariedad: visualización y método estadístico. Este último, por

supuesto, tiene una forma mejor y más sólida de detectar la no estacionariedad. Sin embargo, para mejorar nuestra

comprensión, comencemos con el ACF. El ACF de lenta decadencia implica que los datos no son estacionarios

porque presentan una fuerte correlación en el tiempo. Eso es lo que observo en los datos del S&P­500.

La forma estadística de detectar la no estacionariedad es más confiable y la prueba ADF es una prueba ampliamente

apreciada. Según el resultado de la prueba anterior, el valor p de 0,99 sugiere que los datos no son estacionarios, algo

que debemos abordar antes de seguir adelante.

Tomar diferencias es una técnica eficaz para eliminar la estacionariedad. Tomar la diferencia no es más que

restar el valor actual de la serie de su primer valor rezagado, es decir, xt − xt−1 y el siguiente código de Python

presenta cómo aplicar esta técnica:

En [16]: diff_SP_price = SP_prices.diff()

En [17]: plt.figure(figsize=(10, 6))


plt.plot(diff_SP_price)
plt.title('Precio diferenciado del S&P­500')
plt.ylabel('$')
plt.xlabel('Fecha' )
plt.savefig('images/diff_SP_price.png') plt.show()

En [18]: sm.graphics.tsa.plot_acf(diff_SP_price.dropna(),lags=30) plt.xlabel('Número


de retrasos') plt.savefig('images/
diff_acf_SP.png') plt.show()

En [19]: stat_test2=adfuller(diff_SP_price.dropna())[0:2] print("La


estadística de prueba y el valor p de la prueba ADF después de la diferenciación son {}"\
.formato(stat_test2))
El estadístico de prueba y el valor p de la prueba ADF después de la diferenciación
son (­7.0951058730170855, 4.3095548146405375e­10)

Tomando la diferencia de los precios del S&P­500

Resultado de la prueba del ADF basado en datos diferenciados del S&P­500

Después de tomar la primera diferencia, volvemos a ejecutar la prueba del ADF para ver si funcionó y sí, funciona. El

bajísimo valor p del ADF me dice que los datos del S&P­500 están estacionarios ahora.
Machine Translated by Google

Esto se puede observar en el gráfico de líneas que se proporciona a continuación. A diferencia del
gráfico bruto del S&P­500, la Figura 2­8 muestra fluctuaciones alrededor de la media con volatilidad similar
lo que significa que tenemos una serie estacionaria.

Figura 2­8. Precio del S&P­500 sin tendencia


Machine Translated by Google

Figura 2­9. Precio del S&P­500 sin tendencia

No hace falta decir que la tendencia no es el único indicador de no estacionariedad. La


estacionalidad es otra fuente y ahora estamos a punto de aprender un método para abordarla.

Primero, observemos el ACF de utilización de la capacidad energética ( Figura 2­7), que


muestra altibajos periódicos, lo cual es un signo de no estacionariedad.

Para eliminar la estacionalidad, primero aplicamos el método de remuestreo para calcular


la media anual, que se utiliza como denominador en la siguiente fórmula:

Valor de una serie temporal estacional


Índice estacional =
Promedio estacional

Así, el resultado de la aplicación, índice estacional, nos da la serie temporal desestacionalizada.


El siguiente código nos muestra cómo codificamos esta fórmula en Python.

En [20]: índice_estacional = energía.resample('Q').mean()

En [21]: fechas = energía.index.año.unique()


deestacionalizado = []
para i en fechas:
para j en rango(1, 13):
deestacionalizado.append((energía[str(i)][energía[str(i)].index.mes==j]))
concat_deseasonalized = np.concatenate(desestacionalizado)
Machine Translated by Google

En [22]: temporada_energía = []
para i,s en zip(range(0, len(energy), 3), range(len(seasonal_index))):
deseason_energy.append(concat_deseasonalized[i:i+3] /
season_index.iloc[s])
concat_deseason_energy = np.concatenate(deseason_energy)
deseason_energy = pd.DataFrame(concat_deseason_energy, index=energy.index)
deseason_energy.columns = ['Energía desaestacionalizada']
deseason_energy.head()
Fuera[22]: Energía Desestacionalizada
2010­01­01 1.001737
2010­02­01 1.016452
2010­03­01 0.981811
2010­04­01 0,966758
2010­05­01 1,006862

En [23]: sm.graphics.tsa.plot_acf(deseason_energy, lags=10) plt.xlabel('Número


de retrasos') plt.savefig('images/
deseason_energy_acf.png') plt.show()

En [24]: sm.graphics.tsa.plot_pacf(deseason_energy, lags=10) plt.xlabel('Número


de retrasos') plt.savefig('images/
deseason_energy_pacf.png') plt.show()

Cálculo de la media trimestral de utilización de energía.

Definición de los años en los que se ejecuta el análisis de estacionalidad.

Calcular el numerador de la fórmula del índice estacional .

Concatenando el uso de energía desestacionalizado.

Calcular el índice estacional utilizando una fórmula predefinida.

La Figura 2­10 sugiere que existe una correlación estadísticamente significativa en los desfases 1 y 2, pero
el ACF no muestra ninguna característica periódica, que es otra forma de decir desestacionalización.
Machine Translated by Google

Figura 2­10. ACF desestacionalizado de utilización de energía

De manera similar, en la Figura 2­11, aunque tenemos picos en algunos retrasos, el PACF no
muestra altibajos periódicos. Entonces, podemos decir que los datos están desestacionalizados
utilizando la fórmula del índice estacional.
Machine Translated by Google

Figura 2­11. PACF desestacionalizado de utilización de energía

Lo que tenemos ahora son altibajos menos periódicos en la utilización de la capacidad


energética, lo que significa que los datos resultan desestacionalizados.

Finalmente, estamos listos para avanzar y discutir los modelos de series temporales.

Modelos de series temporales


Los modelos tradicionales de series temporales son modelos univariados y siguen las
siguientes fases:

Identificación: en este proceso, exploramos los datos utilizando ACF, PACF, patrón de
identificación y realización de pruebas estadísticas.

Estimación: esta parte pertenece a la estimación de coeficientes mediante una


técnica de optimización adecuada.

Diagnóstico: Una vez estimada, debemos comprobar si los criterios de información o ACF/
PACF sugieren que el modelo es válido. Si es así, pasamos a la etapa de previsión.
Machine Translated by Google

Pronóstico: esta parte trata más sobre el rendimiento del modelo. Al pronosticar,
predecimos valores futuros basados en nuestra estimación.

La Figura 2­12 indica el proceso de modelado. En consecuencia, después de la


identificación de las variables y el proceso de estimación, se ejecuta el modelo. Sólo después de
realizar un diagnóstico adecuado, podremos realizar el análisis de previsión.

Figura 2­12. Proceso de modelado

Al modelar datos con una dimensión temporal, debemos considerar la correlación en


puntos adyacentes en el tiempo. Esta consideración nos lleva al modelado de series de tiempo
como comentamos antes. Mi objetivo, al modelar series de tiempo, es ajustar un modelo y
comprender el carácter estadístico de una serie de tiempo, que fluctúa aleatoriamente en el tiempo.

Recuerde la discusión sobre el proceso IID, que es el modelo de series de tiempo más básico
y a veces se lo denomina ruido blanco. Toquemos el concepto de ruido blanco.
Machine Translated by Google

Ruido blanco

La serie temporal t se dice que es ruido blanco si satisface lo siguiente:

2
t WN(0, σ )

Corr( t, s) = 0, t≠s

En palabras, t tiene media 0 y varianza constante. Además, no existe correlación entre


términos sucesivos de t.

Bueno, es fácil decir que el proceso de ruido blanco es estacionario y el gráfico de ruido blanco
presenta fluctuaciones alrededor de la media de forma aleatoria en el tiempo.

Sin embargo, como el ruido blanco está formado por una secuencia no correlacionada, no es
un modelo atractivo desde el punto de vista de la previsión. De otra manera, la falta de correlación
nos impide pronosticar valores futuros.

Como podemos observar en la Figura 2­13 a continuación, el ruido blanco oscila alrededor de la
media y es completamente errático.

En [25]: mu = 0
estándar
= 1 WN = np.random.normal(mu, estándar, 1000)

plt.plot(WN)
plt.xlabel('Número de simulación')
plt.savefig('images/WN.png')
plt.show()
Machine Translated by Google

Figura 2­13. Proceso de ruido blanco

A partir de este momento, necesitamos identificar el número óptimo de retraso antes


de ejecutar el modelo de series de tiempo. Como puede imaginar, decidir el número
óptimo de retraso es una tarea desafiante. Los métodos más utilizados
son: ACF, PACF y criterios de información. Se han debatido el ACF y el PACF y,
en aras de la exhaustividad, también se introducirán criterios de información, abreviado AIC.
Machine Translated by Google

CRITERIOS DE INFORMACIÓN

Detectar el número óptimo de retraso es una tarea engorrosa. Necesitamos tener un criterio
para decidir qué modelo se ajusta mejor a los datos, ya que puede haber numerosos
modelos potencialmente buenos. Akaike Information Criteria, también conocido
como AIC, como indican Cavanaugh y Neath (2019) que

AIC se introduce como una extensión del Principio de Máxima Verosimilitud.


La máxima verosimilitud se aplica convencionalmente para estimar los
parámetros de un modelo una vez que se han formulado la estructura y la dimensión
del modelo.

AIC se puede definir matemáticamente como:

AIC = −2ln(Probabilidad Máxima) + 2d


donde d es el número total de parámetros. El último término, el 2d de la ecuación, tiene
como objetivo reducir el riesgo de sobreajuste. También se denomina término de
penalización mediante el cual puedo filtrar la redundancia innecesaria en el modelo.

BIC es el otro criterio de información utilizado para seleccionar el mejor modelo. El plazo
de sanción en BIC es mayor que el de AIC.

BIC = −2ln(Probabilidad Máxima) + ln(n) * d


donde n es el número de observaciones.

Tenga en cuenta que debe tratar el AIC con precaución si el modelo propuesto es de
dimensiones finitas. Este hecho está bien expresado por Clifford y Hurvich (1989):

Si el modelo verdadero es de dimensión infinita, caso que parece más realista en la práctica,
AIC proporciona una selección asintóticamente eficiente de un modelo aproximado de
dimensión finita. Sin embargo, si el verdadero modelo es de dimensión finita, los métodos
asintóticamente eficientes, por ejemplo, el FPE de Akaike (Akaike, 1970), el AIC y el CAT
de Parzen (Parzen, 1977), no proporcionan selecciones consistentes del orden del
modelo.

Comencemos a visitar el modelo clásico de series de tiempo con el modelo de media móvil.

Modelo de media móvil


Machine Translated by Google

La media móvil (MA) y los residuos son modelos estrechamente relacionados. La media móvil puede
considerarse un modelo de suavizado, ya que tiende a tener en cuenta los valores de rezago
del residual. En aras de la simplicidad, comencemos con MA(1):

Xt = t+α t−1

Mientras α ≠ 0, tiene una estructura de correlación no trivial. Intuitivamente, MA(1) nos dice que la
serie temporal ha sido afectada por ty t−1 únicamente.

En forma general, la ecuación MA(q) se convierte en:

Xt = t + α1 t−1 + α2 t−2... + αq t−q

A partir de este momento, para ser coherentes, modelaremos los datos de dos importantes
empresas de TI, a saber, Apple y Microsoft. Yahoo Finance proporciona una herramienta
conveniente para acceder al precio de cierre de las acciones relacionadas para el período 01­01­2019
y 01­01­2021.

Como primer paso, eliminamos los valores faltantes y comprobamos si los datos son estacionarios
y resulta que ni los precios de las acciones de Apple ni de Microsoft tienen una estructura estacionaria
como se esperaba. Por lo tanto, los pasos a seguir en este punto son tomar la primera
diferencia para hacer que estos datos sean estacionarios y dividirlos como tren y prueba . El
siguiente código nos muestra cómo podemos hacer esto en Python.

En [26]: ticker = ['AAPL', 'MSFT'] inicio


= datetime.datetime(2019, 1, 1) end =
datetime.datetime(2021, 1, 1) stock_prices
= yf.download(ticker, start= inicio, fin = fin, intervalo = '1d').Cerrar
[*********************100%************ ***********] 2 de 2 completados

En [27]: precios_stock = precios_stock.dropna()

En [28]: para i en el ticker:


stat_test = adfuller(stock_prices[i])[0:2] print("La
estadística de prueba ADF y el valor p de {} son
{}".formato(i,stat_test))
El estadístico de prueba ADF y el valor p de AAPL son (0,29788764759932335,
0,9772473651259085)
La estadística de prueba ADF y el valor p de MSFT son (­0,8345360070598484,
0,8087663305296826)

En [29]: diff_stock_prices = stock_prices.diff().dropna()

En [30]: dividir = int(len(diff_stock_prices['AAPL'].values) * 0,95)


Machine Translated by Google

diff_train_aapl = diff_stock_prices['AAPL'].iloc[:split] diff_test_aapl


= diff_stock_prices['AAPL'].iloc[split:] diff_train_msft =
diff_stock_prices['MSFT'].iloc[:split] diff_test_msft =
diff_stock_prices['MSFT'] .iloc[dividido:]

En [31]: diff_train_aapl.to_csv('diff_train_aapl.csv')
diff_test_aapl.to_csv('diff_test_aapl.csv')
diff_train_msft.to_csv('diff_train_msft.csv')
diff_test_msft.to_csv('diff_test_msft.cs v')

En [32]: fig, ax = plt.subplots(2, 1, figsize=(10, 6))


plt.tight_layout()
sm.graphics.tsa.plot_acf(diff_train_aapl,lags=30, ax=ax[0] , título='ACF ­ Apple')
sm.graphics.tsa.plot_acf(diff_train_msft,lags=30, ax=ax[1], título='ACF ­ Microsoft')

plt.savefig('images/acf_ma.png') plt.mostrar()

Recuperar los precios de cierre mensuales de las acciones.

Dividir datos en 95% y 5%.

Asignar el 95% de los datos del precio de las acciones de Apple al conjunto de trenes.

Asignar el 5% de los datos del precio de las acciones de Apple al conjunto de prueba.

Asignar el 95% de los datos del precio de las acciones de Microsoft al conjunto de trenes.

Asignar el 5% de los datos del precio de las acciones de Microsoft al conjunto de prueba.

Guardar los datos para uso futuro.

Al observar el primer panel de la Figura 2­14, se puede observar que hay picos significativos en algunos

rezagos y, para estar seguros, elegimos el rezago 9 para el modelo de promedio móvil corto y 22 para el modelo

de promedio móvil largo. Esto implica que el orden 9 será nuestro orden a corto plazo y 22 se convertirá en nuestro

orden a largo plazo al modelar MA.


Machine Translated by Google

Figura 2­14. ACF después de la primera diferencia

En [33]: short_moving_average_appl = diff_train_aapl.rolling(ventana=9).mean()


long_moving_average_appl = diff_train_aapl.rolling(ventana=22).mean()

En [34]: fig, ax = plt.subplots(figsize=(10, 6))


ax.plot(diff_train_aapl.loc[start:end].index,
diff_train_aapl.loc[start:end],
label='Precio de las acciones',
c='b') ax.plot(short_moving_average_appl.loc[start:end]. index,
short_moving_average_appl.loc[start:end], label
= 'Short MA',c='g')
ax.plot(long_moving_average_appl.loc[start:end].index,
long_moving_average_appl.loc[start:end], label
= 'Long MA',c='r')
ax.legend(loc='best')
ax.set_ylabel('Precio en $')
ax.set_title(' Predicción de acciones­Apple')
plt.savefig('images/ma_apple .png')
plt.show()

Media móvil con ventana corta para las acciones de Apple

Media móvil con ventana larga para las acciones de Apple


Machine Translated by Google

Gráfico lineal de los primeros precios diferenciados de las acciones de Apple

Visualización del resultado de media móvil de ventana corta para Apple

Visualización del resultado de media móvil de ventana larga para Apple

La Figura 2­15 muestra el resultado del modelo de promedio móvil a corto plazo en color verde y
el resultado del modelo de promedio móvil a largo plazo en color rojo. Como era de esperar,
resulta que la media móvil a corto plazo tiende a reaccionar más a los cambios diarios en el
precio de las acciones de Apple en comparación con la media móvil a largo plazo. Tiene
sentido porque tener en cuenta una media móvil larga genera una predicción fluida.

Figura 2­15. Resultado de predicción del modelo de media móvil para Apple

En el siguiente paso, intentamos predecir el precio de las acciones de Microsoft utilizando un


modelo de media móvil con una ventana diferente. Pero antes de continuar, permítanme
decirles que elegir la ventana adecuada para el análisis de medias móviles cortas y largas
es clave para un buen modelado. En el segundo panel de la Figura 2­14, parece tener picos
significativos en 2 y 23 y estos retrasos se utilizan en análisis de promedio móvil corto y largo.
Machine Translated by Google

respectivamente. Después de identificar la ventana, ajustemos los datos al modelo de media


móvil con la siguiente aplicación.

En [35]: short_moving_average_msft = diff_train_msft.rolling(ventana=2).mean()


long_moving_average_msft = diff_train_msft.rolling(ventana=23).mean()

En [36]: fig, ax = plt.subplots(figsize=(10, 6))


ax.plot(diff_train_msft.loc[start:end].index,
diff_train_msft.loc[start:end], label='
Precio de las acciones',c='b')
ax.plot(short_moving_average_msft.loc[start:end]. índice,
short_moving_average_msft.loc[inicio:fin],
etiqueta = 'MA corto ',c='g')
ax.plot(long_moving_average_msft.loc[inicio:fin].index,
long_moving_average_msft.loc[start:end], label
= 'Long MA',c='r')
ax.legend(loc='best')
ax.set_ylabel('$')
ax.set_xlabel('Fecha')
ax. set_title(' Predicción de acciones­Microsoft')
plt.savefig('images/ma_msft.png')
plt.show()

De manera similar, las predicciones basadas en el análisis de media móvil corta tienden a
ser más reactivas que las del modelo de media móvil larga de la Figura 2­16. Pero,
en el caso de Microsoft, la predicción del promedio móvil a corto plazo parece estar muy
cerca de los datos reales.
Machine Translated by Google

Figura 2­16. Resultado de predicción del modelo de media móvil para Microsoft

Modelo autorregresivo La estructura

de dependencia de términos sucesivos es la característica más distintiva del modelo


autorregresivo en el sentido de que el valor actual retrocede sobre sus propios valores de
rezago en este modelo. Entonces, básicamente pronosticamos el valor actual de la serie
temporal Xt utilizando una combinación lineal de sus valores pasados. Matemáticamente, la
forma general de AR(p) se puede escribir como:

Xt = c + α1Xt−1 + α2Xt−2... + αpXt−p + t

donde t denota los residuos y c es el término intercetato. El modelo AR(p) implica que los
valores pasados hasta el orden p tienen cierto poder explicativo sobre Xt . Si la
relación tiene memoria más corta, entonces es probable que modele Xt con menos rezagos.

Hemos discutido una de las principales propiedades de las series de tiempo, que es
la estacionariedad , y la otra propiedad importante es la invertibilidad. Después de presentar
Machine Translated by Google

Modelo AR, es hora de mostrar la invertibilidad del proceso MA. Se dice que es invertible si se puede
convertir a un modelo AR infinito.

De manera diferente, bajo algunas circunstancias, MA puede escribirse como un proceso AR


infinito. Estas circunstancias deben tener una estructura de covarianza estacionaria, una parte
determinista y un proceso MA invertible. Al hacerlo, tenemos otro modelo llamado AR infinito
gracias al supuesto de |α| < 1.

Xt = t+α t−1

= t + α(Xt−1 − α t−2)

= t + αXt−1 − α 2 t−2

= t + αXt−1 − α 2(Xt−2 + α t−3)

= t + αXt−1 − α 2Xt−2 + α 3
t−3)

= ...

= αXt−1 − α 2Xt−2 + α 3 t−3 − α 4 t−4 + ... − (−α) norte

t−n

Después de hacer la ecuación matemática necesaria, queda la siguiente forma:

norte­1

norte α t−n = t − ∑ αiXt −i


yo=0

En este caso, si |α| < 1. Entonces n → ∞

2
norte­1
2n 2
∑ ) = mi(α t−n → ∞)
mi( t− yo=0 αiXt −i)

Finalmente, el proceso MA(1) resulta ser:

t= ∑ αiXt −i
yo=0

Debido a la dualidad entre los procesos AR y MA, es posible representar AR(1) como MA infinita,
MA(∞). En otras palabras, el proceso AR(1) puede ser
Machine Translated by Google

expresado en función de los valores pasados de las innovaciones.

Xt = t + θXt−1

= θ(θXt−2 + t−1) + t

= θ 2Xt−2 + θ t−1 + t

= θ 2 (θXt−3 + θ t−2)θ t−1 + t

Xt = t+ t−1 + θ 2 t−2 + ... + θ tXt

Como n → ∞, θ t
→ 0, por lo que puedo representar AR(1) como un proceso MA infinito.

En el siguiente análisis, ejecutamos un modelo autorregresivo para predecir los precios de las
acciones de Apple y Microsoft. A diferencia de la media móvil, la función de autocorrelación parcial es
una herramienta útil para encontrar el orden óptimo en un modelo autorregresivo. Esto se
debe a que, en AR, nuestro objetivo es descubrir la relación de una serie de tiempo entre dos
tiempos diferentes, digamos Xt y Xt­k , y para hacerlo necesito filtrar el efecto de otros retrasos
intermedios.

En [37]: sm.graphics.tsa.plot_pacf(diff_train_aapl,lags=30)
plt.title('PACF de Apple')
plt.xlabel('Número de retrasos')
plt.savefig('images/pacf_ar_aapl.png' )
plt.mostrar()
En [38]: sm.graphics.tsa.plot_pacf(diff_train_msft,lags=30)
plt.title('PACF de Microsoft')
plt.xlabel('Número de retrasos')
plt.savefig('images/pacf_ar_msft.png')
plt.show()

Con base en la Figura 2­17, obtenida de la primera diferencia del precio de las acciones de Apple,
observamos un pico significativo en el rezago 29 y la Figura 2­18 muestra que tenemos un pico
similar en el rezago 23. Por lo tanto, 29 y 23 son los rezagos que Voy a utilizarlo en el modelado
de AR para Apple y Microsoft, respectivamente.
Machine Translated by Google

Figura 2­17. PACF para Apple

Figura 2­18. PACF para Microsoft


Machine Translated by Google

En [39]: de statsmodels.tsa.ar_model importar AutoReg importar


advertencias
advertencias.filterwarnings('ignorar')

En [40]: ar_aapl = AutoReg(diff_train_aapl.values, retrasos=26)


ar_fitted_aapl = ar_aapl.fit()

En [41]: ar_predictions_aapl = ar_fitted_aapl.predict(start=len(diff_train_aapl), end=len(diff_train_aapl)\ +


len(diff_test_aapl) ­ 1,
dinámico=Falso)

En [42]: para i en rango(len(ar_predictions_aapl)): print('==' * 25)


print('valores previstos:
{:.4f} y valores reales:
{:.4f}'.format(ar_predictions_aapl[i],

diff_test_aapl[yo]))
====================================================
valores previstos: 1,9207 y valores reales: 1,3200
====================================================
valores previstos: ­0,6051 y valores reales: 0,8600
====================================================
valores previstos: ­0,5332 y valores reales: 0,5600
====================================================
valores previstos: 1,2686 y valores reales: 2,4600
====================================================
valores previstos: ­0,0181 y valores reales: 3,6700
====================================================
valores previstos: 1,8889 y valores reales: 0,3600
====================================================
valores previstos: ­0,6382 y valores reales: ­0,1400
====================================================
valores previstos: 1,7444 y valores reales: ­0,6900
====================================================
valores previstos: ­1,2651 y valores reales: 1,5000
====================================================
valores previstos: 1,6208 y valores reales: 0,6300
====================================================
valores previstos: ­0,4115 y valores reales: ­2,6000
====================================================
valores previstos: ­0,7251 y valores reales: 1,4600
====================================================
valores previstos: 0,4113 y valores reales: ­0,8300
====================================================
valores previstos: ­0,9463 y valores reales: ­0,6300
====================================================
valores previstos: 0,7367 y valores reales: 6,1000
====================================================
valores previstos: ­0,0542 y valores reales: ­0,0700
====================================================
Machine Translated by Google

valores previstos: 0,1617 y valores reales: 0,8900


====================================================
valores previstos: ­1,0148 y valores reales: ­2,0400
====================================================
valores previstos: 0,5313 y valores reales: 1,5700
====================================================
valores previstos: 0,3299 y valores reales: 3,6500
====================================================
valores previstos: ­0,2970 y valores reales: ­0,9200
====================================================
valores previstos: 0,9842 y valores reales: 1,0100
====================================================
valores previstos: 0,3299 y valores reales: 4,7200
====================================================
valores previstos: 0,7565 y valores reales: ­1,8200
====================================================
valores previstos: 0,3012 y valores reales: ­1,1500
====================================================
valores previstos: 0,7847 y valores reales: ­1,0300

En [43]: ar_predictions_aapl = pd.DataFrame(ar_predictions_aapl)


ar_predictions_aapl.index = diff_test_aapl.index

En [44]: ar_msft = AutoReg(diff_train_msft.values, retrasos=26)


ar_fitted_msft = ar_msft.fit()

En [45]: ar_predictions_msft = ar_fitted_msft.predict(start=len(diff_train_msft), end=len(diff_train_msft)\


+len(diff_test_msft) ­ 1,
dinámico=Falso)

En [46]: ar_predictions_msft = pd.DataFrame(ar_predictions_msft)


ar_predictions_msft.index = diff_test_msft.index

Ajuste de los datos bursátiles de Apple con el modelo AR.

Predicción de los precios de las acciones de Apple.

Comparar las observaciones previstas y reales.

Convertir una matriz en un marco de datos para asignar un índice.

Asigne índices de datos de prueba a los valores previstos.

Ajuste de datos bursátiles de Microsoft con el modelo AR.


Machine Translated by Google

Predicción de los precios de las acciones de Microsoft.

Convierta la matriz en un marco de datos para asignar el índice.

Asigne índices de datos de prueba a los valores previstos.

En [47]: fig, ax = plt.subplots(2,1, figsize=(18, 15))

ax[0].plot(diff_test_aapl, label='Precio real de las acciones', c='b')


ax[0].plot(ar_predictions_aapl, c='r', label="Predicción") ax[0].set_title ('
Precio previsto de las acciones­Apple')
ax[0].legend(loc='best')
ax[1].plot(diff_test_msft, label='Precio real de las acciones', c='b') ax[1].
plot(ar_predictions_msft, c='r', label="Prediction") ax[1].set_title('Precio
de acciones previsto ­Microsoft') ax[1].legend(loc='best') para
ax en ax.flat :
ax.set(xlabel='Fecha',
ylabel='$') plt.savefig('images/ar.png')

plt.mostrar()

La Figura 2­19 indica las predicciones basadas en el modelo AR. Las líneas rojas representan las predicciones del precio de

las acciones de Apple y Microsoft y las líneas azules indican los datos reales.

El resultado revela que el modelo AR es superado por el modelo MA en la captura del precio de las acciones.
Machine Translated by Google

Figura 2­19. Resultados de predicción del modelo autorregresivo


Machine Translated by Google

Modelo de media móvil integrada autorregresiva El modelo de media móvil

integrada autorregresiva, ARIMA para abreviar, es una función de los valores pasados de
una serie temporal y el ruido blanco. Sin embargo, ARIMA se propone como una
generalización de AR y MA, pero no tienen parámetros de integración, lo que nos ayuda
a alimentar el modelo con los datos sin procesar. A este respecto, incluso si incluimos
datos no estacionarios, ARIMA los vuelve estacionarios al definir adecuadamente el
parámetro de integración.

ARIMA tiene tres parámetros, a saber, p, d, q. Como sabemos por los modelos de series temporales
anteriores, p y q se refieren al orden de AR y MA, respectivamente. Pero d controla la diferencia de
nivel. Si d=1, equivale a primera diferencia y si toma el valor de 0, significa que el modelo es ARMA.

Es posible tener d mayor que uno pero no es tan común como tener d de 1.
La ecuación ARIMA (p,1,q) tiene la siguiente estructura:

Xt = α1dXt−1 + α2dXt−2... + αpdXt−p + t + β1d t−1 + β2d t−2... + βqd t−q


donde d se refiere a la diferencia.

Como es un modelo ampliamente adoptado y aplicable, analicemos los pros y los contras del modelo ARIMA
para familiarizarnos más con el modelo.

Ventajas

ARIMA nos permite trabajar con datos sin procesar sin considerar si son estacionarios.

Funciona bien con datos de alta frecuencia.

Es menos sensible a la fluctuación de los datos en comparación con otros modelos.

Contras

ARIMA podría no captar la estacionalidad.

Funciona mejor con series largas y datos a corto plazo (diarios, horarios).

Como no se produce ninguna actualización automática en ARIMA, no se debe observar ninguna


interrupción estructural durante el período de análisis.

No tener ajustes en el proceso ARIMA genera inestabilidad.


Machine Translated by Google

Ahora, mostraremos cómo funciona y se desempeña ARIMA utilizando las mismas acciones, es decir, Apple y

Microsoft.

En [48]: de statsmodels.tsa.arima_model importa ARIMA

En [49]: división = int(len(stock_prices['AAPL'].values) * 0,95)


train_aapl = precios_acciones['AAPL'].iloc[:split]
test_aapl = precios_acciones['AAPL'].iloc[split:]
train_msft = precios_acciones['MSFT'].iloc[:split]
test_msft = precios_acciones['MSFT'] .iloc[dividido:]

En [50]: arima_aapl = ARIMA(train_aapl,order=(9, 1, 9))


arima_fitted_aapl = arima_aapl.fit()

En [51]: arima_msft = ARIMA(train_msft, orden=(6, 1, 6))


arima_fitted_msft = arima_msft.fit()

En [52]: arima_predictions_aapl = arima_fitted_aapl.predict(start=len(train_aapl),


end=len(train_aapl)\ +
len(test_aapl) ­ 1,
dinámico=False)
arima_predictions_msft = arima_fitted_msft.predict(start=len(train_msft),
end=len(train_msft)\ +
len(test_msft) ­ 1,
dinámico=False )

En [53]: arima_predictions_aapl = pd.DataFrame(arima_predictions_aapl)


arima_predictions_aapl.index = diff_test_aapl.index
arima_predictions_msft = pd.DataFrame(arima_predictions_msft)
arima_predictions_msft.index = diff_test_msft.index

Configurando el modelo ARIMA para acciones de Apple.

Adaptación del modelo ARIMA al precio de las acciones de Apple.

Configurando el modelo ARIMA para acciones de Apple.

Ajuste del modelo ARIMA al precio de las acciones de Microsoft.

Predicción de los precios de las acciones de Apple según ARIMA.

Predicción de los precios de las acciones de Microsoft según ARIMA.

Índice de formación para predicciones.


Machine Translated by Google

En [54]: fig, ax = plt.subplots(2, 1, figsize=(18, 15))

ax[0].plot(diff_test_aapl, label='Precio real de las acciones', c='b')


ax[0].plot(arima_predictions_aapl, c='r', label="Predicción") ax[0].set_title
(' Precio previsto de las acciones­Apple')
ax[0].legend(loc='best')
ax[1].plot(diff_test_msft, label='Precio real de las acciones', c='b') ax[1].
plot(arima_predictions_msft, c='r', label="Prediction") ax[1].set_title('Precio
de acciones previsto ­Microsoft') ax[1].legend(loc='best')
para ax en ax.flat :
ax.set(xlabel='Fecha',
ylabel='$')
plt.savefig('imágenes/ARIMA.png')
plt.show()

La Figura 2­20 muestra el resultado de la predicción basada en el precio de las


acciones de Apple y Microsoft y como empleo el mismo orden en los modelos AR y MA,
resulta ser lo mismo con estos modelos.
Machine Translated by Google

Figura 2­20. Resultados de predicción de ARIMA


Machine Translated by Google

Ante esta conjetura, vale la pena discutir el método alternativo para la selección de
rezagos óptimos para modelos de series de tiempo. AIC es el método que aplico aquí
para seleccionar el número adecuado de retrasos. Tenga en cuenta que, aunque el
resultado del AIC sugiere (4, 0, 4), el modelo no converge con este orden. Entonces, en
su lugar se aplica (4, 1, 4).

En [55]: importar itertools

En [56]: p = q = rango(0, 9) d =
rango(0, 3) pdq
= list(itertools.product(p, d, q))
arima_results_aapl = []
para param_set en pdq:

intente: arima_aapl = ARIMA(train_aapl, order=param_set)


arima_fitted_aapl = arima_aapl.fit()
arima_results_aapl.append(arima_fitted_aapl.aic)
excepto:
continuar
print('**'*25)
print('La puntuación AIC más baja es {:.4f} y los parámetros correspondientes son {}'

.format(pd.DataFrame(arima_results_aapl) .where(pd.DataFrame(arima_results_aapl).T.notnull().all()).m
[0],
pdq[arima_results_aapl.index(min(arima_results_aapl))]))
**************************************************
La puntuación AIC más baja es 1951,9810 y los parámetros correspondientes son
(4, 0, 4)

En [57]: arima_aapl = ARIMA(train_aapl, orden=(4, 1, 4))


arima_fitted_aapl = arima_aapl.fit()

En [58]: p = q = rango(0, 6) d =
rango(0, 3) pdq
= list(itertools.product(p, d, q))
arima_results_msft = []
para param_set en pdq:

intente: arima_msft = ARIMA(stock_prices['MSFT'], order=param_set)


arima_fitted_msft = arima_msft.fit()
arima_results_msft.append(arima_fitted_msft.aic)
excepto:
continuar
print('**'*25)
print('La puntuación AIC más baja es { :.4f} y los parámetros correspondientes son {}'

.format(pd.DataFrame(arima_results_msft) .where(pd.DataFrame(arima_results_msft).T.notnull().all()).m
[0],
Machine Translated by Google

pdq[arima_results_msft.index(min(arima_results_msft))]))
**************************************************
La puntuación AIC más baja es 2640,6367 y los parámetros correspondientes son
(4, 2, 4)

En [59]: arima_msft = ARIMA(stock_prices['MSFT'], orden=(4, 2,4 ))


arima_fitted_msft= arima_msft.fit()

En [60]: arima_predictions_aapl = arima_fitted_aapl.predict(start=len(train_aapl),


end=len(train_aapl)\
+len(test_aapl) ­ 1,
dinámico=False)
arima_predictions_msft = arima_fitted_msft.predict(start=len(train_msft),
end=len(train_msft)\ +
len(test_msft) ­ 1,
dinámico=False )

En [61]: arima_predictions_aapl = pd.DataFrame(arima_predictions_aapl)


arima_predictions_aapl.index = diff_test_aapl.index
arima_predictions_msft = pd.DataFrame(arima_predictions_msft)
arima_predictions_msft.index = diff_test_msft.index

Definición de un rango para órdenes AR y MA.

Definición de un término de diferencia de rango.

Aplicando iteración sobre p, d y q.

Cree una lista vacía para almacenar valores AIC.

Configuración del modelo ARIMA para que se ajuste a los datos de Apple.

Ejecutando el modelo ARIMA con todos los retrasos posibles.

Almacenar valores AIC en una lista.

Impresión del valor AIC más bajo para datos de Apple.

Configuración y ajuste del modelo ARIMA con órdenes óptimas.

Ejecutando el modelo ARIMA con todos los retrasos posibles para los datos de Microsoft.

Adaptación del modelo ARIMA a los datos de Microsoft con pedidos óptimos.
Machine Translated by Google

Predicción de los precios de las acciones de Apple y Microsoft.

En [62]: fig, ax = plt.subplots(2, 1, figsize=(18, 15))

ax[0].plot(diff_test_aapl, label='Precio real de las acciones', c='b')


ax[0].plot(arima_predictions_aapl, c='r', label="Predicción") ax[0].set_title
(' Precio previsto de las acciones­Apple')
ax[0].legend(loc='best')
ax[1].plot(diff_test_msft, label='Precio real de las acciones', c='b') ax[1].
plot(arima_predictions_msft, c='r', label="Prediction") ax[1].set_title('Precio
de acciones previsto ­Microsoft') ax[1].legend(loc='best')
para ax en ax.flat :
ax.set(xlabel='Fecha',
ylabel='$')
plt.savefig('imágenes/ARIMA_AIC.png')
plt.show()

Los pedidos identificados para Apple y Microsoft son (4, 1, 4) y (4, 2, 4), respectivamente.
ARIMA hace un buen trabajo al predecir los precios de las acciones. Sin embargo, tenga en cuenta que una
identificación inadecuada de las órdenes da como resultado un ajuste deficiente y esto, a su vez,
produce predicciones que están lejos de ser satisfactorias.
Machine Translated by Google

Figura 2­21. Resultados de predicción de ARIMA


Machine Translated by Google

Conclusión
El análisis de series de tiempo tiene un papel central en el análisis financiero. Es simplemente
porque la mayoría de los datos financieros tienen una dimensión temporal y este tipo de
datos deben modelarse con cautela. Por lo tanto, este capítulo es el primer intento de modelar
datos con dimensión temporal y para ello hemos empleado el modelo clásico de series de
tiempo, es decir, la media móvil, el modelo autorregresivo y, finalmente, la media móvil
integrada autorregresiva. ¿Crees que esa es toda la historia? ¡Absolutamente no! En el
próximo capítulo, veremos cómo se puede modelar una serie de tiempo utilizando modelos de
aprendizaje profundo.

Recursos adicionales
Artículo citado en este capítulo:

Hurvich, Clifford M. y Chih­Ling Tsai. "Selección de modelos de regresión y series de tiempo


en muestras pequeñas". Biometrika 76, núm. 2 (1989): 297­30.

Libros citados en este capítulo:

Buduma, N. y Locascio, N., 2017. Fundamentos del aprendizaje profundo: diseño


de algoritmos de inteligencia artificial de próxima generación. O'Reilly Media, Inc.

Brockwell, Peter J. y Richard A. Davis. Introducción a las series temporales y la


previsión. Saltador, 2016.

Walsh, Norman y Leonard Muellner. DocBook: la guía definitiva.


O'Reilly Media, Inc., 1999.
Machine Translated by Google

Capítulo 3. Aprendizaje profundo para el modelado

de series temporales

UNA NOTA PARA LOS LECTORES DE PUBLICACIÓN ANTICIPADA

Con los libros electrónicos de lanzamiento anticipado, obtiene libros en su forma más
antigua (el contenido sin editar y sin editar del autor mientras escribe) para que pueda
aprovechar estas tecnologías mucho antes del lanzamiento oficial de estos títulos.

Este será el tercer capítulo del libro final. Tenga en cuenta que el repositorio de GitHub se
activará más adelante.

Si tiene comentarios sobre cómo podríamos mejorar el contenido y/


o los ejemplos de este libro, o si nota que falta material en este
capítulo, comuníquese con el editor en [email protected].

... Sí, es cierto que una máquina de Turing puede calcular cualquier función computable
con suficiente memoria y suficiente tiempo, pero la naturaleza tenía que resolver los problemas
en tiempo real. Para ello, utilizó las redes neuronales del cerebro que, como los
ordenadores más potentes del planeta, cuentan con procesadores masivamente paralelos.
Los algoritmos que se ejecuten eficientemente con ellos acabarán ganando.

— Terrence J. Sejnowski (2018)

El aprendizaje profundo se ha convertido recientemente en una palabra de moda por algunas


buenas razones, aunque los intentos de mejorar las prácticas de aprendizaje profundo no son los
primeros de este tipo. Sin embargo, es bastante comprensible por qué el aprendizaje
profundo se ha apreciado durante casi dos décadas. El aprendizaje profundo es un concepto
abstracto, lo que dificulta definirlo en un par de palabras.

A diferencia de las redes neuronales, el aprendizaje profundo tiene una estructura más compleja
y las capas ocultas definen la complejidad. Por lo tanto, algunos investigadores utilizan
Machine Translated by Google

El número de capas ocultas como punto de referencia de comparación para distinguir la red neuronal y el

aprendizaje profundo es una forma útil pero no rigurosa de hacer esta separación. Entonces, una definición

decente deja las cosas claras.

En un nivel alto, el aprendizaje profundo se puede definir como:

Los métodos de aprendizaje profundo son aprendizaje de representación. Nota al pie: [El
aprendizaje de representación nos ayuda a definir un concepto de una manera única.
Por ejemplo, si la tarea es detectar si es un círculo o no, entonces los bordes juegan un papel clave
ya que el círculo no tiene bordes. Entonces, usando el color, la forma y el tamaño, podemos crear una
representación de un objeto. En esencia, así es como funciona el cerebro humano y sabemos que
la estructura de aprendizaje profundo se inspira en su funcionamiento.] métodos con múltiples niveles
de representación, obtenidos componiendo módulos simples pero no lineales, cada uno
de los cuales transforma la representación en un nivel (comenzando con la entrada sin procesar) en
una representación en un nivel superior, ligeramente más abstracto.

—Le Cunn et al. (2015)

Las aplicaciones del aprendizaje profundo se remontan a la década de 1940, en la que se publica la

cibernética y luego el pensamiento conectivista domina los años entre los años 1980 y 1990. Finalmente, el

desarrollo reciente en el aprendizaje profundo, como la retropropagación y las redes

neuronales, ha creado el campo que conocemos como aprendizaje profundo. Bueno, básicamente

estamos hablando de tres oleadas de aprendizaje profundo y ahora resulta tentador preguntar ¿por

qué el aprendizaje profundo está viviendo su apogeo? Goodfellow et al. (2016) enumeran algunas

razones plausibles, que son:

Tamaños de datos crecientes

Aumento de tamaños de modelos

Aumento de la precisión, la complejidad y el impacto en el mundo real

Parece que la tecnología moderna y la disponibilidad de datos allanan el camino para una era de aprendizaje

profundo en la que se proponen nuevos métodos basados en datos para que podamos modelar series

temporales utilizando modelos no convencionales. Este desarrollo ha dado lugar a una nueva ola de Deep

Learning. En Deep Learning destacan dos métodos por su capacidad de incluir períodos de tiempo más largos:

“Recurrent Neural Network” (RNN) y “Long Short­Term Memory” (LSTM).


Machine Translated by Google

RNN y LSTM son dos de ellos. En esta parte, nos concentraremos en la practicidad de estos modelos
en Python después de discutir brevemente los antecedentes teóricos.

Red neuronal recurrente


La red neuronal recurrente tiene una estructura de red neuronal con al menos una conexión de

retroalimentación para que la red pueda aprender secuencias. La conexión de retroalimentación


da como resultado un bucle que nos permite revelar las características no lineales.
Este tipo de conexión nos aporta una propiedad nueva y bastante útil: la Memoria.
Por lo tanto, RNN no solo puede hacer uso de los datos de entrada, sino también de las salidas
anteriores, lo que suena convincente cuando se trata de modelado de series temporales.

RNN viene en muchas formas, como por ejemplo:

Uno a uno: consta de una única entrada y una única salida, lo que lo convierte en el tipo
más básico de RNN.

Uno a muchos: de esta forma, RNN produce múltiples salidas para una sola entrada.

Muchos a uno: a diferencia de la estructura Uno a muchos, Muchos a uno tiene múltiples
entradas para una sola salida.

Muchos a muchos: tiene múltiples salidas y entradas y se conoce como la estructura más
complicada de RNN.

La unidad oculta en RNN se retroalimenta a sí misma en la red neuronal, de modo que RNN tiene, a

diferencia de la red neuronal de retroalimentación, capas recurrentes, lo que lo convierte en un método


adecuado para modelar datos de series de tiempo. Por lo tanto, en RNN, las activaciones de una neurona

provienen de un paso de tiempo anterior, lo que indica que RNN representa el estado de acumulación
de la instancia de red (Buduma, 2017).

Como lo resume Nielsen (2019):

RNN tiene pasos de tiempo uno a la vez de manera ordenada.

El estado de la red permanece igual de un paso de tiempo a otro.


Machine Translated by Google

RNN actualiza su estado según el paso de tiempo.

Estas dimensiones se ilustran en la Figura 3­1. Como se puede ver fácilmente, la estructura RNN en el lado derecho

tiene un paso de tiempo, que es la principal diferencia con la red de alimentación directa.

Figura 3­1. Estructura RNN. 1

RNN tiene entradas tridimensionales, que son:

Tamaño del lote

Pasos de tiempo

Número de característica

El tamaño del lote denota el número de observaciones o el número de filas de un dato.

Los pasos de tiempo son la cantidad de veces que se alimenta el modelo. Finalmente, número de
Machine Translated by Google

La característica es el número de columnas de cada muestra.

En [1]: importar numpy como np


importar pandas como
pd importar
matemáticas
importar fecha y hora
importar yfinance como yf importar
matplotlib.pyplot como plt
importar tensorflow como tf desde tensorflow.keras.models
importar Sequential desde tensorflow.keras.callbacks importar
EarlyStopping desde tensorflow. Importación de keras.layers (denso, abandono, activación,
Aplanar, MaxPooling2D,SimpleRNN)
de sklearn.model_selection importar train_test_split importar
advertencias
advertencias.filterwarnings('ignorar')

En [2]: n_pasos = 13
n_características = 1

En [3]: modelo = Secuencial()


model.add(SimpleRNN(512, activación='relu',
input_shape=(n_pasos, n_características),
return_sequences=True))
model.add(Dropout(0.2))
model.add(Dense(256, activación = 'relu'))
model.add(Flatten())
model.add(Dense(1, activación='linear'))

En [4]: model.compile(optimizer='rmsprop', loss='mean_squared_error',metrics= ['mse'])

Definir el número de pasos para alimentar al modelo RNN.

Definiendo el número de característica como 1.

Llamar a un modelo secuencial para ejecutar RNN.

Identificación del número de neuronas ocultas y función de activación, forma de entrada.

Poner una capa de abandono para evitar el sobreajuste.


Machine Translated by Google

Agregando una capa oculta más con 256 neuronas con función de activación
relu .

Aplanando el modelo para transformar una matriz tridimensional en un vector.

Agregar una capa de salida con función de activación lineal .

Compilando el modelo RNN.

En [5]: def split_sequence(secuencia, n_pasos):


X, y = [], []
para i en rango(len(secuencia)):
end_ix = i + n_steps si
end_ix > len(secuencia) ­ 1:
descanso
seq_x, seq_y = secuencia[i:end_ix], secuencia[end_ix]
X.append(seq_x)
y.append(seq_y)
devuelve np.array(X), np.array(y)

Escribir una función llamada función split_sequence para definir el período de


retrospectiva.

La Figura 3­2 indica los resultados de la predicción del precio de las acciones de
Apple y Microsoft. Aunque el resultado de la predicción parece correcto, no captura los
valores extremos.
Machine Translated by Google
Machine Translated by Google

Figura 3­2. Resultados de predicción de RNN

Incluso si podemos tener un rendimiento predictivo satisfactorio, no deben pasarse por alto las
desventajas del modelo RNN. Los principales inconvenientes del modelo.
son:

Problema de gradiente que desaparece o explota. Consulte la nota al margen a


continuación para obtener una explicación detallada.

Entrenar un RNN es una tarea muy difícil ya que requiere una cantidad considerable de
datos.

RNN no puede procesar secuencias muy largas cuando se utiliza la función de activación
tanh .

NOTA
La desaparición del gradiente es un problema común en el aprendizaje profundo y no está diseñado adecuadamente.
El problema del gradiente de desaparición surge si el gradiente tiende a reducirse a medida que realizamos la
retropropagación. Implica que las neuronas aprenden tan lentamente que la optimización se detiene.

A diferencia del problema del gradiente que desaparece, el problema del gradiente explosivo se produce cuando pequeños
cambios en la retropropagación dan como resultado grandes actualizaciones en los pesos durante el proceso de optimización.
Machine Translated by Google

FUNCIONES DE ACTIVACIÓN

Las funciones de activación son ecuaciones matemáticas que se utilizan para


determinar la salida en la estructura de una red neuronal. La función de activación es
una herramienta para introducir no linealidad en las capas ocultas de modo que podamos
modelar los problemas no lineales.

De las funciones de activación, las siguientes son las más famosas:

Sigmoide: esta función de activación nos permite incorporar una pequeña


cantidad de salida a medida que introducimos pequeños cambios en el
modelo. Toma valores entre 0 y 1. La representación matemática del sigmoide
es:

1
sigmoide(x) =
1 + exp(−∑i wixi − b)

donde w es el peso, x denota datos, b representa el sesgo y el subíndice i muestra


las características.

Tanh: Si manejas números negativos, tanh es tu función de activación. A


diferencia de la función sigmoidea, oscila entre ­1 y 1. La fórmula tanh es:

sinh(x)
tanh(x) =
cosh(x)

Lineal: el uso de la función de activación lineal nos permite construir una


relación lineal entre variables independientes y dependientes. La
función de activación lineal toma las entradas y las multiplica por los
pesos y forma las salidas. proporcional a la entrada. Por lo tanto, es una
función de activación conveniente para modelos de series temporales. La
función de activación lineal toma la forma de:

f(x) = wx
Machine Translated by Google

Lineal rectificado: la función de activación lineal rectificada , conocida como


ReLu, puede tomar 0 si la entrada es cero o está por debajo de cero. Si la
entrada es mayor que 0, aumenta en línea con x. Matemáticamente:

ReLu(x) = máx(0, x)
Softmax: es ampliamente aplicable a problemas de clasificación como en
sigmoide porque softmax convierte la entrada en una distribución
probabilística proporcional al exponencial de los números de
entrada:

exp(xi)
softmax(xi) =
∑i exp(xi)

Las desventajas de RNN están bien expuestas por Haviv et al. (2019) como:

Esto se debe a la dependencia de la red de sus estados pasados y, a través de


ellos, de todo el historial de entrada. Esta capacidad tiene un costo: se sabe que los RNN
son difíciles de entrenar (Pascanu et al., 2013a). Esta dificultad se asocia
comúnmente con el gradiente evanescente que aparece cuando se intenta propagar
errores durante largos períodos de tiempo (Hochreiter, 1998). Cuando el entrenamiento
tiene éxito, el estado oculto de la red representa estos recuerdos. Comprender cómo se
forma dicha representación a lo largo del entrenamiento puede abrir nuevas
vías para mejorar el aprendizaje de tareas relacionadas con la memoria.

Memoria a largo y corto plazo La memoria a largo y

corto plazo, LSTM, por sus siglas en inglés, enfoque de aprendizaje profundo, ha sido
desarrollada por Hochreiter y Schmidhuber (1997) y se basa principalmente en la Unidad
Recurrente Cerrada (GRU).

Se propone GRU para abordar el problema del gradiente de desaparición, que es un


problema común en la estructura de la red neuronal y ocurre cuando la actualización del peso
se vuelve demasiado pequeña para crear un cambio significativo en la red. gru
Machine Translated by Google

Consta de dos puertas: Actualizar y restablecer. Cuando se detecta que una observación temprana
es muy importante, no actualizamos el estado oculto. De manera similar, cuando las primeras
observaciones no son significativas, se restablece el estado.

Como comentamos anteriormente, una de las características más atractivas de RNN es su capacidad para
conectar información pasada y presente. Sin embargo, esta capacidad resulta ser un fracaso cuando las
“dependencias a largo plazo” entran en escena. Las dependencias a largo plazo significan que el
modelo aprende de las primeras observaciones.

Por ejemplo, examinemos la siguiente oración:

Los países tienen sus propias monedas como en EE. UU., donde la gente realiza transacciones en dólares.

En el caso de las dependencias cortas, se sabe que la siguiente palabra predicha es sobre una moneda,
pero si se pregunta ¿qué moneda es esa? Entonces, las cosas se complican, ya que podríamos tener
varias monedas en el texto, lo que implica dependencias a largo plazo. Es necesario retroceder mucho
para encontrar algo relevante sobre el país que utiliza el dólar.

LSTM intenta atacar la debilidad de RNN en dependencias a largo plazo de manera que LSTM tenga una
herramienta bastante útil para deshacerse de la información innecesaria para que funcione de
manera más eficiente. LSTM trabaja con puertas, lo que le permite a LSTM olvidar datos
irrelevantes. Estos son:

Olvídate de las puertas

Puertas de entrada

Puertas de salida

Forget Gates se creó para clasificar la información necesaria e innecesaria para que LSTM funcione de
manera más eficiente que RNN. Al hacerlo, el valor de la función de activación, sigmoidea, se vuelve cero
si la información es irrelevante.
La puerta de olvido se puede formular como:

Ft = σ(XtWI + ht−1Wf + bf )
Machine Translated by Google

donde σ es la función de activación, ht−1 es el estado oculto anterior, WI y Wh son pesos y,


finalmente, bf es el parámetro de sesgo en la celda de olvido.

La puerta de entrada se alimenta mediante el paso , y estado oculto del anterior


de tiempo actual, Xt paso de tiempo t − 1. El objetivo de la puerta de entrada es
determinar el alcance de la información que se debe agregar al estado a largo plazo. La puerta de
entrada se puede formular así:

It = σ(XtWI + ht−1Wh + bI )

La puerta de salida básicamente determina el alcance de la salida que debe leerse y funciona de
la siguiente manera:

Ot = σ(XtWO + ht−1WO + bI )

Las puertas no son los únicos componentes de LSTM. Los otros componentes son:

Celda de memoria candidata

Celda de memoria

Estado oculto

La celda de memoria candidata determina en qué medida la información pasa al estado de la


celda. De manera diferente, la función de activación en la celda candidata es tanh y toma la
siguiente forma:

Cˆt = (XtWc + ht−1Wc + bc)

La celda de memoria permite a LSTM recordar u olvidar la información:

Ct = Ft C + t − 1 + It Cˆt

donde es el producto hadamard.

En esta red recurrente, el estado oculto es una herramienta para hacer circular información.
La celda de memoria relaciona la puerta de salida con el estado oculto:

ht = (ct) Ot
Machine Translated by Google

Intentemos predecir el precio de las acciones de Apple y Microsoft utilizando LSTM y veamos
cómo funciona:

En [18]: desde tensorflow.keras.layers importa LSTM

En [19]: n_pasos = 13
n_características = 1

En [20]: modelo = Sequential()


model.add(LSTM(512, activación='relu',
input_shape=(n_steps, n_features),
return_sequences=True))
model.add(Dropout(0.2))
model.add( LSTM(256,activación='relu'))
model.add(Flatten())
model.add(Dense(1, activación='linear'))

En [21]: model.compile(optimizer='rmsprop', loss='mean_squared_error', metrics= ['mse'])

Llamar al modelo LSTM e identificar la cantidad de neuronas y características

En [22]: historia = model.fit(X_aapl, y_aapl,


épocas = 400, tamaño_lote = 150, detallado =
0, división_validación = 0,10)

En [23]: inicio = X_aapl[X_aapl.shape[0] ­ 13]


x_input = inicio
x_input = x_input.reshape((1, n_pasos, n_características))

En [24]: tempList_aapl = [] para i


en el rango (len (diff_test_aapl)):
x_input = x_input.reshape((1, n_steps, n_features)) yhat =
model.predict(x_input, detallado=0) x_input =
np.append(x_input, yhat) x_input =
x_input[1:]
tempList_aapl.append(yhat)
Machine Translated by Google

NOTA
La idea central de la propagación de la media cuadrática, RMSprop para abreviar, es un método de
optimización en el que calculamos el promedio ponderado de gradientes cuadrados y el
promedio exponencial de los cuadrados de gradientes, el promedio móvil de los gradientes
cuadrados para cada peso. Luego, encuentre la diferencia de peso, que se utilizará para calcular el nuevo peso.

2
vt = ρvt−1 + 1 − ρg t

v
Δpeso = − gt √η +

peso+1 = peso + Δpeso

La Figura 3­3 muestra los resultados de la predicción y LSTM parece superar al RNN,
en particular al ajustarse a los valores extremos.
Machine Translated by Google
Machine Translated by Google

Figura 3­3. Resultados de predicción de LSTM

Conclusión
Este capítulo está dedicado a la predicción del precio de las acciones basada en el aprendizaje profundo.
Los modelos utilizados son RNN y LSTM, que tienen capacidad de procesar períodos de
tiempo más largos. Estos modelos no sugieren una mejora notable, pero aún pueden
emplearse para modelar datos de series de tiempo. LSTM considera, en nuestro caso,
un período retrospectivo de 13 pasos para la predicción. Para una extensión, sería
aconsejable incluir múltiples funciones en los modelos basados en aprendizaje profundo,
lo que no está permitido en los modelos de series de tiempo paramétricos.

En la siguiente parte, se analizará la predicción de la volatilidad basada en modelos


paramétricos y de aprendizaje automático para que podamos comparar el
rendimiento de estos modelos.

Recursos adicionales
Artículos citados en este capítulo:

Ding, Daizong, Mi Zhang, Xudong Pan, Min Yang y Xiangnan He.


"Modelado de eventos extremos en la predicción de series de tiempo". En Actas
de la 25ª Conferencia Internacional ACM SIGKDD sobre Descubrimiento de
Conocimiento y Minería de Datos, págs. 2019.

Haviv, Doron, Alexander Rivkind y Omri Barak. "Comprensión y control de la


memoria en redes neuronales recurrentes". Preimpresión de arXiv
arXiv:1902.07275 (2019).

Hochreiter, Sepp y Jürgen Schmidhuber. "Memoria larga y a corto plazo".


Computación neuronal 9, no. 8 (1997): 1735­1780.

LeCun, Yann, Yoshua Bengio y Geoffrey Hinton. "Aprendizaje


profundo." naturaleza 521, núm. 7553 (2015): 436­444.

Libros citados en este capítulo:


Machine Translated by Google

Nielsen, A. Análisis práctico de series de tiempo: predicción con


estadística y aprendizaje automático. (2019).

Patterson, Josh y Adam Gibson. Aprendizaje profundo: el enfoque de un


profesional. O'Reilly Media, Inc., 2017.

Sejnowski, Terrence J. La revolución del aprendizaje profundo. Prensa


Mit, 2018.

1 Patterson y otros. al, 2017. "Aprendizaje profundo: el enfoque de un profesional".


Machine Translated by Google

Parte II. Aprendizaje automático


para riesgos de mercado, crédito,
liquidez y operativos
Machine Translated by Google

Capítulo 4. Predicción de volatilidad basada en


aprendizaje automático

UNA NOTA PARA LOS LECTORES DE PUBLICACIÓN ANTICIPADA

Con los libros electrónicos de lanzamiento anticipado, obtiene libros en su forma más
antigua (el contenido sin editar y sin editar del autor mientras escribe) para que pueda
aprovechar estas tecnologías mucho antes del lanzamiento oficial de estos títulos.

Este será el cuarto capítulo del libro final. Tenga en cuenta que el repositorio de GitHub se
activará más adelante.

Si tiene comentarios sobre cómo podríamos mejorar el contenido y/


o los ejemplos de este libro, o si nota que falta material en este
capítulo, comuníquese con el editor en [email protected].

La característica más crítica de la distribución de rendimiento condicional es


posiblemente su estructura de segundo momento, que es empíricamente la característica
dominante de la distribución que varía en el tiempo. Este hecho ha estimulado una enorme
literatura sobre la modelización y previsión de la volatilidad de los rendimientos.

—Andersen et al. (2003)

“Algunos conceptos son fáciles de entender pero difíciles de definir. Esto también es válido para
la volatilidad”. Esta podría ser una cita de alguien que vivió antes de Markowitz porque la
forma en que modela la volatilidad es muy clara e intuitiva. Markowitz propone su célebre
teoría de la cartera en la que la volatilidad se define como la desviación estándar, de modo
que a partir de entonces las finanzas se han entrelazado más con las matemáticas.

La volatilidad es la columna vertebral de las finanzas en el sentido de que no sólo proporciona


señales de información a los inversores, sino también datos de diversos modelos financieros.
Machine Translated by Google

¿Qué hace que la volatilidad sea tan importante? La respuesta destaca la importancia de la
incertidumbre, que es la principal característica del modelo financiero.

La mayor integración de los mercados financieros ha dado lugar a una incertidumbre


prolongada en los mercados financieros, lo que a su vez subraya la importancia de la
volatilidad, grado en el que cambian los valores de los activos financieros. La volatilidad
se ha utilizado como indicador del riesgo y se encuentra entre las variables más importantes
en muchos campos, como la fijación de precios de activos y la gestión de riesgos. Su fuerte
presencia y latencia hacen que sea incluso obligatorio modelar. Por lo tanto, el Acuerdo
de Basilea entró en vigor en 1996 y la volatilidad como medida de riesgo ha
asumido un papel clave en la gestión del riesgo (Karasan y Gaygisiz, 2020).

Existe una gran y creciente literatura sobre la estimación de la volatilidad después del
innovador estudio de Black (1976), Raju y Ghosh (2004), Andersen y Bollerslev (1997),
Dokuchaev (2014) y De Stefani et al. (2017). Por lo tanto, estamos hablando de una larga
tradición en la predicción de la volatilidad utilizando modelos de tipo ARCH y GARCH en los
que existen ciertos inconvenientes que pueden causar fallas, por ejemplo, agrupamiento de
volatilidad, asimetría de información, etc. Aunque estos problemas se abordan a través de
modelos diferentes, las recientes fluctuaciones en los mercados financieros, junto con el
desarrollo del aprendizaje automático, hacen que los investigadores reconsideren la
estimación de la volatilidad.

En este capítulo, nuestro objetivo es mostrar cómo podemos mejorar el rendimiento


predictivo utilizando un modelo basado en aprendizaje automático. Visitaremos varios
algoritmos de aprendizaje automático, a saber, regresión vectorial de soporte, redes
neuronales y aprendizaje profundo, para que podamos comparar el rendimiento predictivo.

Modelar la volatilidad equivale a modelar la incertidumbre para que podamos


comprender y abordar mejor la incertidumbre, lo que nos permitirá tener una aproximación
suficientemente buena al mundo real. Para evaluar en qué medida el modelo
propuesto tiene en cuenta la situación real, necesitamos calcular la volatilidad del
rendimiento, que también se conoce como volatilidad realizada. La volatilidad
realizada es la raíz cuadrada de la varianza realizada, que es la suma del rendimiento al
cuadrado. La volatilidad realizada se utiliza para calcular el rendimiento del método
de predicción de la volatilidad. Aquí está la fórmula para la volatilidad del rendimiento:
Machine Translated by Google

2
(rn ­μ)
σˆ = √ 1
norte ­ 1 ∑norte
norte=1

donde r y μ son el rendimiento y la media del rendimiento, n es el número de observaciones.

Veamos cómo se calcula la volatilidad del retorno en Python:

En [1]: importar numpy como np


desde scipy.stats importar norma
importar scipy.optimize como opt
importar yfinance como
yf importar pandas
como pd importar
fecha y hora
importar hora desde arch importar
arch_model importar matplotlib.pyplot
como plt desde numba
importar jit desde sklearn.metrics importar
mean_squared_error
importar advertencias advertencias.filterwarnings ( 'ignorar')

En [2]: acciones = '^GSPC'


inicio = fecha y hora. fecha y hora (2010, 1,
1) fin = fecha y hora. fecha y hora (2021,
8, 1) s_p500 = yf.download (acciones, inicio = inicio, fin = fin , intervalo='1d')
[*********************100%********************* ****] 1 de 1 completado

En [3]: ret = 100 * (s_p500.pct_change()[1:]['Adj Close']) realizado_vol


= ret.rolling(5).std()

En [4]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol.index,realized_vol)
plt.title('Volatilidad realizada­ S&P­500')
plt.ylabel('Volatilidad') plt.
xlabel('Fecha')
plt.savefig('images/realized_vol.png') plt.show()

Calcular los rendimientos del S&P­500 en función de los precios de cierre ajustados.

La Figura 4­1 muestra la volatilidad observada del S&P­500 durante el período 2010­2021.
Las observaciones más sorprendentes son los picos en torno a la pandemia de Covid­19.
Machine Translated by Google

Figura 4­1. Volatilidad realizada: S&P­500

La forma en que se estima la volatilidad tiene un impacto innegable en la confiabilidad


y precisión del análisis relacionado. Por lo tanto, este capítulo trata de las técnicas
de predicción de la volatilidad tanto clásicas como basadas en ML con el fin de
mostrar el rendimiento de predicción superior de los modelos basados en
ML. Para comparar los nuevos modelos basados en ML, comenzamos
modelando los modelos de volatilidad clásicos. Algunos modelos clásicos de
volatilidad muy conocidos son, entre otros:

ARCO

GARCIA

GJR­GARCH

EGARCH
Machine Translated by Google

Es hora de profundizar en los modelos clásicos de volatilidad. Comencemos con el


modelo ARCH.

Modelo ARCO
Uno de los primeros intentos de modelar la volatilidad fue propuesto por Engel (1982)
y se conoce como modelo ARCH. El modelo ARCH es un modelo univariado y se basa en
los rendimientos históricos de los activos. El modelo ARCH(p) tiene la siguiente forma:

pag

2
2σt
__
= ω+ ∑ αk(rt−k)
k=1

dónde

rt = σt t

donde se supone que t tiene una distribución normal. En este modelo paramétrico,
necesitamos satisfacer algunos supuestos para tener una varianza estrictamente positiva.
A este respecto, se debe cumplir la siguiente condición:

ω>0

ak ≥ 0

Todas estas ecuaciones nos dicen que ARCH es un modelo univariado y no lineal en el que
la volatilidad se estima con el cuadrado de los rendimientos pasados. Una de las
características más distintivas de ARCH es que tiene la propiedad de una varianza
condicional que varía en el tiempo,1por lo que ARCH puede modelar el
fenómeno conocido como agrupación de volatilidad, es decir, los grandes cambios tienden
a ser seguidos por grandes cambios de cualquier signo. , y los pequeños cambios
tienden a ir seguidos de pequeños cambios, como señala Benoit Mandelbrot (1963). Por lo
tanto, una vez que llega un anuncio importante al mercado, puede generar una gran
volatilidad.
Machine Translated by Google

El siguiente bloque de código muestra cómo trazar la agrupación y cómo se ve:

En [5]: retv = valores.retv

En [6]: plt.figure(figsize=(10, 6))


plt.plot(s_p500.index[1:], ret)
plt.title('Agrupación de volatilidad del S&P­500')
plt.ylabel('Daily devuelve')
plt.xlabel('Fecha')
plt.savefig('images/vol_clustering.png')
plt.show()

Devuelve el marco de datos a una representación numerosa.

De manera similar a los picos en la volatilidad observada, la Figura 4­2 sugiere algunos
movimientos importantes y, como era de esperar, estos altibajos ocurren en torno a eventos
importantes como la pandemia de Covid­19 a mediados de 2020.
Machine Translated by Google

Figura 4­2. Agrupación de volatilidad: S&P­500

A pesar de sus atractivas características como simplicidad, no linealidad, facilidad y ajuste


para el pronóstico, tiene ciertos inconvenientes, que pueden enumerarse como:

Igual respuesta a los shocks positivos y negativos.

Supuestos fuertes como restricciones sobre los parámetros.

Posible error de predicción debido a un ajuste lento a grandes movimientos.

Estos inconvenientes motivan a los investigadores a trabajar en extensiones del


modelo ARCH y Bollerslev (1986) y Taylor (2008) propusieron el modelo GARCH.

Ahora, emplearemos el modelo ARCH para predecir la volatilidad, pero primero


generaremos nuestro propio código Python y luego lo compararemos para ver la diferencia
con el código Python integrado.

En [7]: n = 252
split_date = ret.iloc[­n:].index
Machine Translated by Google

En [8]: sgm2 = ret.var()


K = ret.kurtosis() alfa
= (­3.0 * sgm2 + np.sqrt(9.0 * sgm2 ** 2 ­ 12.0 *
(3.0 * sgm2 ­ K) * K)) / (6 * K)
omega = (1 ­ alfa) * sgm2
parámetros_iniciales = [alfa, omega]
omega,alfa
Fuera[8]: (0.6345749196895419, 0.46656704131150534)

En [9]: @jit(nopython=True, paralelo=True) def


arch_likelihood(initial_parameters, retv):
omega = abs(parámetros_iniciales[0])
alfa = abs(parámetros_iniciales[1])
T = len(retv)
logliks = 0
sigma2 = np.zeros(T)
sigma2[0] = np.var(retv)
para t en rango(1, T):
sigma2[t] = omega + alfa * (retv[ t ­ 1]) ** 2 logliks =
np.sum(0.5 * (np.log(sigma2)+retv ** 2 / sigma2)) devolver logliks

En [10]: logliks = arch_likelihood(initial_parameters, retv) logliks

Fuera[10]: 1453.127184488521

En [11]: def opt_params(x0, retv):


opt_result = opt.minimize(arch_likelihood, x0=x0, args = (retv),
método='Nelder­Mead',
opciones={'maxiter': 5000})
params = opt_result.x
print('\nResultados de la minimización de Nelder­Mead\n{}
\n{}' .format(''.join(['­'] * 28), opt_result))
print('\nParámetros resultantes = {}'.format(params))
devolver parámetros

En [12]: params = opt_params(initial_parameters, retv)

Resultados de la minimización de Nelder­Mead


­­­­­­­­­­­­­­­­­­­­­­­­­­­­
final_simplex: (matriz([[0.70168795, 0.39039044],
[0.70163494, 0.3904423 ],
[0.70163928, 0.39033154]]), matriz ([1385.79241695, 1385.792417 ,
1385.79241907]))
diversión: 1385.7924169507244
mensaje: 'La optimización finalizó exitosamente.'
Machine Translated by Google

nfev: 62
nits: 33
estado: 0
éxito: Verdadero
x: matriz ([0.70168795, 0.39039044])

Parámetros resultantes = [0,70168795 0,39039044]

En [13]: def arch_apply(ret): omega


= params[0] alfa =
params[1]
T = len(ret)
sigma2_arch = np.zeros(T + 1)
sigma2_arch[0] = np.var(ret) para
t en rango(1, T):
sigma2_arch[t] = omega + alpha * ret[t ­ 1] ** 2 devuelve
sigma2_arch

En [14]: sigma2_arch = arch_apply(ret)

Definir la ubicación de división y asignar los datos divididos a la variable de división .

Cálculo de la varianza del S&P­500.

Cálculo de curtosis del S&P­500.

Identificar el valor inicial del coeficiente de pendiente α.

Identificar el valor inicial del término constante ω.

Usar procesamiento paralelo para disminuir el tiempo de procesamiento.

Tomar valores absolutos y asignar los valores iniciales a variables relacionadas.

Identificar los valores iniciales de la volatilidad.

Iterando la varianza del S&P­500.

Cálculo de log­verosimilitud.
Machine Translated by Google

Llamando a la función.

Minimizar la función de probabilidad logarítmica.

Creación de parámetros variables para parámetros optimizados.

Bueno, modelamos la volatilidad a través de ARCH usando nuestro propio método de optimización y
Ecuación ARCO. ¿Qué tal compararlo con el código Python incorporado? Este
El código incorporado se puede importar desde la biblioteca ARCH y es extremadamente fácil
de aplicar. El resultado del código incorporado se proporciona a continuación y resulta que
Estos dos resultados son muy similares entre sí.

En [15]: arch = arch_model(ret, mean='zero', vol='ARCH', p=1).fit(disp='off')


imprimir(arco.summary())
Media cero : resultados del modelo ARCH

==================================================== =====================

========

Dep. Variable: 0,000 Adj Cerrar R cuadrado:

Modelo medio: Ajuste de media cero R­cuadrado:


0.000
Modelo de volumen: Registro de probabilidad de ARCH :
­4063.63
Distribución: AIC normal:
8131.25
Método: BIC de máxima probabilidad:
8143.21
N° Observaciones: 2914

Fecha: Mar, 07 de septiembre de 2021 Df Residuos:


2914
Tiempo: 11:19:08 Modelo Df:
0
Modelo de volatilidad
==================================================== =======================

coef error estándar t P>|t| 95,0% Conf. En t.


­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­­­

omega 0.7018 5.006e­02 14.018 1.214e­44 [ 0.604, 0.800]


alfa[1] 0.3910 7.016e­02 5,573 2,506e­08 [ 0,253, 0,529]
==================================================== =======================

Estimador de covarianza: robusto


Machine Translated by Google

Aunque desarrollar nuestro propio código siempre es útil y mejora nuestra comprensión,
la belleza del código integrado no se limita solo a su simplicidad. Encontrar el valor
de retraso óptimo utilizando el código incorporado es otra ventaja junto con el
procedimiento de ejecución optimizado.

Todo lo que necesitamos es crear un bucle for y definir criterios de información adecuados.
A continuación, se eligen los criterios de información bayesianos (BIC) como método de
selección del modelo y para seleccionar el retraso. La razón por la que se elige BIC es
que, siempre que tengamos muestras lo suficientemente grandes, BIC es una
herramienta confiable para la selección de modelos, como lo discuten Burnham y Anderson
(2002 y 2004). Ahora, iteramos el modelo ARCH de 1 a 5 retrasos.

En [16]: bic_arch = []

para p en el rango (1,5):


arch = arch_model(ret, mean='zero', vol='ARCH', p=p)\ .fit(disp='off')
bic_arch.append(arch.bic)
if arch.bic == np.min( bic_arch):
mejor_param = p

arco = arch_model(ret, media='Constante', vol='ARCH', p=p)\


.fit(disp='off')
print(arch.summary())
pronóstico = arch.forecast(start=split_date[0]) pronóstico_arch
= pronóstico Media constante ­
Resultados del modelo ARCH

==================================================== =====================

========

Dep. Variable: Adj Cerrar R cuadrado:


0,000
Media Modelo: Ajuste de media constante R­cuadrado:
Modelo

de 0,000 volúmenes: Registro de probabilidad de ARCH :


­3691.03
Distribución: AIC normal:
7394.06
Método: BIC de máxima probabilidad:
7429.92
No. Observaciones: 2914

Fecha: Mar, 07 de septiembre de 2021 Df Residuos:


2913
Tiempo: 11:19:11 Modelo Df:
Machine Translated by Google

1
Modelo medio

==================================================== =====================

====
error estándar coef t P>|t| 95,0% Conf. En t.

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

­­­­
mu 0,0852 1,391e­02 6.128 8.877e­10 [5.798e­02,
0,113]
Modelo de volatilidad

==================================================== =====================

====
error estándar coef t P>|t| 95,0% Conf. En t.

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

­­­­

omega 0,2652 2,618e­02 10.130 4.052e­24 [ 0.214,


0.317]
alfa[1] 0,1674 3,849e­02 4.350 1.361e­05 [9.198e­02,
0,243]
alfa[2] 0,2357 3,679e­02 6,406 1,496e­10 [ 0,164,
0,308]
alfa[3] 0,2029 3,959e­02 5.127 2.950e­07 [ 0.125,
0,281]
alfa[4] 0.1910 4.270e­02 4,474 7,687e­06 [ 0,107,
0,275]
==================================================== =====================

====

Estimador de covarianza: robusto

En [17]: rmse_arch = np.sqrt(mean_squared_error(realized_vol[­n:] / 100,


np.sqrt(forecast_arch\
.varianza.iloc[­
len(fecha_dividida):]
/ 100)))
print('El valor RMSE del modelo ARCH es {:.4f}'.format(rmse_arch))
El valor RMSE del modelo ARCH es 0,0896

En [18]: plt.figure(tamañofig=(10, 6))


plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(forecast_arch.variance.iloc[­len(split_date):] / 100,
etiqueta = 'Predicción de volatilidad­ARCH')
plt.title('Predicción de volatilidad con ARCH', tamaño de fuente=12)
plt.leyenda()
Machine Translated by Google

plt.savefig('imagenes/arch.png')
plt.show()

Iterando el parámetro ARCH p durante el intervalo especificado.

Ejecutando el modelo ARCH con diferentes valores de p.

Encontrar el puntaje mínimo de los Criterios de Información Bayesianos para seleccionar el


mejor modelo.

Ejecutando el modelo ARCH con el mejor valor p.

Previsión de la volatilidad basada en el modelo ARCH optimizado.

Calcular la puntuación RMSE.

El resultado de la predicción de la volatilidad basada en nuestro primer modelo se muestra


en la Figura 4­3.
Machine Translated by Google

Figura 4­3. Predicción de volatilidad con ARCH

Modelo GARCH
El modelo GARCH es una extensión del modelo ARCH que incorpora varianza
condicional rezagada. Por lo tanto, ARCH se mejora agregando p número de varianza
condicional retrasada, lo que hace que el modelo GARCH sea multivariado en el
sentido de que es un modelo de promedio móvil autorregresivo para varianza
condicional con p número de rendimientos cuadrados rezagados y q número de
varianza condicional rezagada. GARCH (p, q) se puede formular como:

q pag

2
2σt
__
= ω+ ∑ t−k 2 + αkr
∑ βkσ t­k
k=1 k=1

donde ω, β y α son parámetros a estimar y q y p son el rezago máximo en el modelo.


Para tener GARCH consistente, las siguientes condiciones
Machine Translated by Google

debe contener:

ω>0

β≥0
α≥0
β+α<1

El modelo ARCH no puede capturar la influencia de las innovaciones históricas.


Sin embargo, como modelo más parsimonioso, el modelo GARCH puede explicar el cambio en
las innovaciones históricas porque los modelos GARCH pueden expresarse como un ARCH de
orden infinito. Demostremos cómo se puede mostrar GARCH como un orden infinito de
ARCH.

2σt
__
= ω + αr t­1
2 2
+ βσ t­1
2 2 2
Luego reemplace σt­1 por ω + αr t­2 + βσ t­2
2
2σt
__
2 = ω + αr t−1 + β(ω + αr 2t−2σ t­2)

2 2 22σ
= ω(1 + β) + αr t­1 + βαr t­2 +β t­2)

Ahora, sustituyamos σ math, 2 por ω + αr 2 2


+ βσ t­3 y hacer lo necesario
t­2 t­3
terminamos con:


2σt
__ = ω(1 + β + β 2+. . . ) + α β∑k−1rt−k
k=1

De manera similar al modelo ARCH, hay más de una forma de modelar la volatilidad usando
GARCH en Python. Intentemos desarrollar nuestro propio código basado en Python utilizando
primero la técnica de optimización. A continuación, se utilizará la biblioteca Arch para predecir la
volatilidad.

En [19]: a0 = 0.0001
sgm2 = ret.var()
K = ret.curtosis()
Machine Translated by Google

h = 1 ­ alfa / sgm2 alfa =


np.sqrt(K * (1 ­ h ** 2) / (2.0 * (K + 3))) beta = np.abs(h ­ omega)
omega = (1 ­ omega ) * sgm2
parámetros_iniciales =
np.array([omega, alfa, beta]) print('Los parámetros iniciales para
omega, alfa y beta son \n{}\n{}\n{}'
.formato(omega, alfa, beta))
Los parámetros iniciales para omega, alfa y beta son
0,43471178001576827
0.512827280537482
0.02677799855546381

En [20]: retv = valores.retv

En [21]: @jit(nopython=True, paralelo=True) def


garch_likelihood(initial_parameters, retv): omega =
parámetros_iniciales[0] alfa =
parámetros_iniciales[1] beta =
parámetros_iniciales[2]
T = len(retv)
logliks = 0
sigma2 = np.zeros(T)
sigma2[0] = np.var(retv) para
t en rango(1, T): sigma2[t]
= omega + alfa * (retv[ t ­ 1]) ** 2 + beta * sigma2[t­1]
logliks = np.sum(0.5 * (np.log(sigma2) + retv ** 2 / sigma2)) devuelve logliks

En [22]: logliks = garch_likelihood(initial_parameters, retv)


print('La probabilidad del registro es {:.4f}'.format(logliks))
La probabilidad logarítmica es 1387,7215

En [23]: def garch_constraint(parámetros_iniciales): alfa =


parámetros_iniciales[0] gamma =
parámetros_iniciales[1] beta =
parámetros_iniciales[2] return
np.array([1 ­ alfa ­ beta])

En [24]: límites = [(0.0, 1.0), (0.0, 1.0), (0.0, 1.0)]

En [25]: def opt_paramsG(initial_parameters, retv): opt_result =


opt.minimize(garch_likelihood, x0=initial_parameters,
constraints=np.array([1 ­
alpha ­ beta]), límites=límites, args = (retv),
método='Nelder­Mead',
opciones={'maxiter': 5000})

parámetros = opt_result.x
Machine Translated by Google

print('\nResultados de la minimización de Nelder­Mead\n{}


\n{}'\ .format('­' * 35, opt_result))
print('­' * 35)
print('\nParámetros resultantes = {}'.format(params)) return
params

En [26]: params = opt_paramsG(initial_parameters, retv)

Resultados de la minimización de Nelder­Mead


­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
Final_Simple: (Array ([[0.03918956, 0.17370549, 0.78991502],
[0.03920507, 0.17374466, 0.78987403],
[0.03916671, 0.17377319, 0.78993078],
[0.03917324, 0.17364595, 0.78998753]]), matriz ([979.87109624, 979.8710967 ,
979.87109865, 979.8711147 ]))
diversión: 979.8710962352685
mensaje: 'La optimización finalizó exitosamente.' nfev:
178 nit:
102
estado: 0
éxito: Verdadero
x: matriz([0.03918956, 0.17370549, 0.78991502])
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Parámetros resultantes = [0,03918956 0,17370549 0,78991502]

En [27]: def garch_apply(ret):


omega = params[0]
alfa = params[1]
beta = params[2]
T = len(ret)
sigma2 = np.zeros(T + 1)
sigma2[0] = np.var(ret)
para t en rango(1, T):
sigma2[t] = omega + alfa * ret[t ­ 1] ** 2 + beta * sigma2[t­
1]
devolver sigma2

Los parámetros que obtenemos de nuestro propio código GARCH son aproximadamente:

ω = 0,0375

α = 0,1724

β = 0,7913
Machine Translated by Google

El siguiente código Python incorporado confirma que hicimos un gran trabajo como
Los parámetros obtenidos a través del código incorporado son casi los mismos que los nuestros. Entonces,

Hemos aprendido a codificar modelos GARCH y ARCH para predecir.


volatilidad.

En [28]: garch = arch_model(ret, mean='zero', vol='GARCH', p=1, o=0, q=1)\


.fit(disp='apagado')
imprimir(garch.summary())
Media cero : resultados del modelo GARCH

==================================================== =====================

========

Dep. Variable: Adj Cerrar R cuadrado:


0,000
Modelo medio: Ajuste de media cero R­cuadrado:
0.000
Modelo de volumen: Registro de probabilidad GARCH :
­3657.62
Distribución: AIC normal:
7321.23
Método: BIC de máxima probabilidad:
7339.16
N° Observaciones: 2914

Fecha: Mar, 07 de septiembre de 2021 Df Residuos:


2914
Tiempo: 11:19:28 Modelo Df:
0
Modelo de volatilidad

==================================================== =====================

======
error estándar coef t P>|t| 95,0% Conf. En t.

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

­­­­­­

omega 0,0392 8,422e­03 4.652 3.280e­06


[2.268e­02,5.569e­02]
alfa[1] 0,1738 2,275e­02 7,637 2,225e­14 [ 0,129,
0,218]
beta[1] 0,7899 2,275e­02 34.715 4.607e­264 [ 0,745,
0,835]
==================================================== =====================

======

Estimador de covarianza: robusto


Machine Translated by Google

Es evidente que es fácil trabajar con GARCH(1, 1) pero ¿cómo sabemos


que estos parámetros sean los óptimos. Decidamos el óptimo
conjunto de parámetros dado el valor BIC más bajo.

En [29]: bic_garch = []

para p en el rango (1, 5):


para q en el rango (1, 5):
garch = arch_model(ret, media='cero',vol='GARCH', p=p, o=0, q=q)\
.fit(disp='apagado')
bic_garch.append(garch.bic)
si garch.bic == np.min(bic_garch):
mejor_param = p, q
garch = arch_model(ret, media='cero', vol='GARCH', p=p, o=0, q=q)\
.fit(disp='apagado')
imprimir(garch.summary())
pronóstico = garch.forecast(inicio=fecha_dividida[0])
pronóstico_garch = pronóstico
Media cero : resultados del modelo GARCH

==================================================== =====================

========

Dep. Variable: 0,000 Adj Cerrar R cuadrado:

Modelo medio: Ajuste de media cero R­cuadrado:


0,000
Modelo de Registro de probabilidad GARCH :
volumen: ­3653.12
Distribución: AIC normal:
7324,23
Método: BIC de máxima probabilidad:
7378.03
N° Observaciones: 2914

Fecha: Mar, 07 de septiembre de 2021 Df Residuos:


2914
Hora: 11:19:30 Modelo Df:
0
Modelo de volatilidad

==================================================== =====================

=====
error estándar coef t P>|t| 95,0% Conf. En t.

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

­­­­­
Machine Translated by Google

omega 0,1013 6,895e­02 1.469 0,142 [­3,388e­02,


0,236]
alfa[1] 0,1347 3,680e­02 3.660 2.525e­04 [6.255e­02,
0,207]
alfa[2] 0,1750 0.103 1.707 8.781e­02 [­2.593e­02,
0,376]
alfa[3] 0.0627 0.163 0.386 0.700 [ ­0,256,
0,382]
alfa[4] 0,0655 8.901e­02 0,736 0.462 [ ­0,109,
0,240]
beta[1] 1.7151e­15 0,734 2,337e­15 1.000 [ ­1.438,
1.438]
beta[2] 0.2104 0,298 0.707 0.480 [ ­0,373,
0,794]
beta[3] 0.2145 0.547 0,392 0,695 [ ­0,857,
1.286]
beta[4] 0.0440 0.233 0,189 0.850 [ ­0,412,
0,500]
==================================================== =====================

=====

Estimador de covarianza: robusto

En [30]: rmse_garch = np.sqrt(mean_squared_error(realized_vol[­n:] / 100,


np.sqrt(forecast_garch\
.varianza.iloc[­
len(fecha_dividida):]
/ 100)))
print('El valor RMSE del modelo GARCH es {:.4f}'.format(rmse_garch))
El valor RMSE del modelo GARCH es 0,0878

En [31]: plt.figure(tamañofig=(10,6))
plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(forecast_garch.variance.iloc[­len(split_date):] / 100,
label='Predicción de volatilidad­GARCH')
plt.title('Predicción de volatilidad con GARCH', tamaño de fuente=12)
plt.leyenda()
plt.savefig('imagenes/garch.png')
plt.mostrar()
Machine Translated by Google

Figura 4­4. Predicción de volatilidad con GARCH

Las principales razones para aplicar GARCH al modelado de volatilidad son que los
rendimientos se ajustan bien al modelo GARCH, en parte debido a la agrupación
de volatilidad y GARCH no supone que los rendimientos sean independientes,
lo que permite modelar la propiedad leptocúrtica de los rendimientos. Sin embargo, a
pesar de estas útiles propiedades y su carácter intuitivo, GARCH no es capaz de
responder asimétricamente a las perturbaciones (Karasan y Gaygisiz (2020)).
Para solucionar este problema, Glosten, Jagannathan y Runkle (1993) propusieron GJR­GARCH.

GJR­GARCH
Este modelo funciona bien al modelar los efectos asimétricos de los anuncios
de manera que las malas noticias tienen un impacto mayor que el de las buenas. En
otras palabras, en presencia de asimetría, la distribución de las pérdidas tiene una cola
más gruesa que la distribución de las ganancias. La ecuación del modelo incluye un
parámetro más γ y toma la siguiente forma:
Machine Translated by Google

q pag

2 2 2
2σt = ω+ t­k + γr t−kI( t−1 < 0)) + βkσ ∑ t­k
__
∑ (αkr
k=1 k=1

donde γ controla la asimetría de los anuncios y si


γ = 0, entonces la respuesta al shock pasado es la misma

γ > 0, entonces la respuesta al shock negativo pasado es más fuerte


que la de uno positivo

γ < 0, entonces la respuesta al shock positivo pasado es más fuerte que


la de uno negativo

En [32]: bic_gjr_garch = []

para p en el rango (1, 5):


para q en el rango (1, 5):
gjrgarch = arch_model(ret,mean='zero', p=p, o=1, q=q)\ .fit(disp='off')

bic_gjr_garch.append(gjrgarch.bic) si gjrgarch.bic
== np.min(bic_gjr_garch): best_param = p, q

gjrgarch = arch_model(ret,mean='zero', p=p, o=1, q=q)\ .fit(disp='off')


print(gjrgarch.summary())
pronóstico = gjrgarch.forecast(start=
split_date[0]) Forecast_gjrgarch = pronóstico de media cero ­
Resultados del modelo GJR­GARCH

==================================================== =====================

========

Dep. Variable: 0,000 Adj Cerrar R cuadrado:

Modelo medio: Ajuste de media cero R­cuadrado:


0.000
Modelo de volumen: Registro de probabilidad GJR­GARCH :
­3588.89
Distribución: AIC normal:
7197.78
Método: BIC de máxima probabilidad:
7257.55
N° Observaciones: 2914

Fecha: Mar, 07 de septiembre de 2021 Df Residuos:


Machine Translated by Google

2914
Tiempo: 11:19:35 Modelo Df:
0
Modelo de volatilidad

==================================================== =====================

======
error estándar coef t P>|t| 95,0% Conf. En t.

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

­­­­­­

omega 0,0538 1,510e­02 3.560 3.712e­04


[2.416e­02,8.336e­02]
alfa[1] 8.9183e­03 5.189e­02 0,172 0.864 [­9.277e­02,
0.111]
alfa[2] 0.0000 6.279e­02 0.000 1.000 [ ­0,123,
0,123]
alfa[3] 0.0000 6.520e­02 0.000 1.000 [ ­0,128,
0,128]
alfa[4] 0,0480 4,966e­02 0.966 0,334 [­4,937e­02,
0,145]
gama[1] 0,3271 7,842e­02 4.171 3.029e­05 [ 0,173,
0,481]
beta[1] 0.7296 0,488 1.494 0.135 [ ­0,228,
1.687]
beta[2] 0.0000 0.462 0.000 1.000 [ ­0,905,
0,905]
beta[3] 0.0000 0.370 0.000 1.000 [ ­0,725,
0,725]
beta[4] 0.0103 0,293 3,512e­02 0,972 [ ­0,563,
0,584]
==================================================== =====================

======

Estimador de covarianza: robusto

En [33]: rmse_gjr_garch = np.sqrt(mean_squared_error(realized_vol[­n:] / 100,


np.sqrt(forecast_gjrgarch\
.varianza.iloc[­
len(fecha_dividida):]
/ 100)))
print('El valor RMSE de los modelos GJR­GARCH es
{:.4f}'.format(rmse_gjr_garch))
El valor RMSE de los modelos GJR­GARCH es 0,0880

En [34]: plt.figure(tamañofig=(10, 6))


plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(forecast_gjrgarch.variance.iloc[­len(split_date):] / 100,
Machine Translated by Google

label='Predicción de volatilidad­GJR­GARCH')
plt.title('Predicción de volatilidad con GJR­GARCH', tamaño de fuente=12)
plt.legend()
plt.savefig('images/gjr_garch.png')
plt.show()

Figura 4­5. Predicción de volatilidad con GJR­GARCH

EGARCH
Junto con el modelo GJR­GARCH, EGARCH propuesto por Nelson (1991),
también es una herramienta para controlar el efecto de los anuncios
asimétricos y adicionalmente se especifica en forma logarítmica, no hay
necesidad de poner restricciones para evitar volatilidad negativa.

q q
+∑
pag

|rk−1 | rt­k
2
log(σt ) = ω + ∑ βklogσt­k
2
+ ∑ αi γk
k=1 k=1 k=1
√σ 2 t­k √σ 2 t­k
Machine Translated by Google

La principal diferencia de la ecuación EGARCH es que el logaritmo se toma del


varianza en el lado izquierdo de la ecuación. Esto indica el apalancamiento
efecto que significa que existe una correlación negativa entre activos pasados
rentabilidad y volatilidad. Si γ < 0, implica efecto de apalancamiento y si γ ≠ 0, implica efecto de apalancamiento.

muestra asimetría en la volatilidad.

En [35]: bic_egarch = []

para p en el rango (1, 5):


para q en el rango (1, 5):
egarch = arch_model(ret, media='cero',vol='EGARCH', p=p, o=1, q=q)\
.fit(disp='apagado')
bic_egarch.append(egarch.bic)
si egarch.bic == np.min(bic_egarch):
mejor_param = p, q
egarch = arch_model(ret, media='cero', vol='EGARCH', p=p, o=1, q=q)\
.fit(disp='apagado')
imprimir(egarch.summary())
pronóstico = egarch.forecast(inicio=fecha_dividida[0])
Forecast_egarch = pronóstico
Media cero : resultados del modelo EGARCH

==================================================== =====================

========

Dep. Variable: 0,000 Adj Cerrar R cuadrado:

Modelo medio: Ajuste de media cero R­cuadrado:


0.000
Modelo de volumen: Registro de probabilidad de EGARCH :
­3575.09
Distribución: AIC normal:
7170.17
Método: BIC de máxima probabilidad:
7229.94
N° Observaciones: 2914

Fecha: Mar, 07 de septiembre de 2021 Df Residuos:


2914
Tiempo: 11:19:38 Modelo Df:
0
Modelo de volatilidad

==================================================== =====================

========
error estándar coef t P>|t| 95,0% Conf. En t.
Machine Translated by Google

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

­­­­­­­­
­1.9786e­03 8.231e­03 omega ­0,240 0.810
[­1.811e­02,1.415e­02]
alfa[1] 0,1879 8,662e­02 2.170 3.004e­02 [1.816e­02,
0,358]
alfa[2] 0.0661 0.130 0.508 0,612 [ ­0,189,
0,321]
alfa[3] ­0.0129 0.212 ­6.081e­02 0,952 [ ­0,429,
0,403]
alfa[4] 0,0936 9,336e­02 1.003 0,316 [­8,936e­02,
0,277]
gama[1] ­0,2230 3,726e­02 ­5.986 2.149e­09 [ ­0,296,
­0,150]
beta[1] 0.8400 0.333 2.522 1.168e­02 [ 0,187,
1.493]
beta[2] 4.1051e­14 0,658 6,235e­14 1.000 [ ­1.290,
1.290]
beta[3] 1.2375e­14 0,465 2,659e­14 1.000 [ ­0,912,
0,912]
beta[4] 0.0816 0.202 0.404 0,686 [ ­0,314,
0,478]
==================================================== =====================

========

Estimador de covarianza: robusto

En [36]: rmse_egarch = np.sqrt(mean_squared_error(realized_vol[­n:] / 100,


np.sqrt(forecast_egarch.varianza\
.iloc[­len(fecha_dividida):]
/ 100)))
print('El valor RMSE de los modelos EGARCH es {:.4f}'.format(rmse_egarch))
El valor RMSE de los modelos EGARCH es 0,0895

En [37]: plt.figure(tamañofig=(10, 6))


plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(forecast_egarch.variance.iloc[­len(split_date):] / 100,
label='Predicción de volatilidad­EGARCH')
plt.title('Predicción de volatilidad con EGARCH', tamaño de fuente=12)
plt.leyenda()
plt.savefig('imagenes/egarch.png')
plt.mostrar()
Machine Translated by Google

Figura 4­6. Predicción de volatilidad con GJR­GARCH

Dado el resultado del RMSE, los modelos con mejor y peor rendimiento son GARCH
y ARCO, respectivamente. Pero no hay grandes diferencias entre los
rendimiento del modelo que hemos utilizado anteriormente. En particular, durante
Anuncio de malas/buenas noticias, el desempeño de EGARCH y GJR­GARCH podría
ser diferente debido a la asimetría en el mercado.

Modelo RMSE

ARCO 0.0896

GARCIA 0.0878

GJR­GARCH 0.0880

EGARCH 0.0895
Machine Translated by Google

Hasta ahora, hemos analizado los modelos de volatilidad clásicos, pero a partir de ahora
veremos cómo se pueden utilizar el aprendizaje automático y el enfoque bayesiano para
modelar la volatilidad. En el contexto del aprendizaje automático, las máquinas de vectores de
soporte y las redes neuronales serán los primeros modelos en visitarse. Empecemos.

Regresión de vectores de soporte: las máquinas de vectores de soporte

(SVM) de GARCH son un algoritmo de aprendizaje supervisado, que puede ser aplicable
tanto a la clasificación como a la regresión. El objetivo en SVM es encontrar una línea que
separe dos clases. Suena fácil, pero aquí está la parte desafiante: hay casi
infinitas líneas que se pueden usar para distinguir las clases. Pero buscamos la recta óptima
por la que se puedan discriminar perfectamente las clases.

En álgebra lineal, la línea óptima se llama hiperplano, que maximiza la distancia entre los
puntos más cercanos al hiperplano pero que pertenecen a diferentes clases. La
distancia entre los dos puntos, es decir, los vectores de soporte, se conoce como margen.
Entonces, en SVM, lo que intentamos hacer es maximizar el margen entre los vectores de
soporte.

La SVM para clasificación está etiquetada como Clasificación de vectores de soporte (SVC).
Manteniendo todas las características de SVM, puede ser aplicable a la regresión.
Nuevamente, en regresión, el objetivo es encontrar el hiperplano que minimice el error y
maximice el margen. Este método se llama Regresión de vectores de soporte (SVR) y, en
esta parte, aplicaremos este método al modelo GARCH.
De la combinación de estos dos modelos surge un nombre diferente: SVR­GARCH.
Machine Translated by Google

FUNCIÓN DEL NÚCLEO

¿Qué sucede si los datos con los que estamos trabajando no pueden ser
separables linealmente? Eso sería un gran dolor de cabeza para nosotros, pero no te
preocupes, tenemos funciones del Kernel para solucionar este problema. Es un método
agradable y sencillo para modelar datos no lineales y de alta dimensión. Los pasos que
damos en Kernel SVM son:

1. Mueva los datos a una dimensión alta.

2. Encuentra el hiperplano adecuado

3. Volver a los datos iniciales

Para hacer eso usamos funciones del kernel. Usar la idea de mapa de características
indica que nuestras variables originales se asignaron a un nuevo conjunto de cantidades y se
pasaron al algoritmo de aprendizaje.

Finalmente, en lugar de datos de entrada utilizamos las siguientes funciones principales del Kernel en

los procedimientos de optimización:

Núcleo polinómico: K(x, z) = (x T z + b).


2

Núcleo de base radial (gaussiano): K(x, z) = exp(− |x−z| 2 ). 2σ

Núcleo exponencial: K(x, z) = exp(− |x−z| σ ). donde x es


2.
entrada, b es sesgo o constante, y z es una combinación lineal de x

El siguiente código nos muestra los preparativos antes de ejecutar SVR­GARCH en Python.
El paso más crucial aquí es obtener variables independientes, que son la volatilidad
realizada y el cuadrado de los rendimientos históricos.

En [38]: desde sklearn.svm importar SVR


desde scipy.stats importar uniforme como sp_rand
desde sklearn.model_selection importar RandomizedSearchCV
desde sklearn.metrics importar mean_squared_error
Machine Translated by Google

En [39]: realizado_vol = ret.rolling(5).std()


realizado_vol = pd.DataFrame(realizado_vol)
realizado_vol.reset_index(drop=True, inplace=True)

En [40]: return_svm = ret ** 2


return_svm = return_svm.reset_index() del
return_svm['Fecha']

En [41]: X = pd.concat([realized_vol, return_svm], eje=1, ignore_index=True)


X = X[4:].copiar()
X = X.reset_index()
X.drop('índice', eje=1, inplace=True)

En [42]: realizado_vol = realizado_vol.dropna().reset_index()


realizado_vol.drop('índice', eje=1, inplace=True)

En [43]: svr_poly = SVR(kernel='poly')


svr_lin = SVR(kernel='linear')
svr_rbf = SVR(kernel='rbf')

Calcular la volatilidad realizada y asignarle una nueva variable llamada


realizada_vol.

Creando nuevas variables para diferentes kernels SVR.

Ejecutemos y veamos nuestra primera aplicación SVR­GARCH con kernel lineal.


El error cuadrático medio (RMSE) es la métrica que se utilizará para comparar.

En [44]: para_grid = {'gamma': sp_rand(), 'C':


sp_rand(),
'epsilon': sp_rand()} clf
= RandomizedSearchCV(svr_lin, para_grid)
clf.fit(X.iloc[:­ n].values,
realizado_vol.iloc[1:­(n­1)].values.reshape(­1,))
predict_svr_lin = clf.predict(X.iloc[­n:])

En [45]: predict_svr_lin = pd.DataFrame(predict_svr_lin)


predict_svr_lin.index = ret.iloc[­n:].index

En [46]: rmse_svr = np.sqrt(mean_squared_error(realized_vol.iloc[­n:] / 100,


predict_svr_lin / 100))
print('El valor RMSE de SVR con Linear Kernel es
{:.6f}'.format(rmse_svr))
Machine Translated by Google

El valor RMSE de SVR con Linear Kernel es 0,000648

En [47]: realizado_vol.index = ret.iloc[4:].index

En [48]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(predict_svr_lin / 100, label='Predicción de volatilidad­SVR­GARCH' ) plt.title('Predicción
de volatilidad con SVR­GARCH (lineal)', tamaño de fuente=12) plt.legend() plt.savefig('images/

svr_garch_linear.png') plt.show()

Identificación del espacio de hiperparámetros para el ajuste.

Aplicación de ajuste de hiperparámetros con RandomizedSearchCV.

Ajuste de SVR­GARCH con kernel lineal a los datos.

Predecir las volatilidades en función de las últimas 252 observaciones y almacenarlas


en predict_svr_lin.
Machine Translated by Google

Figura 4­7. Predicción de volatilidad con el kernel lineal SVR­GARCH

La Figura 4­7 muestra los valores predichos y la observación real. A simple vista, se
puede decir que SVR­GARCH funciona bien. Como puede adivinar, el kernel lineal funciona
bien si el conjunto de datos es linealmente separable y también es la sugerencia de _Occam's
3
Razor_. ¿Qué pasa si no es así? Sigamos con RBF y núcleos polinomiales. El primero
utiliza curvas elípticas alrededor de las observaciones y el segundo, a diferencia de los dos
primeros, también se centra en las combinaciones de muestras. Veamos ahora cómo
funcionan.

A continuación se puede encontrar la aplicación SVR­GARCH con kernel RBF, una función
que proyecta datos en un nuevo espacio vectorial. Desde el punto de vista práctico, la
aplicación SVR­GARCH con diferentes núcleos no es un proceso que requiere mucha
mano de obra, todo lo que necesitamos es cambiar el nombre del núcleo.

En [49]: para_grid ={'gamma': sp_rand(),


'C': sp_rand(),
'épsilon': sp_rand()} clf
= RandomizedSearchCV(svr_rbf, para_grid)
Machine Translated by Google

clf.fit(X.iloc[:­n].values,
realizado_vol.iloc[1:­(n­1)].values.reshape(­1,)) predict_svr_rbf
= clf.predict(X.iloc[­n] :])

En [50]: predict_svr_rbf = pd.DataFrame(predict_svr_rbf)


predict_svr_rbf.index = ret.iloc[­n:].index

En [51]: rmse_svr_rbf = np.sqrt(mean_squared_error(realized_vol.iloc[­n:] / 100,


predict_svr_rbf / 100)) print('El
valor RMSE de SVR con RBF Kernel es
{:.6f}'.format(rmse_svr_rbf))
El valor RMSE de SVR con RBF Kernel es 0,000942

En [52]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(predict_svr_rbf / 100, label='Predicción de volatilidad­SVR_GARCH') plt .title('Predicción
de volatilidad con SVR­GARCH (RBF)', tamaño de fuente=12) plt.legend()

plt.savefig('images/svr_garch_rbf.png') plt.show()

Tanto la puntuación RMSE como la visualización sugieren que SVR­


GARCH con kernel lineal supera a SVR­GARCH con kernel RBF. El
RMSE de SVR­GARCH con núcleos lineales y RBF es 0,000453 y
0,000986, respectivamente. Entonces, SVR con kernel lineal funciona bien.
Machine Translated by Google

Figura 4­8. Predicción de volatilidad con el kernel SVR­GARCH RBF

Por último, se emplea SVR­GARCH con núcleo polinómico, pero resulta que
tiene el RMSE más bajo, lo que implica que es el núcleo con peor rendimiento
entre estas tres aplicaciones diferentes.

En [53]: para_grid = {'gamma': sp_rand(), 'C':


sp_rand(),
'epsilon': sp_rand()} clf =
RandomizedSearchCV(svr_poly, para_grid)
clf.fit(X.iloc[:­ n].values,
realizado_vol.iloc[1:­(n­1)].values.reshape(­1,))
predict_svr_poly = clf.predict(X.iloc[­n:])

En [54]: predict_svr_poly = pd.DataFrame(predict_svr_poly)


predict_svr_poly.index = ret.iloc[­n:].index

En [55]: rmse_svr_poly = np.sqrt(mean_squared_error(realized_vol.iloc[­n:] / 100,


predict_svr_poly / 100))
print('El valor RMSE de SVR con Kernel polinómico es {:.6f}'\
.formato(rmse_svr_poly))
El valor RMSE de SVR con kernel polinómico es 0,005291
Machine Translated by Google

En [56]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol/100, label='Volatilidad realizada')
plt.plot(predict_svr_poly/100, label='Predicción de volatilidad­SVR­GARCH' )
plt.title('Predicción de volatilidad con SVR­GARCH (polinomio)', tamaño de fuente=12)
plt.legend()
plt.savefig('images/svr_garch_poly.png')
plt.show()

Figura 4­9. Predicción de volatilidad con el núcleo polinómico SVR­GARCH

Red neuronal
La red neuronal (NN) es la piedra angular del aprendizaje profundo. En NN, los datos se
procesan en múltiples etapas para tomar una decisión. Cada neurona toma el resultado de
un producto escalar como entrada y lo utiliza como entrada en la función de activación
para tomar una decisión.

z = w1x1 + w2x2 + b
Machine Translated by Google

donde b es el sesgo, w es el peso y x son los datos de entrada.

Durante este proceso, los datos de entrada se llevan a cabo diversas manipulaciones
matemáticas en capas ocultas y de salida. En términos generales, NN tiene tres tipos de capas:

Capa de entrada

capa oculta

Capa de salida

La capa de entrada incluye datos sin procesar. Al pasar de la capa de entrada a la capa oculta,
aprendemos coeficientes. Puede haber una o más capas ocultas según la estructura de
la red. Mientras más capa oculta tenga la red, más complicada será. La capa oculta, ubicada entre
las capas de entrada y salida, realiza una transformación no lineal mediante la función de activación.

Finalmente, la capa de salida es la capa en la que se produce la salida y se toman las decisiones.

En el aprendizaje automático, el descenso de gradiente es la herramienta que se aplica para


minimizar la función de costo, pero emplear solo el descenso de gradiente en la red neuronal no
es factible debido a la estructura en forma de cadena de la red neuronal. Así, se propone
un nuevo concepto conocido como retropropagación para minimizar la función de costos.
La idea de retropropagación se basa en el error de cálculo entre la salida observada y la
real y pasa este error a la capa oculta. Entonces, retrocedemos y la ecuación principal toma la
forma:

δJ
l δ= yo

δz
j

donde z es la transformación lineal y δ representa el error. Hay mucho más que decir pero para
mantener el rumbo me detengo aquí. Para aquellos que quieran profundizar más en las
matemáticas detrás de Neural Network, consulte Wilmott (2013) y Alpaydin (2020).
Machine Translated by Google

DESCENSO DE GRADIENTE

Supongamos que estamos en la cima de la colina y tratamos de llegar a la meseta en la


que minimizamos la función de costos. Formalmente, Gradient Descent es un algoritmo
de optimización que se utiliza para buscar el mejor espacio de parámetros (w, b) que
minimiza la función de costos mediante la siguiente regla de actualización:

δJ θt+1 = θt −
λ δθt

donde θ(w, b) es la función del peso, w, y el sesgo, b. J es la función de costos y λ es la


tasa de aprendizaje, que es un número constante que decide qué tan rápido queremos
minimizar la función de costos. Bueno, en cada iteración actualizamos los parámetros para
minimizar el error.

En resumen, el algoritmo de descenso de gradiente funciona de la siguiente manera:

1. Seleccione los valores iniciales para w y b.

2. Da un paso λ en la dirección opuesta a donde se encuentra el gradiente.


puntos.

3. Actualice w y b en cada iteración.

4. Repita desde el paso 2 hasta la convergencia.

Ahora, aplicamos la predicción de volatilidad basada en redes neuronales


utilizando el módulo MLPRegressor de scikit­learn Python, aunque tenemos varias
4 redes neuronales en Python. Dada la estructura de red neuronal que
opciones para ejecutar
presentamos, el resultado se muestra a continuación.

En [57]: de sklearn.neural_network import MLPRegressor


NN_vol = MLPRegressor(learning_rate_init=0.001, random_state=1)
para_grid_NN = {'hidden_layer_sizes': [(100, 50), (50, 50), (10, 100)],
'max_iter': [500, 1000],
'alfa': [0.00005, 0.0005 ]} clf =
RandomizedSearchCV(NN_vol, para_grid_NN)
clf.fit(X.iloc[:­n].values,
Machine Translated by Google

realizado_vol.iloc[1:­(n­1)].values.reshape(­1, ))
NN_predicciones = clf.predict(X.iloc[­n:])

En [58]: NN_predicciones = pd.DataFrame(NN_predicciones)


NN_predictions.index = ret.iloc[­n:].index

En [59]: rmse_NN = np.sqrt(mean_squared_error(realized_vol.iloc[­n:] / 100, NN_predictions /


100))
print('El valor RMSE de NN es {:.6f}'.format(rmse_NN))
El valor RMSE de NN es 0,000583

En [60]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol / 100, label='Volatilidad realizada')
plt.plot(NN_predictions / 100, label='Predicción de volatilidad­NN') plt .title('Predicción
de volatilidad con red neuronal', tamaño de fuente=12) plt.legend() plt.savefig('images/
NN.png')
plt.show()

Importando la biblioteca MLPRegressor .

Configuración del modelo de red neuronal.

5
Ajuste del modelo de red neuronal a los datos de entrenamiento.

Predecir las volatilidades en función de las últimas 252 observaciones y almacenarlas en


la variable NN_predictions .

La Figura 4­10 muestra el resultado de la predicción de volatilidad según el modelo de red


neuronal. A pesar de su rendimiento razonable, podemos jugar con la cantidad de neuronas
ocultas para encontrar y generar un modelo de aprendizaje profundo. Para ello, podemos
aplicar la biblioteca Keras, interfaz Python para redes neuronales artificiales.
Machine Translated by Google

Figura 4­10. Predicción de volatilidad con red neuronal

Ahora es el momento de predecir la volatilidad mediante el aprendizaje profundo. Basado


en Keras, es fácil configurar la estructura de la red. Todo lo que necesitamos es
determinar el número de neuronas de la capa específica. Aquí, el número de neuronas
para la primera y segunda capa oculta es 256 y 128, respectivamente. Como la
volatilidad es de tipo continuo, solo tenemos una neurona de salida.

En [61]: importar tensorflow como tf


desde tensorflow importar keras
desde tensorflow.keras importar capas

En [62]: modelo = keras.Sequential(


[capas.Dense(256, activación="relu"),
capas.Dense(128, activación="relu"),
capas.Dense(1, activación="lineal"),])

En [63]: model.compile(loss='mse', optimizador='rmsprop')

En [64]: epochs_trial = np.arange(100, 400, 4)


lote_trial = np.arange(100, 400, 4)
Machine Translated by Google

DL_pred = []
DL_RMSE =
[] para i, j, k en zip(rango(4), epochs_trial, lote_trial):
model.fit(X.iloc[:­n].values,
realizado_vol.iloc[1:­(n­1)].values.reshape(­1,),
lote_size=k, epochs=j, detallado=False)
DL_predict = model.predict(np.asarray(X.iloc[­n:]))
DL_RMSE.append(np.sqrt(mean_squared_error(realized_vol.iloc[­n:] / 100,
DL_predict.flatten() / 100)))
DL_pred.append(DL_predict)
print('DL_RMSE_{}:{:.6f}'.format(i+1, DL_RMSE[i]))
DL_RMSE_1:0.000524
DL_RMSE_2:0.001118
DL_RMSE_3:0.000676
DL_RMSE_4:0.000757

En [65]: DL_predict = pd.DataFrame(DL_pred[DL_RMSE.index(min(DL_RMSE))])


DL_predict.index = ret.iloc[­n:].index

En [66]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol / 100,label=' Volatilidad realizada ')
plt.plot(DL_predict / 100,label='Predicción de volatilidad­DL')
plt .title('Predicción de volatilidad con aprendizaje profundo', tamaño de
fuente=12)
plt.legend() plt.savefig('images/
DL.png') plt.show()

Configurar la estructura de la red decidiendo el número de capas y neuronas.

Compilación de modelo con pérdida y optimizador.

Decidir la época y el tamaño del lote usando np.arange.

Adaptación del modelo de aprendizaje profundo.

Predecir la volatilidad en función de los pesos obtenidos de la fase de entrenamiento.

Calcular la puntuación RMSE aplanando las predicciones.

Resulta que obtenemos una puntuación RMSE mínima a medida que aumentamos el tamaño
de la capa, lo cual es bastante comprensible porque la mayoría de las veces el número de capas y
Machine Translated by Google

El rendimiento del modelo va de la mano hasta un punto en el que el modelo tiende a


sobreajustarse. Determinar el número adecuado de capas para datos específicos es clave en el
aprendizaje profundo en el sentido de que dejamos de agregar más capas antes de que el
modelo entre en el problema de sobreajuste.

La Figura 4­11 muestra el resultado de la predicción de la volatilidad derivado del siguiente código
e implica que el aprendizaje profundo también proporciona una herramienta sólida para
modelar la volatilidad.

Figura 4­11. Predicción de volatilidad con aprendizaje profundo

Enfoque bayesiano
La forma en que abordamos la probabilidad es de importancia central en el sentido de que
distingue el enfoque clásico (o frecuentista) del bayesiano.
Según el primer método, la frecuencia relativa convergerá a la probabilidad real. Sin embargo,
la aplicación bayesiana se basa en lo subjetivo.
Machine Translated by Google

interpretación. A diferencia de los frecuentistas, los estadísticos bayesianos


consideran que la distribución de probabilidad es incierta y la revisan a medida que llega
nueva información.

Debido a la diferente interpretación de la probabilidad de estos dos enfoques, la verosimilitud,


definida como, dado un conjunto de parámetros, la probabilidad del evento observado, se
calcula de manera diferente.

A partir de la función de densidad conjunta, podemos dar la representación


matemática de la función de verosimilitud:

L (θ|x1, x2, . . . , xp) =Pr (x1, x2, . . . , xp|θ)

Entre los posibles valores de θ , lo que intentamos hacer es decidir cuál es más probable.
Según el modelo estadístico propuesto por la función de verosimilitud, los datos observados
x1, . . . , xp es el más probable.

De hecho, está familiarizado con el método basado en el enfoque, que es la estimación


de máxima verosimilitud. Habiendo definido la principal diferencia entre los enfoques
bayesiano y frecuentista, es hora de profundizar más en el teorema de Bayes.

El enfoque bayesiano del

teorema de Bayes se basa en la distribución condicional, que establece que la


probabilidad mide el grado en que uno tiene información sobre un evento incierto.
Entonces, la aplicación bayesiana sugiere una regla que puede usarse para actualizar las
creencias que uno tiene a la luz de nueva información:

La estimación bayesiana se utiliza cuando tenemos información previa sobre un


parámetro. Por ejemplo, antes de mirar una muestra para estimar la media de una
distribución, podemos tener alguna creencia previa de que está cerca de 2, entre 1 y 3.
Esas creencias previas son especialmente importantes cuando tenemos una
muestra pequeña. En tal caso, nos interesa combinar lo que nos dicen los
datos, es decir, el valor calculado a partir de la muestra, y nuestra información
previa.
— (Rachev et al., 2008)
Machine Translated by Google

De manera similar a la aplicación frecuentista, la estimación bayesiana se basa en la


densidad de probabilidad Pr (x|θ). Sin embargo, como hemos comentado antes, la forma en
que los métodos bayesianos y frecuentistas tratan el conjunto de parámetros θ de manera diferente.
El frecuentista supone que θ es fijo, mientras que, en el entorno bayesiano, se toma como una
variable aleatoria, cuya probabilidad se conoce como densidad previa Pr (θ). ¡Oh, no!
Tenemos otro término diferente pero no te preocupes, es fácil de entender.

A la luz de esta información, podemos estimar L (x|θ) usando la densidad previa Pr (θ) y
obtenemos la siguiente fórmula. Prior se emplea cuando necesitamos estimar la distribución
condicional de los parámetros dadas las observaciones.

L (x1, x2, . . . , xp|θ) Pr (θ)


Pr (θ|x1, x2, . . . , xp) =
Pr (x1, x2, . . . , xp)

L (datos|θ) Pr (θ)
Pr (θ|datos) =
Pr (datos)

dónde

Pr (θ|datos) es la densidad posterior, que nos da la información sobre los parámetros


dados los datos observados.

L (datos|θ) es la función de verosimilitud, que estima la probabilidad de los


datos dados los parámetros.

Pr (θ) es probabilidad previa. Es la probabilidad de los parámetros.


Lo primero son básicamente las creencias iniciales sobre las estimaciones.

Finalmente, Pr es la evidencia, que se utiliza para actualizar lo anterior.

En consecuencia, el teorema de Bayes sugiere que la densidad posterior es directamente


proporcional a los términos anterior y de probabilidad, pero está inversamente relacionada con
el término de evidencia. Como existe evidencia para escalar, podemos describir esto
procesar como:
Machine Translated by Google

Posterior Probabilidadxanterior

donde significa “es proporcional a”

En este contexto, el teorema de Bayes suena atractivo, ¿no? Bueno, lo es, pero tiene un costo,
que es la intratabilidad analítica. Incluso si el teorema de Bayes es teóricamente intuitivo,
en general es difícil de resolver analíticamente. Éste es el principal inconveniente de la amplia
aplicabilidad del teorema de Bayes. Sin embargo, la buena noticia es que los métodos
numéricos proporcionan métodos sólidos para resolver este modelo probabilístico.

Entonces, se proponen algunos métodos para abordar la cuestión computacional del teorema
de Bayes. Estos métodos proporcionan una solución aproximada, que se puede enumerar como:

Aproximación de cuadratura

Estimación máxima a posteriori

Enfoque de cuadrícula

Enfoque basado en muestreo

Metrópolis­Hastings

Muestra de Gibbs

Muestreador sin giro en U

De estos enfoques, limitemos nuestra atención al algoritmo de Metropolis­Hastings, que será


nuestro método a utilizar para modelar el teorema de Bayes. El método Metropolis­
Hastings (MH) se basa en la cadena de Markov Monte Carlo (MCMC). Además, la estimación
máxima a posteriori se analizará en el [Enlace a continuación]. Entonces, antes de seguir
adelante, sería mejor hablar sobre el método MCMC.

Cadena de Markov Montecarlo

La Cadena de Markov es un modelo para describir las probabilidades de transición entre


estados, lo cual es una regla de juego. Una cadena se llama Markoviana si
Machine Translated by Google

La probabilidad del estado actual st depende sólo del estado más reciente st­1.

Pr (st|st−1, st−2, . . . , st−p) =Pr (st|st−1)

Por lo tanto, MCMC se basa en la cadena de Markov para encontrar el espacio de parámetros θ
con la mayor probabilidad posterior. A medida que crece el tamaño de la muestra, los valores de
los parámetros se aproximan a la densidad posterior.

D
lím θ j →Pr (θ|x)
j→+∞

donde D se refiere a la aproximación distributiva. Los valores obtenidos del espacio de parámetros se
pueden utilizar para hacer inferencias sobre posterior. En pocas palabras, el método MCMC nos
ayuda a recopilar muestras iid de la densidad posterior para que podamos calcular la probabilidad
posterior.

Para ilustrarlo, podemos referirnos a la Figura 4­12. Esta cifra nos dice la probabilidad de pasar de un
estado a otro. En aras de la simplicidad, establecemos la probabilidad en 0,2, lo que indica, por
ejemplo, que la transición del estudio al sueño tiene una probabilidad de 0,2.

En [67]: importar quantecon como qe


desde quantecon importar MarkovChain
importar networkx como
nx desde pprint importar pprint

En [68]: P = [[0,5, 0,2, 0,3], [0,2, 0,3,


0,5], [0,2, 0,2, 0,6]]

mc = qe.MarkovChain(P, ('estudiando', 'viajando', 'durmiendo'))


mc.is_irreducible
Out[68]: True

En [69]: estados = ['estudiando', 'viajando', 'durmiendo']


problemas_iniciales = [0.5, 0.3, 0.6]
espacio_estado = pd.Series(probs_iniciales, índice=estados, nombre='estados')

En [70]: q_df = pd.DataFrame(columnas=estados, índice=estados)


q_df = pd.DataFrame(columnas=estados, índice=estados)
q_df.loc[estados[0]] = [0.5, 0.2, 0.3]
q_df.loc[estados[1]] = [0,2, 0,3, 0,5]
Machine Translated by Google

q_df.loc[estados[2]] = [0,2, 0,2, 0,6]

En [71]: def _get_markov_edges(Q):


bordes = {}
para col en Q.columns:
para idx en Q.index:
bordes[(idx,col)] = Q.loc[idx,col]
bordes de retorno
bordes_wts = _get_markov_edges(q_df)
pprint(edges_wts)
{('durmiendo', 'durmiendo'): 0.6,
('durmiendo', 'estudiando'): 0.2,
('durmiendo', 'viajando'): 0.2,
('estudiando ', 'dormir'): 0,3,
('estudiar', 'estudiar'): 0,5,
('estudiar', 'viajar'): 0,2, ('viajar',
'dormir'): 0,5, ('viajar', 'estudiar'):
0,2, ('viajar', 'viajar'): 0,3}

En [72]: G = nx.MultiDiGraph()
G.add_nodes_from(estados)
para k, v en bordes_wts.items():
tmp_origin, tmp_destination = k[0], k[1]
G.add_edge(tmp_origin, tmp_destination, peso=v, etiqueta=v)

pos = nx.drawing.nx_pydot.graphviz_layout(G, prog='dot')


nx.draw_networkx(G, pos)
edge_labels = {(n1, n2):d['label'] para n1, n2, d en G. bordes(datos=True)}
nx.draw_networkx_edge_labels(G , pos, edge_labels=edge_labels)
nx.drawing.nx_pydot.write_dot(G, 'mc_states.dot')
Machine Translated by Google

Figura 4­12. Interacciones de diferentes estados.

Hay dos métodos MCMC comunes: Metropolis­Hastings y Gibbs Sampler. Aquí profundizamos
en el primero.

Metropolis­Hastings

Metropolis­Hastings (MH) nos permite tener un procedimiento de muestreo eficiente con dos
pasos: primero extraemos una muestra de la densidad de la propuesta y, en el segundo
paso, decidimos aceptar o rechazar.

Sea q(θ θ t−1) una densidad de propuesta y θ un espacio de parámetros. El algoritmo completo
de MH se puede resumir como:

1. Seleccione el valor inicial para θ 1 del espacio de parámetros θ


Machine Translated by Google

2. Seleccione un nuevo valor de parámetroθ 2 de la densidad de propuesta, que


puede ser, para mayor facilidad, distribución gaussiana o uniforme.

3. Calcule la siguiente probabilidad de aceptación:

θt −1)
Pra (θ * ,
θ t−1) = min(1, p(θ
p(*)/q(θ
θ t−1)/q(θ
* t−1 θ *) )

4. Si Pra * , θ t−1) es mayor que un valor de muestra extraído de uniforme


(distribución θ U(0,1).

5. Repita desde el paso 2.

Bueno, parece intimidante pero no lo seas. Tenemos código incorporado en Python que
facilita mucho la aplicabilidad del algoritmo MH. Usamos la biblioteca PyFlux para
hacer uso del teorema de Bayes. Apliquemos el algoritmo MH para predecir la volatilidad.

En [73]: importar pyflux como pf


de scipy.stats importar curtosis

En [74]: modelo = pf.GARCH(ret.values, p=1, q=1)


print(model.latent_variables)
model.adjust_prior(1, pf.Normal())
model.adjust_prior(2, pf.Normal ()) x =
model.fit(método='MH', iteraciones='1000') print(x.summary())

Transformada dist VI de Previo Hiperparámetros previos


variable latente de índice
======== ========================= ================

========================== ========== ==========

0 Vol constante Normal mu0: 0, sigma0: 3


Normal Exp
1 q(1) Normal mu0: 0, sigma0: 0,5
Normalp logit
2 (1) Normal mu0: 0, sigma0: 0,5
logit normal
3 Devoluciones constantes Normal mu0: 0, sigma0: 3
Normal Ninguno

La tasa de aceptación de Metropolis­Hastings es 0,00285 La


tasa de aceptación de Metropolis­Hastings es 0,2444
Machine Translated by Google

¡Sintonización completa! Ahora muestreo.


La tasa de aceptación de Metropolis­Hastings es 0,237925
GARCH(1,1)

==================================================== =====

====================================================

Variable dependiente: Serie Método: Metrópolis


Hastings
Fecha de inicio: 1 Registro no normalizado
Posterior: ­3635.1999
Fecha de finalización: 2913 AIC:
7278.39981852521
Número de observaciones: 2913 BIC:
7302.307573553048
==================================================== =====================

======================================
Variable latente Mediana Significar

Intervalo de credibilidad del 95%


======================================== ========== ========

=================== ==========================

Vol constante 0.0425 0.0425


(0,0342 | 0,0522)
q(1) 0,1966 0,1981
(0,1676 | 0,2319)
pag(1) 0.7679 0,767
(0,7344 | 0,7963)
Devoluciones constantes 0.0854 0.0839
(0,0579 | 0,1032)
==================================================== =====================

======================================
Ninguno

En [75]: model.plot_z([1, 2])


model.plot_fit(tamaño de figura=(15, 5))
model.plot_ppc(T=curtosis, nsims=1000)

Configurando el modelo GARCH usando la biblioteca PyFlux.

Impresión de la estimación de variables latentes (parámetros).

Ajustando los priors para las variables latentes del modelo.

Ajuste del modelo mediante el proceso MH.


Machine Translated by Google

Trazar las variables latentes.

Trazar el modelo ajustado.

Trazar el histograma para su posterior verificación.

Vale la pena visualizar los resultados de lo que hemos hecho hasta ahora para la
predicción de la volatilidad con el modelo Garch basado en bayesiano.

La figura 4­13 muestra la distribución de variables latentes. La variable latente q reúne


alrededor de 0,2 y la otra variable latente p en su mayoría toma valores entre 0,7 y
0,8.
Machine Translated by Google

Figura 4­13. Variables latentes

La Figura 4­14 indica la serie de volatilidad degradada y el resultado de la


predicción GARCH basado en el enfoque bayesiano.
Machine Translated by Google

Figura 4­14. Ajuste del modelo

La Figura 4­15 visualiza las predicciones posteriores del modelo bayesiano con
los datos para que podamos detectar discrepancias sistemáticas, si las hubiera. El
Machine Translated by Google

La línea vertical representa la estadística de prueba y resulta que el valor observado es


mayor que el de nuestro modelo.
Machine Translated by Google
Machine Translated by Google

Figura 4­15. Predicción posterior

Una vez que hayamos terminado con la parte de entrenamiento, todos nos prepararemos
para pasar a la siguiente fase, que es la predicción. Se realiza un análisis de predicción para el
paso 252 por delante y se calcula el RMSE dada la volatilidad realizada.

En [76]: predicción_bayesiana = model.predict_is(n, fit_method='MH')


La tasa de aceptación de Metropolis­Hastings es 0,1127
La tasa de aceptación de Metropolis­Hastings es 0,17795
La tasa de aceptación de Metropolis­Hastings es 0,2532

¡Sintonización completa! Ahora muestreo.


La tasa de aceptación de Metropolis­Hastings es 0,255425

En [77]: bayesian_RMSE = np.sqrt(mean_squared_error(realized_vol.iloc[­n:] / 100,


bayesian_prediction.values / 100))
print('El RMSE del modelo bayesiano es {:.6f}'.format(bayesian_RMSE ))
El RMSE del modelo bayesiano es 0,004090

En [78]: bayesian_prediction.index = ret.iloc[­n:].index

En [79]: plt.figure(figsize=(10, 6))


plt.plot(realized_vol / 100,
label='Volatilidad realizada')
plt.plot(bayesian_prediction['Series'] / 100,
label='Predicción de volatilidad­bayesiana')
plt.title('Predicción de volatilidad con enfoque MH', tamaño de fuente=12)
plt.legend()
plt.savefig('images/bayesian.png')
plt.show()

Predicción de volatilidad en muestra.

Calcular la puntuación RMSE.

Finalmente, estamos listos para observar el resultado de la predicción del enfoque


bayesiano y el siguiente código lo hace por nosotros.

La Figura 4­16 visualiza la predicción de volatilidad basada en el enfoque bayesiano de


Metropolis­Hasting y parece sobrepasarse hacia finales de 2020.
Machine Translated by Google

y el rendimiento general de este método muestra que no se encuentra entre los mejores
métodos, ya que simplemente supera a SVR­GARCH con núcleo polinomial.

Figura 4­16. Predicción de volatilidad bayesiana

Conclusión
La predicción de la volatilidad es clave para comprender la dinámica del mercado
financiero en el sentido de que nos ayuda a medir la incertidumbre. Dicho esto, se utiliza
como entrada en muchos modelos financieros, incluidos los modelos de riesgo. Estos
hechos enfatizan la importancia de tener una predicción precisa de la volatilidad.
Tradicionalmente, los métodos paramétricos como ARCH, GARCH y sus extensiones se
han utilizado ampliamente, pero estos modelos adolecen de ser inflexibles. Para remediar
este problema, los modelos basados en datos se consideran prometedores y este
capítulo intenta hacer uso de estos modelos, a saber, máquinas de vectores de
soporte, redes neuronales y modelos basados en aprendizaje profundo, y resulta
que el modelo basado en datos supera al modelo paramétrico. modelos.
Machine Translated by Google

En el próximo capítulo, se discutirá el riesgo de mercado, un tema central del riesgo


financiero, tanto desde el punto de vista teórico como empírico y se incorporarán
modelos de aprendizaje automático para mejorar aún más la estimación de este riesgo.

Recursos adicionales
Artículos citados en este capítulo:

Andersen, Torben G., Tim Bollerslev, Francis X. Diebold y Paul Labys. "Modelado
y previsión de la volatilidad realizada". Econométrica 71, núm. 2 (2003): 579­625.

Andersen, Torben G. y Tim Bollerslev. “Periodicidad intradiaria y persistencia de


la volatilidad en los mercados financieros”. Revista de finanzas empíricas 4,
no. 2­3 (1997): 115­158.

Negro, Fischer. “Estudios de cambios de volatilidad en el mercado de valores”.


1976 Actas de la sección de estadísticas económicas y comerciales de la
asociación estadística estadounidense (1976).

Burnham, Kenneth P. y David R. Anderson. "Inferencia multimodelo:


comprensión de AIC y BIC en la selección de modelos".
Métodos e investigación sociológicos 33, no. 2 (2004): 261­304.

Eagle, Robert F. "Heterocedasticidad condicional autorregresiva con


estimaciones de la varianza de la inflación del Reino Unido". Econométrica 50,
núm. 4 (1982): 987­1008.

De Stefani, Jacopo, Olivier Caelen, Dalila Hattab y Gianluca Bontempi.


"Aprendizaje automático para la previsión de indicadores de volatilidad en varios
pasos". En MIDAS@PKDD/ECML, págs. 17­28. 2017.

Dokuchaev, Nikolai. "Estimación de la volatilidad a partir de series cortas de


precios de acciones". Revista de estadística no paramétrica 26, no. 2 (2014):
373­384.

Karasan, Abdullah y Esma Gaygisiz. "Predicción de la volatilidad y gestión de


riesgos: un enfoque SVR­GARCH". El diario de
Machine Translated by Google

Ciencia de datos financieros 2, no. 4 (2020): 85­104.

Mandelbrot, Benoit. "Nuevos métodos en economía estadística".


Revista de economía política 71, núm. 5 (1963): 421­440.

Raju, MT y Anirban Ghosh. "Volatilidad del mercado de valores: una


comparación internacional". Junta de Bolsa y Valores de la India (2004).

Libros citados en este capítulo:

Alpaydin, E., 2020. Introducción al aprendizaje automático. Prensa del MIT.

Burnham, Kenneth P. y David R. Anderson. "Un enfoque práctico de


la teoría de la información". Selección de modelos e inferencia multimodelo
(2002).

Focardi, Sergio M. Modelando el mercado: Nuevas teorías y técnicas.


vol. 14. John Wiley e hijos, 1997.

Rachev, Svetlozar T., John SJ Hsu, Biliana S. Bagasheva y Frank J. Fabozzi.


Métodos bayesianos en finanzas. vol. 153. John Wiley e hijos, 2008.

Wilmott, Pablo. Aprendizaje automático: una introducción a las


matemáticas aplicadas. John Wiley e hijos, 2013.

1 La varianza condicional significa que la estimación de la volatilidad es una función de los valores pasados de los activos.
devoluciones.

2 Para obtener más información, consulte esta nota: http://cs229.stanford.edu/notes/cs229­notes3.pdf

3 La Navaja de Occam, también conocida como ley de la parsimonia, establece que, dado un conjunto de explicaciones, la
explicación más simple es la más plausible y probable.

4 De estas alternativas, Tensorflow, PyTorch y Neurolab son las bibliotecas más destacadas.

5 Consulte este manual: https://scikit­


learn.org/stable/modules/generated/sklearn.neural_network.MLPClasifier.html
Machine Translated by Google

Capítulo 5. Riesgo de Mercado

UNA NOTA PARA LOS LECTORES DE PUBLICACIÓN ANTICIPADA

Con los libros electrónicos de lanzamiento anticipado, obtiene libros en su forma más
antigua (el contenido sin editar y sin editar del autor mientras escribe) para que pueda
aprovechar estas tecnologías mucho antes del lanzamiento oficial de estos títulos.

Este será el quinto capítulo del libro final. Tenga en cuenta que el repositorio de GitHub se
activará más adelante.

Si tiene comentarios sobre cómo podríamos mejorar el contenido y/


o los ejemplos de este libro, o si nota que falta material en este
capítulo, comuníquese con el editor en [email protected].

El riesgo es omnipresente en las finanzas, pero es difícil de cuantificar. Lo primero y más importante
que hay que saber es diferenciar las fuentes de los riesgos financieros, ya que podría no ser una
buena decisión utilizar las mismas herramientas contra los riesgos financieros que surgen de
diferentes fuentes.

Por lo tanto, tratar diferentes fuentes de riesgo financiero es crucial ya que el impacto de los
diferentes riesgos financieros, así como las herramientas desarrolladas para mitigarlos, son
completamente diferentes. Si se supone que las empresas están sujetas a grandes
fluctuaciones del mercado, todos los activos de la cartera de las empresas son susceptibles al
riesgo derivado de estas fluctuaciones. Sin embargo, se debería desarrollar una herramienta
diferente para hacer frente al riesgo que emana del perfil del cliente. Además, hay que tener en
cuenta que diferentes factores de riesgo contribuyen significativamente a los precios de los activos.
Todos estos ejemplos implican que la evaluación de los factores de riesgo necesita una
consideración cuidadosa en las finanzas.

Como se analizó brevemente anteriormente, se trata, principalmente, de riesgos de


mercado, de crédito, de liquidez y operacionales. Es evidente que se pueden agregar algunos
otros tipos a esta lista de riesgos financieros pero se pueden pensar como un subconjunto de estos.
Machine Translated by Google

cuatro tipos principales de riesgo. Por lo tanto, estos tipos de riesgos serán nuestro enfoque a lo largo de
este capítulo.

El riesgo de mercado es el riesgo que surge de cambios en los indicadores financieros como el tipo de
cambio, la tasa de interés, la inflación, etc. De otra manera, el riesgo de mercado puede referirse al riesgo
de pérdidas en posiciones dentro y fuera de balance que surgen de movimientos en los precios de
mercado (BPI, 2020). Veamos ahora cómo estos factores afectan el riesgo de mercado. Supongamos
que un aumento en la tasa de inflación podría representar una amenaza para la rentabilidad actual de las
instituciones financieras con miras a que la inflación cree presión sobre la tasa de interés. Esto, a
su vez, afecta el costo de los fondos para el prestatario. Estos casos pueden amplificarse, pero también
debemos tener en cuenta las interacciones de estas fuentes de riesgo financiero. Es decir, mientras una
única fuente de riesgo financiero cambia, otras fuentes de riesgo no pueden permanecer constantes. Dicho
esto, hasta cierto punto, los indicadores financieros están interrelacionados, lo que significa que se deben
tener en cuenta las interacciones de estas fuentes de riesgos.

Como puedes imaginar, existen diferentes herramientas para medir el riesgo de mercado. De ellas, las
herramientas más destacadas y ampliamente aceptables son el valor en riesgo (VaR) y el déficit esperado
(ES). El objetivo final de este capítulo es aumentar estos enfoques utilizando desarrollos recientes en
aprendizaje automático. En esta coyuntura, sería tentador preguntar: ¿fracaso el modelo tradicional en el
ámbito financiero? ¿Y qué hace diferente al modelo basado en ML?

Empezaré abordando la primera pregunta. El primer y principal desafío que los modelos tradicionales
no pueden abordar es la complejidad del sistema financiero. Debido a algunas suposiciones
sólidas o simplemente a la incapacidad de capturar la complejidad introducida por los datos, los
modelos tradicionales de larga data han comenzado a ser reemplazados por modelos basados en
ML.

Este hecho lo expresa bien Prado:

Considerando la complejidad de los sistemas financieros modernos, es poco probable que un


investigador pueda descubrir los ingredientes de una teoría mediante una inspección visual de los
datos o realizando algunas regresiones.

—Prado (Aprendizaje automático para gestores de activos, 2020, p.4)


Machine Translated by Google

Para abordar la segunda pregunta, sería prudente pensar en la lógica de funcionamiento de los
modelos de ML. Los modelos ML, a diferencia de los antiguos métodos estadísticos, intentan revelar
la asociación entre variables, identificar variables clave y permitirnos descubrir el impacto de
las variables en la variable dependiente sin necesidad de una teoría bien establecida. De hecho, esta
es la belleza del modelo ML, ya que los modelos ML, sin requerir muchos supuestos restrictivos y
sólidos, nos permiten descubrir teorías, y mucho menos exigirlas.

En principio, muchos métodos de estadística y aprendizaje automático (ML) pueden


utilizarse tanto para la predicción como para la inferencia. Sin embargo, los métodos estadísticos se
centran desde hace mucho tiempo en la inferencia, que se logra mediante la creación y el
ajuste de un modelo de probabilidad específico del proyecto...
Por el contrario, el ML se concentra en la predicción mediante el uso de algoritmos de aprendizaje
de propósito general para encontrar patrones en datos a menudo ricos y difíciles de manejar.

—Bzdok (Estadísticas versus aprendizaje automático, 2018, p.232)

En la siguiente parte, iniciamos nuestra discusión sobre los modelos de riesgo de mercado.
Primero, hablamos de la aplicación del valor en riesgo (VaR) y del déficit esperado (ES). Después
de la aplicación tradicional de estos modelos, aprenderemos a utilizarlos utilizando el enfoque basado
en ML. Entremos.

Valor en riesgo
La aparición del modelo VaR se debe a una solicitud de un ejecutivo de JP Morgan que quería tener
un informe resumido que mostrara las posibles pérdidas y los riesgos en un día a los que está
expuesto JP Morgan. En este informe se informa a los ejecutivos sobre el riesgo asumido por la
institución de manera agregada.
El método mediante el cual se calcula el riesgo de mercado se conoce como VaR. Por lo tanto, es el
punto de partida del VaR y, ahora, se ha generalizado tanto que los reguladores han obligado su
adopción.

La adopción del VaR se remonta a la década de 1990 y, a pesar de numerosas extensiones del VaR
y nuevos modelos propuestos, todavía está en uso. Entonces, ¿qué lo hace tan atractivo?
tal vez la cuestión a abordar. La respuesta viene de Kevin Dowd:
Machine Translated by Google

La cifra del VaR tiene dos características importantes. La primera es que proporciona
una medida común y consistente del riesgo entre diferentes posiciones y factores de riesgo.
Nos permite medir el riesgo asociado con una posición de renta fija, digamos, de una
manera que sea comparable y consistente con una medida del riesgo asociado con posiciones
de renta variable. El VaR nos proporciona un criterio de riesgo común, y este criterio hace
posible que las instituciones gestionen sus riesgos de nuevas formas que antes no eran
posibles. La otra característica del VaR es que tiene en cuenta las correlaciones entre
diferentes factores de riesgo. Si dos riesgos se compensan entre sí, el VaR permite esta
compensación y nos dice que el riesgo general es bastante bajo.

—Dowd (2002, pág.10)

De hecho, el VaR básicamente aborda una de las preguntas más comunes de un


inversor:

Dado el nivel de riesgo, ¿cuál es la pérdida máxima esperada de mi inversión?

El VaR proporciona una respuesta muy intuitiva y práctica a esta pregunta. En este sentido,
se utiliza para medir la peor pérdida esperada de una empresa durante un período
determinado y un intervalo de confianza predefinido. Supongamos que el VaR diario de una
inversión es de 10 millones de dólares con un intervalo de confianza del 95%. Esto dice así:
Existe un 5% de posibilidades de que el inversor pueda incurrir en una pérdida superior a 10
millones de dólares en un día.

Según la definición anterior, resulta que los componentes del VaR son el intervalo de confianza,
el período de tiempo, el valor de un activo o cartera y la desviación estándar, ya que
hablamos de riesgo.

En resumen, hay algunos puntos importantes en el análisis del VaR que es necesario destacar:

El VaR necesita una estimación de la probabilidad de pérdida

El VaR se concentra en las pérdidas potenciales. No estamos hablando de pérdidas


reales o realizadas, sino que el VaR es una especie de proyección de pérdidas.

El VaR tiene tres ingredientes clave:


Machine Translated by Google

Desviación estándar que define el nivel de pérdida

Horizonte temporal fijo sobre el cual se evalúa el riesgo

Intervalo de confianza

Bueno, el VaR se puede medir mediante tres enfoques diferentes:

VaR de varianza­covarianza

VaR de simulación histórica

VaR de Montecarlo

Método de varianza­covarianza
El método de varianza­covarianza también se conoce como método paramétrico porque
se supone que los datos están distribuidos normalmente. El método de varianza­covarianza
es común debido a este supuesto; sin embargo, vale la pena señalar que los
rendimientos no tienen una distribución normal. El supuesto de forma paramétrica
hace que la aplicación del método de varianza­covarianza sea práctica y fácil de aplicar.

Como en todos los enfoques de VaR, podemos trabajar con un solo activo o con
una cartera. Sin embargo, trabajar con cartera requiere un tratamiento cuidadoso en el
sentido de que es necesario estimar la estructura de correlación y la varianza de la cartera.
Exactamente en este punto, la correlación entra en escena y los datos históricos se utilizan
para calcular la correlación, la media y la desviación estándar. Si bien
aumentamos esto con un enfoque basado en ML, nuestro enfoque principal será la
estructura de correlación.

Supongamos que tenemos un solo activo, en la Figura 5­1, se muestra que la media de
este activo es cero y la desviación estándar es 1 y si el período de tenencia es 1, se puede
calcular el valor VaR correspondiente al valor del activo. por el valor Z correspondiente
y la desviación estándar. Por lo tanto, el supuesto de normalidad facilita las cosas, pero es
un supuesto sólido porque no hay garantía de que los rendimientos de los
activos se distribuyan normalmente, sino que la mayoría de los rendimientos de los
activos no siguen una distribución normal. Además, debido a la normalidad
Machine Translated by Google

supuesto, es posible que no se capture el riesgo potencial resultante. Por lo tanto, el


supuesto de normalidad tiene un costo.

En [1]: importar pandas como


pd importar numpy
como np importar matplotlib.pyplot
como plt importar
fecha y hora importar
yfinance como yf desde scipy.stats
importar normas
importar solicitudes desde
io importar StringIO importar seaborn
como sns;
sns.set() importar advertencias
advertencias.filterwarnings('ignorar') plt.rcParams['figure.figsize'] = (10,6)

En [2]: media = 0
std_dev = 1
x = np.arange(­5, 5, 0.01) y =
norm.pdf(x, media, std_dev) pdf =
plt.plot(x, y) min_ylim,
max_ylim = plt.ylim()
plt.text(np.percentile(x, 5), max_ylim * 0.9, '95%:$
{:.4f}' .format(np.percentile(x, 5)))
plt.axvline( np.percentile(x, 5), color='r', estilo de línea='discontinuo', ancho de línea=4)
plt.title('Ilustración de valor en riesgo')
plt.savefig('images/VaR_Illustration.png')
plt.mostrar()
En [3]: media = 0
std_dev = 1
x = np.arange(­5, 5, 0.01) y =
norm.pdf(x, media, std_dev) pdf =
plt.plot(x, y) min_ylim,
max_ylim = plt.ylim()
plt.text(np.percentile(x, 5), max_ylim * 0.9, '95%:$
{:.4f}' .format(np.percentile(x, 5)))
plt.axvline( np.percentile(x, 5), color='r', estilo de línea='discontinuo', ancho de línea=4)
plt.title('Ilustración de valor en riesgo')
plt.savefig('images/VaR_Illustration.png')
plt.mostrar()

Generación de una función de densidad de probabilidad basada en x, media y


desviación estándar dadas.
Machine Translated by Google

Limitar el eje x y el eje y.

Especificar la ubicación de x en el percentil 5% de los datos de x.

Figura 5­1. Ilustración de valor en riesgo

NOTA
Siguiendo a Fama (1965), se observa que algunos rendimientos de los precios de las acciones no siguen una
distribución normal debido a la cola gruesa y la asimetría. Más bien siguen una distribución leptocúrtica. Esta
observación empírica implica que los rendimientos de las acciones tienen una curtosis mayor que la de la
distribución normal.

Tener una curtosis alta equivale a una cola gruesa y esto podría generar retornos negativos extremos.
Como el método de varianza­covarianza no puede capturar la cola gruesa, no puede, por lo tanto, estimar el
rendimiento negativo extremo, que probablemente ocurrirá especialmente en el período de crisis.
Machine Translated by Google

Veamos cómo aplicamos Varianza­Covarianza VaR en Python. A modo de


ilustración, se considera una cartera de 2 activos y la fórmula de Varianza­Covarinza
VaR es la siguiente:

VaR = Vσp√tZα

2 2
1 + w2 2σ2 + ρw1w2σ1σ2
σp = √w2 1σ

σp = √w1σ1 + w2 + σ + 2w1w2 ∑1,2

En [4]: def getDailyData(symbol): parámetros


= {'function': 'TIME_SERIES_DAILY_ADJUSTED', 'symbol': símbolo,
'outputsize':'full',
'datatype': 'csv', 'apikey':
'LL1WA15IW41XV2T2 '}

respuesta = solicitudes.get('https://www.alphavantage.co/query',
parámetros=parámetros)

# Procesar el archivo CSV recuperado


csvText = StringIO(response.text) data =
pd.read_csv(csvText, index_col='timestamp') devolver datos

En [5]: símbolos = ["IBM", "MSFT", "INTC"] data3 = []


para símbolo
en símbolos:
data3.append(getDailyData(symbol)[::­1]['close'][' 2020­01­01': '2020­12­
31'])
acciones = pd.DataFrame(data3).T
acciones.columnas = símbolos

En [6]: acciones.head()
Fuera[6]: IBM MSFT INTC
marca de
tiempo 2020­01­02 135,42 160,62 60,84
2020­01­03 134,34 158,62 60,10
2020­01­06 134,10 159,03 59,93
2020­01­07 134,19 157,58 58,93
2020­01­08 135,31 160,09 58,97
Machine Translated by Google

Identificar los parámetros que se utilizarán para extraer los datos de Alpha Vantage.

Realizar una solicitud al sitio web de Alpha Vantage.

Abra el archivo de respuesta, que está en formato de texto.

Invertir los datos que cubren el período de examen y adjuntar los precios diarios de
las acciones de IBM, MSFT e INTC.

NOTA
Alpha Vantage es una empresa proveedora de datos asociada con las principales bolsas e
instituciones. Con Alpha Vantage API, es posible acceder a los precios de las acciones con diferentes
intervalos de tiempo, es decir, intradiario, diario, semanal, etc., a los fundamentos de las acciones y
a la información de Forex. Para obtener más información, consulte el sitio web de Alpha Vantage.

En [7]: stocks_returns = (np.log(stocks) ­ np.log(stocks.shift(1))).dropna() stocks_returns

Fuera[7]: IBM MSFT INTC


marca de
tiempo 2020­01­03 ­0.008007 ­0.012530 ­0.012238
2020­01­06 ­0.001788 0.002581 ­0.002833
2020­01­07 0.000671 ­0.009160 ­0.016827
2020­01­08 0.008312 0.015803 0.000679
2020­01­09 0.010513 0.012416 0.005580
... ... ... ...
2020­12­24 0.006356 0.007797 0.010679
2020­12­28 0.001042 0.009873 0.000000
2020­12­29 ­0.008205 ­0.003607 0.048112
2020­12­30 0.004352 ­0.011081 ­0.013043
2020­12­31 0.012309 0.003333 0.021711

[252 filas x 3 columnas]

En [8]: stocks_returns_mean = stocks_returns.mean() pesos


= np.random.random(len(stocks_returns.columns)) pesos /=
np.sum(pesos) cov_var =
stocks_returns.cov() port_std =
np.sqrt(pesos .T.dot(cov_var).dot(pesos))
Machine Translated by Google

En [9]: inversión_inicial = 1e6


nivel_conf = 0,95

En [10]: def VaR_parametric(initial_investment, conf_level): alpha =


norm.ppf(1 ­ conf_level, stocks_returns_mean, port_std) para i, j en
zip(stocks.columns, range(len(stocks.columns))):
VaR_param = (inversión_inicial ­ inversión_inicial * (1 + alfa))
[j]
print("El resultado del VaR paramétrico para {} es {} ".format(i, VaR_param))
VaR_param = (inversión_inicial­inversión_inicial * (1 + alfa)) print('­­' * 25)
return VaR_param

En [11]: VaR_param = VaR_parametric(inversión_inicial, nivel_conf)


VaR_param
El resultado del VaR paramétrico para IBM es 42199,839069714886
El resultado del VaR paramétrico para MSFT es 40618,179754271754
El resultado del VaR paramétrico para INTC es 42702,930219301255
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Fuera[11]: matriz([42199.83906971, 40618.17975427, 42702.9302193 ])

Calcular el rendimiento logarítmico.

Dibujar números aleatorios para los pesos.

Generando pesos.

Calcular la matriz de covarianza.

Encontrar la desviación estándar de la cartera.

Calcular la puntuación Z para un valor específico utilizando la función de punto porcentual


(ppf).

Estimación del modelo VaR de Varianza­Covarianza.

Dado el horizonte temporal, el resultado del valor en riesgo cambia debido al hecho de que
mantener el activo durante un período más largo hace que el inversor sea más susceptible
al riesgo. Como se muestra en la Figura 5­2, el VaR aumenta en relación con la tenencia
Machine Translated by Google

tiempo por la cantidad de √t. Además, el período de tenencia es el más largo para
la liquidación de cartera. Teniendo en cuenta el propósito del informe, un
período de 30 días puede ser más adecuado para un inversionista y se
ilustra en la Figura 5­2.

En [12]: var_horizon = []
time_horizon = 30
para j en rango(len(stocks_returns.columns)): para
i en rango(1, time_horizon + 1):
var_horizon.append(VaR_param[j] * np.sqrt( i))
plt.plot(var_horizon[:time_horizon], "o", c='blue',
marcador='*', label='IBM')
plt.plot(var_horizon[time_horizon:time_horizon + 30], "o ",
c='verde', marcador='o', etiqueta='MSFT')
plt.plot(var_horizon[time_horizon + 30:time_horizon + 60], "o",
c='rojo', marcador='v', etiqueta='INTC')
plt.xlabel("Días")
plt.ylabel("USD")
plt.title("VaR durante un período de 30
días") plt.savefig ('imagenes/

VaR_30_day.png') plt.legend() plt.show()


Machine Translated by Google

Figura 5­2. Valor en riesgo en un horizonte diferente

Concluimos esta parte enumerando los pros y los contras del método Varianza­
Covarianza.

Ventajas

Fácil de calcular

No requiere gran cantidad de muestras.

Contras

Las observaciones se distribuyen normalmente.

No funciona bien con estructuras no lineales.

Requiere cálculo de matriz de covarianza

Por lo tanto, aunque suponer que la normalidad suena atractivo, puede que no sea la mejor
manera de estimar el VaR, especialmente en el caso en que el rendimiento del activo no tiene
Machine Translated by Google

distribución normal. Afortunadamente, existen otros métodos que no requieren el


supuesto de normalidad y los modelos se conocen como modelo VaR de simulación histórica .

Método de simulación histórica


Tener suposiciones sólidas, como la distribución normal, podría ser la causa de una estimación
inexacta. Una solución a este problema se denomina VaR de simulación histórica. Este es

un método empírico y en lugar de utilizar un enfoque paramétrico, lo que hacemos es encontrar


el percentil, que es el equivalente en la tabla Z del método de varianza­covarianza.
Supongamos que el intervalo de confianza es del 95%, luego se usará el 5% en lugar del
valor de la tabla Z y todo lo que tenemos que hacer es multiplicar este percentil por la
inversión inicial.

Estos son los pasos que se siguen en el VaR de simulación histórica:

Obtener rentabilidades de los activos de la cartera (o activo individual).

Encuentre el percentil de rendimiento correspondiente según el intervalo de


confianza.

Multiplique este percentil por la inversión inicial.

En [13]: def VaR_historical(initial_investment, conf_level): Hist_percentile95 = []


para i, j en
zip(stocks_returns.columns,
range(len(stocks_returns.columns))):
Hist_percentile95.append(np.percentile(stocks_returns.loc[:, i],
5))
print("Basado en valores históricos, el 95% del retorno de {} es {:.4f}" .format(i,
Hist_percentile95[j]))
VaR_histórico = (inversión_inicial­inversión_inicial *
(1 + Hist_percentile95[j]))
print("El resultado histórico del VaR para {} es {:.2f} "
.format(i, VaR_historical)) print('­­' *
35)

En [14]: VaR_historical(inversión_inicial,nivel_conf)
Basado en valores históricos, el 95% del rendimiento de IBM es ­0,0371.
El resultado histórico del VaR de IBM es 37081,53.
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

Según valores históricos, el 95% del rendimiento de MSFT es ­0,0426


Machine Translated by Google

El resultado histórico del VaR para MSFT es 42583,68


­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

Basado en valores históricos, el 95% del rendimiento de INTC es ­0,0425.


El resultado histórico del VaR de INTC es 42485,39.
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

Calcular el percentil del 95% de la rentabilidad de las acciones

Estimación del VaR de simulación histórica

El método VaR de simulación histórica supone implícitamente que los cambios históricos de precios

tienen un patrón similar, es decir, que no hay ruptura estructural. Los pros y los contras de este método
son los siguientes:

Ventajas

Sin supuesto distributivo

Funciona bien con estructura no lineal.

Fácil de calcular

Contras

Requiere una muestra grande

Necesita una alta potencia informática

Engañar si una empresa está sujeta a ambigüedad, como las acciones de empresas en
crecimiento.

Monte Carlo­Simulación VaR


Antes de profundizar en la estimación del VaR de la simulación Monte Carlo, sería mejor hacer una breve
introducción sobre la simulación Monte Carlo. Monte Carlo es un método matemático computarizado

que se utiliza para realizar una estimación en el caso de que no exista una solución de forma cerrada. Por

tanto, es una herramienta muy eficaz para la aproximación numérica. Monte Carlo se basa en muestras

aleatorias repetidas de una distribución determinada.


Machine Translated by Google

La lógica detrás de Montecarlo está bien definida por Glasserman:

Los métodos de Monte Carlo se basan en la analogía entre probabilidad y volumen. Las
matemáticas de la medida formalizan la noción intuitiva de probabilidad, asociando un
evento con un conjunto de resultados y definiendo la probabilidad del evento como su
volumen o medida relativa al de un universo de resultados posibles. Monte Carlo utiliza
esta identidad a la inversa, calculando el volumen de un conjunto interpretando el volumen
como una probabilidad.

—Glasserman (Métodos de Monte Carlo en Ingeniería


Financiera, 2003, p.11)

Desde el punto de vista de la aplicación, Monte Carlo es muy similar al VaR de simulación
histórica pero no utiliza observaciones históricas. Más bien, genera muestras
aleatorias a partir de una distribución determinada. Por lo tanto, Monte Carlo ayuda a los
tomadores de decisiones al proporcionar un vínculo entre los posibles resultados
y las probabilidades, lo que lo convierte en una herramienta eficiente y aplicable en finanzas.

Monte Carlo matemático se puede definir como:

Sea X1, X2, . . Xn son variables aleatorias independientes y distribuidas idénticamente


y f(x) es una función de valor real. Entonces, la Ley de los Grandes Números establece
que:

1
E(f(X)) ≈ norte
∑Nf
i (Xi)

En pocas palabras, la simulación Monte Carlo no es más que generar muestras


aleatorias y calcular su media. Computacionalmente sigue los siguientes pasos:

Definir el dominio

Generar números aleatorios

Iteración y agregación del resultado.

La determinación de π matemática es un juguete pero un ejemplo ilustrativo para la


aplicación Monte Carlo.
Machine Translated by Google

Supongamos que tenemos un círculo con radio r = 1 y área = 4. El área de un círculo es π


y el área de un cuadrado en el que intentamos encajar el círculo es 4. La relación resulta
ser:

π
4 ecuación.1

Dejando π solo, la proporción entre círculo y área se puede definir como:

Circunferenciacirculo
= metro

ecuación 2
Áreacuadrada norte

Una vez que igualamos la ecuación 1 y la ecuación 2, resulta:

π = 4x
metro

norte

Si vamos paso a paso, el primero es definir el dominio que es [­1,1]. Entonces, los números
2 2
dentro del círculo satisfacen: x +y ≤ 1.

El segundo paso es generar números aleatorios para cumplir la condición


anterior. Es decir, necesitamos tener muestras aleatorias distribuidas uniformemente,
lo cual es una tarea bastante sencilla en Python. Para practicar, generaré 100 números
aleatorios distribuidos uniformemente usando la biblioteca numpy:

En [15]: x = np.random.uniform(­1, 1, 100) y =


np.random.uniform(­1, 1, 100)

En [16]: muestra = 100


def pi_calc(x, y):
point_inside_circle = 0
para i en rango (muestra):
if np.sqrt(x[i] ** 2 + y[i] ** 2) <= 1:
point_inside_circle += 1
print(' el valor pi es {}'.format(4 * point_inside_circle/sample))

En [17]: pi_calc(x,y) el
valor pi es 3,36

En [18]: x = np.random.uniform(­1, 1, 1000000) y =


np.random.uniform(­1, 1, 1000000)

En [19]: muestra = 1000000

def pi_calc(x, y):


punto_inside_circle = 0
Machine Translated by Google

para i en rango (muestra):


si np.sqrt(x[i] ** 2 + y[i] ** 2) < 1:
punto_interior_circulo += 1
print('el valor pi es {:.2f}'.format(4 * point_inside_circle/sample))

En [20]: sim_data = pd.DataFrame([])


número_repeticiones = 1000

media = np.aleatorio.aleatorio(3)
estándar = np.aleatorio.aleatorio(3)
para i en rango (len (existencias.columnas)):
temp = pd.DataFrame(np.random.normal(media[i], std[i], num_reps))
datos_sim = pd.concat([datos_sim, temperatura],eje=1)
sim_data.columns = ['Simulación 1', 'Simulación 2', 'Simulación 3']

En [21]: datos_sim
Fuera[21]: Simulación 1 Simulación 2 Simulación 3
0 0,475188 1.587426 1.334594
1 0.547615 ­0.169073 0.684107
2 0.486227 1.533680 0,755307
3 0.494880 ­0.230544 0.471358
4 0.580477 0.388032 0.493490
.. ... ... ...
995 0.517479 0.387384 0.539328
996 0.286267 0.680610 0.409003
997 0.398601 0.733176 0.820090
998 0,624548 0.482050 0.821792
999 0.627089 1.405230 1.275521

[1000 filas x 3 columnas]

En [22]: def MC_VaR(inversión_inicial, nivel_conf):


MC_percentil95 = []
para i, j en zip(sim_data.columns, range(len(sim_data.columns))):
MC_percentile95.append(np.percentile(sim_data.loc[:, i], 5))
print("Basado en la simulación, el 95% del retorno de {} es {:.4f}"
.formato(i, MC_percentile95[j]))
VaR_MC = (inversión_inicial­inversión_inicial *
(1 + MC_percentil95[j]))
print("El resultado de la simulación VaR para {} es {:.2f} ".format(i, VaR_MC))
imprimir('­­'*35)

En [23]: MC_VaR(inversión_inicial, nivel_conf)


Basado en la simulación, el 95% del rendimiento de la Simulación 1 es 0,3294
El resultado de la simulación VaR para la simulación 1 es ­329409,17
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

Basado en la simulación, el 95% del rendimiento de la Simulación 2 es 0,0847


El resultado de la simulación VaR para la simulación 2 es ­84730,05
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­
Machine Translated by Google

Basado en la simulación, el 95% del rendimiento de la Simulación 3 es 0,1814.


El resultado del VaR de la simulación para la Simulación 3 es ­181376,94.
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­­­

Generar números aleatorios a partir de distribución uniforme.

Comprobando si los puntos están dentro del círculo, que tiene un radio de 1.

Calcular el 95% de los rendimientos de cada acción y agregar el resultado a la lista


denominada MC_percentile95.

Estimación del VaR de Montecarlo.

Denoising Volatility

está en todas partes, pero es una tarea formidable descubrir qué tipo de volatilidad es
más valiosa. En general, existen dos tipos de información en el mercado: ruido y señal. El
primero no genera más que información aleatoria, pero el segundo nos proporciona
información valiosa con la que los inversores pueden ganar dinero. A modo de ejemplo,
considere que hay dos actores principales en el mercado: uno que utiliza información
ruidosa, llamado comerciante de ruido, y un comerciante informado que explota señales o
información privilegiada. La motivación comercial de los traders ruidosos está impulsada
por un comportamiento aleatorio. Por lo tanto, se cree que el flujo de información hacia las
señales del mercado es una señal de compra para algunos operadores de ruido y de venta
para otros.

Sin embargo, se considera que el comerciante informado es racional en el sentido de que el


comerciante informado desde dentro puede evaluar una señal porque sabe que es información
privada.

En consecuencia, el flujo continuo de información debe tratarse con cautela.


En resumen, la información proveniente de un comerciante de ruido puede considerarse
ruido y la información proveniente de información privilegiada puede tomarse como una
señal y este es el tipo de información que importa. El inversor que no puede distinguir el
ruido y la señal puede no obtener beneficios ni evaluar el riesgo de forma adecuada.
Machine Translated by Google

Ahora, el problema resulta ser diferenciar el flujo de información hacia los mercados financieros.
¿Cómo podemos diferenciar el ruido de la señal? y cómo podemos utilizar esta información.

Ahora es apropiado discutir el Teorema de Marcenko Pastur que nos ayuda a tener una matriz
de covarianza homogénea. El teorema de Marcenko­Pastur nos permite extraer señales
del ruido utilizando valores propios de la matriz de covarianza.

NOTA
Sea A R nxn
una matriz cuadrada. Entonces, λ R es un valor propio de A y
x mathbbRn{0} es el vector propio correspondiente de A si

Hacha = λx

El valor propio y el vector propio tienen un significado especial en el contexto financiero.


El vector propio corresponde a la varianza en la matriz de covarianza, mientras que el valor
propio muestra la magnitud del vector propio. Específicamente, el vector propio más grande
corresponde a la varianza más grande y la magnitud de esta es igual al valor propio
correspondiente. Debido al ruido en los datos, algunos valores propios pueden considerarse
aleatorios y tiene sentido detectar y filtrar estos valores propios para retener únicamente las
señales.

Para diferenciar ruido y señal, ajustamos el PDF del teorema de Marcenko Pastur a la
covarianza ruidosa. La PDF del teorema de Marcenko Pastur toma la siguiente forma
(Prado, 2020):

√(λt − λ)(λ − λ−) si λ


t [λ − λ−]
norte

f(λ) = { 0, si λ [λ − λ−]

donde λ+ y λ− son valores propios máximo y mínimo, respectivamente.

En el siguiente bloque de código, que es una ligera modificación de los códigos


proporcionados por Prado (2020), generaremos la función de densidad de probabilidad de
Distribución de Marchenko­Pastur y densidad del kernel que nos permite modelar una
Machine Translated by Google

variable aleatoria en un enfoque no paramétrico. Luego, se ajustará la


distribución de Marchenko­Pastur a los datos.

En [24]: def mp_pdf(sigma2, q, obs): lambda_plus


= sigma2 * (1 + q ** 0,5) ** 2 lambda_minus = sigma2 * (1
­ q ** 0,5) ** 2 l = np.linspace (lambda_minus, lambda_plus,
obs) pdf_mp = 1 / (2 * np.pi * sigma2 *
q * l) * np.sqrt((lambda_plus ­ l) * (l ­

lambda_minus))
pdf_mp = pd.Series(pdf_mp, index=l) devolver
pdf_mp

En [25]: de sklearn.neighbors importa KernelDensity

def kde_fit(ancho de banda,obs,x=Ninguno):


kde = KernelDensity(ancho de banda, kernel='gaussian') if
len(obs.shape) == 1:
kde_fit=kde.fit(np.array(obs).reshape(­1, 1))
si x es Ninguno:
x=np.unique(obs).reshape(­1, 1) si
len(x.shape) == 1: x =
x.reshape(­1, 1) logprob =
kde_fit.score_samples(x) pdf_kde = pd.
Serie(np.exp(logprob), index=x.flatten()) devuelve pdf_kde

En [26]: corr_mat = np.random.normal(size=(10000, 1000)) corr_coef =


np.corrcoef(corr_mat, rowvar=0) sigma2 = 1 obs =

corr_mat.shape[0] q =
corr_mat.shape[ 0] / corr_mat.forma[1]

def trazado (corr_coef, q):


_ = np.linalg.eigh(corr_coef) ev, idx =
ev.argsort()[::­1] eigen_val =
np.diagflat(ev[idx]) pdf_mp = mp_pdf(1.,
q=corr_mat.shape[1] / corr_mat.shape[0], obs=1000)

kde_pdf = kde_fit(0.01, np.diag(eigen_val)) ax =


pdf_mp.plot(title=" Teorema de Marchenko­Pastur",
etiqueta="MP", estilo='r­­')
kde_pdf.plot(label=" Densidad empírica", style='o­', alpha=0.3) ax.set(xlabel="Valor
propio", ylabel="Frecuencia") ax.legend(loc="superior derecha")
plt .savefig('imágenes/MP_fit.png')
Machine Translated by Google

plt.show()
devolver plt

En [27]: trazado(corr_coef, q);

Calcular el valor propio máximo esperado.

Calcular el valor propio mínimo esperado

Generación de la función de densidad de probabilidad de la distribución de Marchenko­Pastur.

Iniciando la estimación de la densidad del grano.

Ajuste de la densidad del núcleo a las observaciones.

Evaluación del modelo de densidad logarítmica en observaciones.

Generando muestras aleatorias a partir de distribución normal.

Conversión de matriz de covarianza en matriz de correlación.

Calcular valores propios de la matriz de correlación.

Convirtiendo una matriz numpy en una matriz diagonal.

Llamar a la función mp_pdf para estimar la pdf de la distribución de Marchenko­Pastur.

Llamar a la función kde_fit para ajustar la distribución del kernel a los datos.

La Figura 5­3 muestra que la distribución de Marchenko­Pastur se ajusta bien a los datos.
Gracias al teorema de Marchenko­Pastur podemos diferenciar el ruido de la señal y los datos en los que

se filtra el ruido se denominan denoised.


Machine Translated by Google

Figura 5­3. Montaje de la distribución Marchenko­Pastur

Hasta ahora, hemos analizado los principales pasos a seguir para eliminar el ruido de la matriz de
covarianza para poder conectarla al modelo VaR, que se denomina estimación de VaR sin ruido . Eliminar
el ruido de la matriz de covarianza no es más que eliminar información innecesaria (ruido)
de los datos. Entonces, utilizamos la señal del mercado, que nos dice que algo importante está
sucediendo en el mercado.

1
La eliminación de ruido de la matriz de covarianza incluye las siguientes etapas:

Calcular valores propios y vectores propios basados en la matriz de correlación.

Utilizando la estimación de densidad del núcleo, encuentre el vector propio para un valor
propio específico.

Ajuste de la distribución de Marchenko­Pastor a la estimación de la densidad del grano.

Encontrar el valor propio teórico máximo utilizando la distribución de Marchenko­Pastur.


Machine Translated by Google

Se calcula el promedio de valores propios mayores que el valor teórico.

Estos nuevos valores propios y vectores propios se utilizan para calcular


la matriz de correlación sin ruido.

La matriz de covarianza sin ruido se calcula mediante la nueva matriz de


correlación.

En el Apéndice puede encontrar el algoritmo que incluye todos estos pasos, pero aquí
Me gustaría mostrarles lo fácil que es aplicar la búsqueda de una matriz de covarianza
sin ruido con unas pocas líneas de código utilizando la biblioteca portfoliolab en Python:

En [28]: importar portfoliolab como pl

En [29]: Risk_estimators = pl.estimators.RiskEstimators()

En [30]: precios_acciones = acciones.copia()

En [31]: cov_matrix = stocks_returns.cov()


matriz_cov
Fuera[31]: IBM MSFT INTC
IBM 0,000672 0,000465 0,000569
MSFT 0,000465 0,000770 0,000679
INTC 0,000569 0,000679 0,001158

En [32]: tn_relation = stock_prices.shape[0] / stock_prices.shape[1] kde_bwidth = 0,25


cov_matrix_denoised =
Risk_estimators.denoise_covariance(cov_matrix,
tn_relación,
kde_bwidth)
cov_matrix_denoised = pd.DataFrame(cov_matrix_denoised,
index=cov_matrix.index,
columnas=cov_matrix.columns)
cov_matrix_denoised
Fuera[32]: IBM MSFT INTC
IBM 0,000672 0,000480 0,000589
MSFT 0,000480 0,000770 0,000638
INTC 0,000589 0,000638 0,001158

En [33]: def VaR_parametric_denoised(initial_investment, conf_level):


port_std = np.sqrt(weights.T.dot(cov_matrix_denoised).dot(weights)) alpha = norm.ppf(1 ­
conf_level, stocks_returns_mean, port_std) para i,j en
zip(stocks.columns,range(len(stocks .columnas))):
print("El resultado del VaR paramétrico para {} es {} ".format(i,VaR_param))
VaR_params = (inversión_inicial ­ inversión_inicial * (1 + alfa))
Machine Translated by Google

print('­­' * 25)
devuelve VaR_params

En [34]: VaR_parametric_denoised(initial_investment, conf_level)


El resultado del VaR paramétrico para IBM es [42199.83906971 40618.17975427
42702.9302193 ]
El resultado del VaR paramétrico para MSFT es [42199.83906971 40618.17975427
42702.9302193 ]
El resultado del VaR paramétrico para INTC es [42199.83906971 40618.17975427
42702.9302193 ]
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Fuera[34]: matriz([42259.80830949, 40678.14899405, 42762.89945907])

En [35]: símbolos = ["IBM", "MSFT", "INTC"] data3 =


[] para
símbolo en símbolos:
data3.append(getDailyData(symbol)[::­1]['close'][' 2007­04­01': '2009­
02­01'])
stocks_crisis = pd.DataFrame(data3).T
stocks_crisis.columns = símbolos

En [36]: precios_acciones = crisis_acciones.copia()

En [37]: stocks_returns = (np.log(acciones) ­ np.log(acciones.shift(1))).dropna()

En [38]: cov_matrix = stocks_returns.cov()

En [39]: VaR_parametric(inversión_inicial, nivel_conf)


El resultado del VaR paramétrico para IBM es 42199,839069714886
El resultado del VaR paramétrico para MSFT es 40618,179754271754
El resultado del VaR paramétrico para INTC es 42702,930219301255
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Fuera[39]: matriz([42199.83906971, 40618.17975427, 42702.9302193 ])

En [40]: VaR_parametric_denoised(initial_investment, conf_level)


El resultado del VaR paramétrico para IBM es [42199.83906971 40618.17975427
42702.9302193 ]
El resultado del VaR paramétrico para MSFT es [42199.83906971 40618.17975427
42702.9302193 ]
El resultado del VaR paramétrico para INTC es [42199.83906971 40618.17975427
42702.9302193 ]
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Fuera[40]: matriz([42259.80830949, 40678.14899405, 42762.89945907])


Machine Translated by Google

Relación del número de observaciones T con el número de variables N.

Identificación del ancho de banda para la estimación de la densidad del kernel.

Generando la matriz de covarianza sin ruido.

Incorporar la matriz de covarianza sin ruido a la fórmula VaR.

La diferencia entre el VaR tradicionalmente aplicado y el VaR denominado es aún más


pronunciada en el período de crisis. Durante el período de crisis, la correlación entre los
activos aumenta, lo que a veces se denomina ruptura de correlación. Las posibles
consecuencias de la ruptura de la correlación pueden ser dos:

Un aumento del riesgo de mercado que hace que la diversificación se vuelva


menos efectiva.

Haciendo la cobertura aún más difícil.

Para comprobar este fenómeno, consideramos el período de crisis financiera 2017­2018


y el período de crisis exacto se obtiene del NBER, que anuncia los ciclos económicos
(ver [https://www.nber.org/research/data/us­business ­ciclo­expansiones­y­contracciones]
para más información).

El resultado confirma que la correlación y, por tanto, el VaR aumentan durante el


período de crisis.

Ahora, logramos obtener el VaR basado en ML utilizando una matriz de covarianza sin
ruido en lugar de una matriz empírica que calculamos directamente a partir de los datos.
A pesar de su atractivo y facilidad, el VaR no es una medida de riesgo coherente. Ser una
medida de riesgo coherente requiere que se cumplan ciertas condiciones o axiomas. Puede
pensar en estos axiomas como requisitos técnicos para una medida de riesgo.

Sea α (0, 1) un nivel de confianza fijo y (ωFP) un espacio de probabilidad en el que ω


representa un espacio muestral, F denota un subconjunto del espacio muestral y P es
una medida de probabilidad.
Machine Translated by Google

NOTA
Para ilustrar, digamos que ω es el conjunto de todos los resultados posibles en caso de lanzar una moneda, ω=
{ω}=2
{H,T}. F puede tratarse como lanzar una moneda dos veces, F=2 2. Finalmente, la medida de probabilidad, P, es que
la probabilidad de obtener cruz es 0,5.

Aquí están los cuatro axiomas de una medida de riesgo coherente:

1) Invariancia de traducción: Para todos los resultados Y y una constante a R, tenemos

V aR(Y1 + Y2) = V aR(Y ) + a

Significa que si se agrega una cantidad sin riesgo de a a la cartera, se obtiene un VaR más bajo
por la cantidad de a.

2) Subaditividad: Para todos los Y1 e Y2 tenemos

V aR(Y1 + Y2) ≤ V aR(Y1) + V aR(Y2)

Este axioma subraya la importancia de la diversificación en la gestión de riesgos. Tome Y1 e Y2


como dos activos, si ambos están incluidos en la cartera, el resultado será un valor en riesgo
menor que incluirlos por separado. Comprobemos si el VaR satisface o no el supuesto de
subaditividad:

En [41]: activo1 = [­0,5, 0, 0,1, 0,4]


VaR1 = np.percentile(asset1, 90)
print('VaR para el Activo 1 es {:.4f}'.format(VaR1)) activo2
= [0, ­0,5, 0,01, 0,4]
VaR2 = np.percentile(asset2, 90)
print('VaR para el Activo 2 es {:.4f}'.format(VaR2))
VaR_all = np.percentile(asset1 + active2, 90)
print('VaR para la cartera es {:.4f}'.format(VaR_all))
El VaR para el Activo 1 es 0,3100
El VaR para el Activo 2 es 0,2830
El VaR para la cartera es 0,4000

En [42]: activo1 = [­0,5, 0, 0,05, 0,03]


VaR1 = np.percentile(asset1, 90)
print('VaR para el Activo 1 es {:.4f}'.format(VaR1)) activo2
= [0, ­0,5, 0,02, 0,8]
VaR2 = np.percentil(activo2,90)
Machine Translated by Google

print('VaR para el Activo 2 es {:.4f}'.format(VaR2))


VaR_all = np.percentile(asset1 + active2 , 90)
print('VaR para la cartera es {:.4f}'.format(VaR_all))
El VaR para el Activo 1 es 0,0440
El VaR para el Activo 2 es 0,5660
El VaR para la cartera es 0,2750

Rentabilidad del activo para el primer activo.

Rentabilidad del activo para el segundo activo.

Resulta que el VaR de la cartera es menor que la suma de los VaR individuales, lo que
no tiene sentido debido a la mitigación del riesgo mediante la diversificación. Más
detalladamente, el VaR de la cartera debería ser menor que la suma de los VaR individuales
a través de la diversificación, ya que la diversificación mitiga el riesgo, lo que a su vez
reduce el VaR de la cartera.

3) Homogeneidad positiva: para todos los resultados Y y a>0, tenemos

V aR(aY ) = aV aR(L)
Implica que el riesgo y el valor de la cartera van en conjunto, es decir, si el valor de una cartera
aumenta en una cantidad de a, el riesgo aumenta en una cantidad de a.

4) Monotonicidad: para 2 resultados cualesquiera, Y1 e Y2, si Y1 ≤ Y2, entonces

V aR(Y1) ≥ V aR(Y2)
Al principio puede parecer desconcertante pero es intuitivo. La monotonicidad indica que un
activo con mayor rendimiento tiene un menor VaR.

A la luz de la discusión anterior, ahora sabemos que el VaR no es una medida de riesgo
coherente. Pero no te preocupes, el VaR no es la única herramienta con la que estimamos
el riesgo de mercado. El déficit esperado es otra medida coherente del riesgo de mercado.

Déficit esperado A diferencia del VaR,

el déficit esperado se centra en la cola de la distribución. De manera más elaborada, el déficit


esperado nos permite tener en cuenta la
Machine Translated by Google

Riesgos inesperados en el mercado. Sin embargo, esto no significa que el déficit esperado
y el VaR sean dos conceptos completamente diferentes. Más bien, están relacionados,
es decir, es posible expresar el déficit esperado utilizando el VaR.

Supongamos ahora que la distribución de pérdidas es continua, entonces se espera que


El déficit se puede definir matemáticamente como:
1
ESα = 1 1−α ∫ α qudu

donde q denota el cuantil de la distribución de pérdidas. La fórmula del déficit esperado sugiere
que no es más que un promedio ponderado de probabilidad de (1 − α)% de las pérdidas.

Sustituyamos qu y VaR, lo que nos da la siguiente ecuación:


1
ESα = 1 1−α ∫ α V aRudu

Alternativamente, es la media de pérdidas que exceden el VaR como se muestra a continuación:

ESα = E(L|L > V aRα)


La distribución de pérdidas puede ser continua o discreta y, como se puede imaginar, si toma la
forma discreta, el déficit esperado se vuelve diferente como se indica a continuación:

ESα = 1 1−α ∑1 norte=0 máx(Ln) * P(Ln)


donde max(Ln) muestra la enésima pérdida más alta y Prob(Ln) indica la probabilidad
de la pésima pérdida más alta.

En [43]: def ES_parametric(initial_investment , conf_level): alfa = ­ norm.ppf(1 ­


conf_level,stocks_returns_mean,port_std) para i,j en zip(stocks.columns,
range(len(stocks.columns))): VaR_param = (inversión_inicial * alfa)[j]

ES_param = (1 / (1 ­ conf_level)) * norma.expect(lambda x:


VaR_param,
lb = conf_level)
print(f"El resultado de ES paramétrico para {i} es {ES_param}")

En [44]: ES_parametric(inversión_inicial, nivel_conf)


El resultado de ES paramétrico para IBM es 144370.82004213505
Machine Translated by Google

El resultado de ES paramétrico para MSFT es 138959,76972934653


El resultado de ES paramétrico para INTC es 146091,9565067016

Estimación del VaR de varianza­covarianza.

Dado el intervalo de confianza, estimando el ES con base en el VaR.

ES también se puede calcular basándose en las observaciones históricas. De


manera similar al método VaR de simulación histórica, los supuestos paramétricos
pueden relajarse. Para ello primero se encuentra el retorno (o pérdida) correspondiente
al 95% y luego la media de las observaciones mayores al 95% nos da el resultado.
Aquí, esto es lo que hacemos:

En [45]: def ES_historical(initial_investment, conf_level):


para i, j en zip(stocks_returns.columns,
rango(len(stocks_returns.columns))):
ES_hist_percentile95 = np.percentile(stocks_returns.loc[:, i], 5)
ES_historical = retornos_acciones[cadena(i)][retornos_acciones[cadena(i)] <=
ES_hist_percentile95].media()

print("El resultado histórico de ES para {} es {:.4f} "


.formato(i, inversión_inicial * ES_histórico))

En [46]: ES_historical(inversión_inicial, nivel_conf)


El resultado histórico de ES para IBM es ­64802,3898 El
resultado histórico de ES para MSFT es ­65765,0848 El
resultado histórico de ES para INTC es ­88462,7404

Calculando el 95% de los retornos.

Estimación del ES con base en las observaciones históricas.

Hasta ahora hemos visto cómo modelar el déficit esperado de forma tradicional. Ahora
es el momento de introducir un enfoque basado en ML para mejorar aún más el
rendimiento de la estimación y la confiabilidad del modelo ES.

Déficit esperado de liquidez aumentada


Machine Translated by Google

Como ya se ha comentado, ES nos proporciona una medida de riesgo coherente para medir el riesgo de

mercado. Sin embargo, aunque diferenciamos el riesgo financiero en mercado, crédito, liquidez y operativo,

eso no significa necesariamente que estos riesgos no tengan ninguna relación entre sí. Más bien, hasta

cierto punto, están correlacionados.

Es decir, una vez que una crisis financiera golpea el mercado, los aumentos repentinos del riesgo de

mercado se alinean con la reducción de las líneas de crédito, lo que a su vez aumenta el riesgo de liquidez.

Dada la situación de la economía, el efecto de la iliquidez varía, ya que se vuelve común durante las

grandes crisis del mercado, pero es más manejable en tiempos normales. Por lo tanto, su impacto

será más distintivo en el mercado a la baja.

Este hecho es apoyado por Antoniades afirmando que

El fondo común de activos líquidos es la restricción de recursos a través de la cual el riesgo de liquidez
puede afectar la oferta de crédito hipotecario. Durante la crisis financiera de 2007­2008, la
principal fuente de tensiones sobre las condiciones de financiación bancaria surgió de la iliquidez de
financiación experimentada en los mercados de financiación mayorista.

—Antoniades (Riesgo de liquidez y crisis crediticia de 2007­2008: evidencia de


datos a nivel micro sobre solicitudes de préstamos hipotecarios, 2014, p.6)

Ignorar la dimensión de liquidez del riesgo puede provocar una subestimación del riesgo de mercado. Por

lo tanto, aumentar los ES con el riesgo de liquidez puede dar como resultado una estimación más

precisa y confiable. Bueno, suena atractivo, pero ¿cómo podemos encontrar un indicador de la liquidez?
Machine Translated by Google

NOTA
La liquidez se puede definir como la facilidad de transacción con la que se pueden vender activos en un período de
tiempo muy corto sin un impacto significativo en el precio de mercado. Hay dos medidas principales de liquidez:

Liquidez del mercado: La facilidad con la que se negocia un activo.

Liquidez de financiación: La facilidad con la que el inversor puede obtener financiación.

La liquidez y el riesgo que de ella se deriva se analizarán con mayor detalle en el Capítulo 7. Por lo tanto, gran parte
de la discusión queda para este capítulo.

En la literatura, las medidas de diferencial entre oferta y demanda se utilizan comúnmente para modelar la

liquidez. En resumen, el diferencial entre oferta y demanda es la diferencia de los precios entre oferta y

demanda. Dicho de otra manera, es la diferencia entre el precio más alto disponible (precio de oferta) que un

comprador está dispuesto a pagar y el precio más bajo (precio de venta) que un vendedor está dispuesto a

obtener. Por lo tanto, el diferencial entre oferta y demanda proporciona una herramienta para medir el
costo de transacción.

En la medida en que el diferencial entre oferta y demanda es un buen indicador del costo de
transacción, también es un buen indicador de la liquidez en el sentido de que el costo de transacción
es uno de los componentes de la liquidez. Los diferenciales se pueden definir de varias maneras
dependiendo de su enfoque. Estos son los diferenciales de oferta y demanda que utilizaremos
para incorporar el riesgo de liquidez en el modelo ES.

Spread efectivo

Spread efectivo = 2 * |(Pt − Pmid)|


donde Pt es el precio de transacción en el momento t y Pmid es el punto medio de la oferta
compradora ( (Pask − Pbid)/2) vigente en el momento t.

Spread cotizado proporcional

Spread cotizado proporcional = (Pask − Pbid)/Pmid


donde Pask es el precio de venta y Pbid y Pmid son el precio de oferta y el precio medio,
respectivamente.
Machine Translated by Google

Spread cotizado

Spread cotizado = Pask − Pbid


Spread efectivo proporcional:

Spread efectivo proporcional = 2 * (|Pt − Pmid|)/Pmid

Costo efectivo
(Pt − Pmid)/Pmid para el comprador iniciado
Costo efectivo = { (Pmid/Pt)/Pmid para vendedor iniciado

La operación iniciada por el comprador ocurre cuando una operación se ejecuta a un precio
superior al precio medio cotizado. De manera similar, la operación iniciada por el vendedor ocurre
cuando una operación se ejecuta a un precio inferior al precio medio cotizado.

Ahora, necesitamos encontrar una manera de incorporar estos diferenciales entre oferta y demanda en
el modelo ES para que podamos tener en cuenta el riesgo de liquidez así como el riesgo de mercado.
Empleamos dos métodos diferentes para realizar esta tarea. La primera es tomar la media transversal del
diferencial de oferta y demanda como lo sugieren Chordia et al. (2000) y Pastor y Stambaugh (2003). El
segundo método consiste en aplicar el Análisis de Componentes Principales (PCA) propuesto por
Mancini et al. (2013).

La media transversal no es más que promediar el diferencial entre oferta y demanda. Con este método, podemos

generar una medida de la liquidez de todo el mercado. La fórmula promediada es la siguiente: ∑N Li,t

1
LM,t = norte i

donde LM,t es la liquidez del mercado y Li,t es la medida de liquidez individual, es decir, el
diferencial de oferta y demanda en nuestro caso.

ESL = ES + Costo de Liquidez


1
ESL = 1 1−α ∫ α
V a Rudu + 12
Plast(μ + kσ)
dónde
Machine Translated by Google

Plast es el precio de cierre de las acciones.

μ es la media de dispersión.

k es el factor de escala para dar cabida a la cola gruesa.

σ es la desviación estándar del diferencial.

En [47]: bid_ask = pd.read_csv('bid_ask.csv')

En [48]: bid_ask['mid_price'] = (bid_ask['ASKHI'] + bid_ask['BIDLO']) / 2 comprador_vendedor_iniciado


= [] para i en el rango(len(bid_ask)):

if bid_ask['PRC'][i] > bid_ask['mid_price'][i]:


comprador_vendedor_iniciado.append(1)
más:
comprador_vendedor_iniciado.append(0)

bid_ask['buyer_seller_init'] = comprador_vendedor_iniciado

En [49]: costo_efectivo = []
para i en el rango(len(bid_ask)): if
bid_ask['buyer_seller_init'][i] == 1:
Effective_cost.append((bid_ask['PRC'][i] ­ bid_ask['mid_price'][i])
/
bid_ask['mid_price'][i])
demás:
costo_efectivo.append((bid_ask['mid_price'][i] ­ bid_ask['PRC']
[i])/
bid_ask['mid_price'][i])
bid_ask['coste_efectivo'] = costo_efectivo

En [50]: bid_ask['quoted'] = bid_ask['ASKHI'] ­ bid_ask['BIDLO']


bid_ask['prop_quoted'] = (bid_ask['ASKHI'] ­ bid_ask['BIDLO']) / \
bid_ask['mid_price']
bid_ask['efectivo'] = 2 * abs(bid_ask['PRC'] ­ bid_ask['mid_price']) bid_ask['prop_efectivo'] = 2 *
abs(bid_ask['PRC'] ­ bid_ask ['precio_medio'])
/\
bid_ask['RPC']

En [51]: spread_measures = bid_ask.iloc[:, ­5:]


spread_measures.corr()
Fuera[51]: costo_efectivo cotizado prop_quoted efectivo \ 0.727917
costo_efectivo 1.000000 0.441290 0.800894
cotizado 0,441290 1,000000 0,628526 0,717246
prop_citado 0,727917 0,628526 1,000000 0,514979
Machine Translated by Google

efectivo 0,800894 0,717246 0,514979 1,000000


prop_efectivo 0,999847 0,442053 0,728687 0,800713

prop_efectivo
costo_efectivo 0.999847
cotizado 0.442053
prop_citado 0.728687
efectivo 0.800713
prop_efectivo 1.000000

En [52]: spread_measures.describe()
Out[52]: recuento de citado prop_citado efectivo prop_efectivo
costos_efectivos
756.000000 756.000000 756.000000 756.000000
756.000000
significar 0.004247 1.592583 0.015869 0.844314
0.008484
0.003633 0.921321 0.007791 0.768363
estándar 0.007257
0.000000 0.320000 0.003780 0.000000
mín . 0,000000
25% 0.001517 0.979975 0.010530 0.300007
0.003029
50% 0.003438 1.400000 0.013943 0.610000
0.006874
75% 0.005854 1.962508 0.019133 1.180005
0.011646
máximo 0.023283 8.110000 0.055451 6.750000
0.047677

En [53]: high_corr = spread_measures.corr().unstack()\


.sort_values(ascendente=Falso).drop_duplicates()
high_corr[(high_corr > 0.80) & (high_corr != 1)]
Fuera[53]: costo_efectivo prop_efectivo 0.999847
efectivo costo_efectivo prop_efectivo tipo 0.800894
d efectivo: float64 0.800713

En [54]: medidas_difusión_clasificadas = bid_ask.iloc[:, ­5:­2]

En [55]: cross_sec_mean_corr = sorted_spread_measures.mean(axis=1).mean()


std_corr = medidas_difusión_clasificadas.std().sum() / 3

En [56]: df = pd.DataFrame(índice=acciones.columnas)
últimos_precios = []
para i en símbolos:
last_prices.append(existencias[i].iloc[­1])
df['últimos_precios'] = últimos_precios
Machine Translated by Google

En [57]: def ES_parametric(inversión_inicial, nivel_conf):


ES_params = []
alpha = ­ norm.ppf(1 ­ conf_level, stocks_returns_mean, port_std) para i,j en
zip(stocks.columns,range(len(stocks.columns))): VaR_param =
(initial_investment * alpha)[j ]
ES_param = (1 / (1 ­ conf_level)) * norma.expect(lambda x:
VaR_param,
lb = nivel_conf)
ES_params.append(ES_param)
devuelve ES_params

En [58]: ES_params = ES_parametric(initial_investment,conf_level) para i en el


rango(len(symbols)):
print(f'El resultado del déficit esperado para {symbols[i]} es
{ES_params[i]}')
El resultado del déficit esperado para IBM es 144370,82004213505 El
resultado del déficit esperado para MSFT es 138959,76972934653 El
resultado del déficit esperado para INTC es 146091,9565067016

En [59]: k = 1,96 para


i, j en zip(rango(len(símbolos)), símbolos):
print('El ES ajustado por liquidez de {} es {}' .format(j,
ES_params[i] + (df.loc[j].values[0] / 2) * (cross_sec_mean_corr + k *
std_corr)))
El ES ajustado por liquidez de IBM es 144443.0096816674 El ES
ajustado por liquidez de MSFT es 139087.3231105412 El ES ajustado
por liquidez de INTC es 146120.5272712512

Importando los datos de bid_ask .

Calculando el precio medio.

Condición definitoria para el comercio iniciado por comprador y vendedor.

Si se cumple la condición anterior, devuelve 1 y se agrega a la lista comprador_vendedor_iniciado .

Si la condición anterior no se cumple, devuelve 0 y se agrega a la lista comprador_vendedor_iniciado .

Si la variable comprador_vendedor_iniciado toma el valor de 1, se ejecuta la fórmula de costo


efectivo correspondiente.
Machine Translated by Google

Si la variable comprador_vendedor_iniciado toma el valor de 0, se ejecuta la fórmula de


costo efectivo correspondiente.

Se calculan los diferenciales cotizados, cotizados , y proporcional efectivo


proporcionalmente y efectivos.

Se obtienen matrices de correlación y se enumeran en columnas.

Clasificando la correlación mayor al 80%.

Calcular la media transversal de las medidas de dispersión.

Obtención de la desviación estándar de los diferenciales.

Filtrar los últimos precios de las acciones observados a partir de los datos de las acciones .

Estimación de los SE ajustados por liquidez.

PCA es un método utilizado para reducir la dimensionalidad. Se utiliza para extraer la mayor cantidad
de información posible utilizando la menor cantidad de componentes posible. Es decir, en este
ejemplo, de 5 características, elegimos 2 componentes según la Figura 5­4 que se
muestra a continuación. Entonces, reducimos la dimensionalidad a expensas de perder
información. Porque dependiendo del punto de corte que decidamos, elegimos el número de
componentes y perdemos información tanto como la cantidad de componentes que dejamos.

Para ser más específicos, el punto en el que la Figura 5­4 se vuelve más plana implica que
retenemos menos información y este es el punto de corte para el PCA. Sin embargo, no es una
decisión fácil ya que existe un equilibrio entre el punto de corte y la información retenida. Es decir,
por un lado, cuanto mayor sea el punto de corte (cuanto mayor número de componentes) tengamos,
más información retendremos (menos dimensionalidad reduciremos). Por otro lado, cuanto menor
sea el punto de corte (menos número de componentes tenemos), menos información retenemos
(mayor dimensionalidad reducimos). Conseguir un terreno de pedregal más plano no es un mero
criterio para seleccionar el número adecuado de componentes. Entonces, ¿cuál sería el
Machine Translated by Google

posibles criterios para seleccionar el número adecuado de componentes. Estos son los
posibles criterios de corte para PCA:

Más del 80% de la varianza explicada

Mayor que 1 valores propios

El punto en el que el pedregal se vuelve más plano.

Sin embargo, la reducción de dimensionalidad no es lo único que aprovechamos. En


este estudio, aplicamos PCA para beneficiarnos de obtener características peculiares de
liquidez. Porque PCA filtra la información más importante de los datos para nosotros.

Las matemáticas detrás del PCA se analizan en detalle en el Apéndice.

ADVERTENCIA

Tenga en cuenta que el ajuste de liquidez también se puede aplicar al VAR. El mismo procedimiento
se aplica al VaR. Matemáticamente,

V aRL = σp√tZα + 12
Plast(μ + kσ)

Esta aplicación se deja al lector.

En [60]: desde sklearn.decomposition importar PCA


desde sklearn.preprocessing importar StandardScaler

En [61]: escalador = StandardScaler()


spread_measures_scaled = scaler.fit_transform(np.abs(spread_measures)) pca =
PCA(n_components=5)
prin_comp = pca.fit_transform(spread_measures_scaled)

En [62]: var_expl = np.round(pca.explained_variance_ratio_, decimales=4)


cum_var = np.cumsum(np.round(pca.explained_variance_ratio_, decimals=4))
print('Las variaciones explicadas individualmente son:\n{}'.format(var_expl))
print('=='*30)
print(' Las variaciones acumuladas explicadas son: {}'.format(cum_var))
Las varianzas explicadas individualmente
son: [0,7494 0,1461 0,0983 0,0062 0. ]
==================================================== ==========

Las variaciones acumuladas explicadas son: [0,7494 0,8955 0,9938 1. 1. ]


Machine Translated by Google

En [63]: plt.plot(pca.explained_variance_ratio_)
plt.xlabel('Número de componentes')
plt.ylabel(' Explicación de la variación')
plt.title(' Gráfico de pantalla')
plt.savefig('Scree_plot.png') plt.show()

En [64]: pca = PCA(n_components=2)


pca.fit(np.abs(spread_measures_scaled))
prin_comp = pca.transform(np.abs(spread_measures_scaled)) prin_comp
= pd.DataFrame(np.abs(prin_comp), columnas = ['Componente 1', 'Componente 2'])

print(pca.explained_variance_ratio_*100)
[65.65640435 19.29704671]

En [65]: def myplot(puntuación, coeficiente, etiquetas=Ninguno):


xs = puntuación[:,
0] ys = puntuación[:,
1] n = coeff.shape[0]
scalex = 1,0 / (xs.max() ­ xs.min()) scaley =
1,0 / (ys.max( ) ­ ys.min()) plt.scatter(xs *
scalex * 4, ys * scaley * 4, s=5) para i en rango(n): plt.arrow(0,
0, coeff[i, 0] , coeff[i,
1], color = 'r', alpha=0.5) si las etiquetas son Ninguna: plt.text(coeff[i, 0], coeff[i, 1],
"Var"+str(i),
color='negro') else: plt.text(coeff[i,0 ], coeff[i, 1], etiquetas[i], color='negro')

plt.xlabel("PC{}".format(1))
plt.ylabel("PC{}".format(2)) plt.grid()

En [66]: spread_measures_scaled_df = pd.DataFrame(spread_measures_scaled,


columnas = medidas_difusión.columnas)

En [67]: myplot(np.array(spread_measures_scaled_df)[:, 0:2],


np.transpose(pca.components_[0:2,:]),
list(spread_measures_scaled_df.columns))
plt.savefig('Bi_plot.png') plt.show()

Estandarización de las medidas de diferencial.

Identificando el número de componentes principales como 5.


Machine Translated by Google

Aplicando el componente principal a spread_measures_scaled.

Observando la varianza explicada de los cinco componentes principales.

Observación de la varianza explicada acumulada de los cinco componentes principales.

Dibujar el diagrama de pedregal.

Con base en el diagrama de pedregal, decida el número de componentes como 2 que se usarán en
el análisis de PCA.

Dibujar el biplot para observar la relación entre componentes y características.

Figura 5­4. Gráfico de pantalla PCA


Machine Translated by Google

Figura 5­5. Biplot PCA

Muy bien, ya tenemos toda la información necesaria y estamos incorporando esto.


información, podemos calcular los ES ajustados por liquidez. Como era de esperar,
El siguiente código revela que el ES ajustado por liquidez proporciona mayores
valores en comparación con la aplicación ES estándar. Esto implica que incluir
La dimensión de liquidez en la estimación de ES resulta en un mayor riesgo. Tenga en cuenta que
la diferencia será más pronunciada durante la crisis.

En [68]: prin_comp1_rescaled = prin_comp.iloc[:,0] * prin_comp.iloc[:,0].std()\


+ prin_comp.iloc[:, 0].media()
prin_comp2_rescaled = prin_comp.iloc[:,1] * prin_comp.iloc[:,1].std()\
+ prin_comp.iloc[:, 1].mean()
prin_comp_rescaled = pd.concat([prin_comp1_rescaled, prin_comp2_rescaled],
eje=1)
prin_comp_rescaled.head()
Fuera[68]: Componente 1 Componente 2
0 1.766661 1.256192
1 4.835170 1.939466
2 3.611486 1.551059
Machine Translated by Google

3 0.962666 0.601529
4 0.831065 0.734612

En [69]: mean_pca_liq = prin_comp_rescaled.mean(axis=1).mean()


mean_pca_liq
Fuera[69]: 1.0647130086973815

En [70]: k = 1,96 para


i, j en zip(rango(len(símbolos)), símbolos):
print('El ES ajustado por liquidez de {} es {}' .format(j,
ES_params[i] + (df.loc[j].values[0] / 2) * (mean_pca_liq + k *
std_corr)))
El ES ajustado por liquidez de IBM es 144476.18830537834 El ES
ajustado por liquidez de MSFT es 139145.94711344707 El ES ajustado
por liquidez de INTC es 146133.65849966934

Calcular la parte de liquidez de la fórmula ES ajustada por liquidez para el primer


componente principal.

Calcular la parte de liquidez de la fórmula ES ajustada por liquidez para el primer


componente principal.

Calcular la media de la sección transversal de los dos componentes principales.

Estimación de los SE ajustados por liquidez.

Conclusión
El riesgo de mercado siempre ha estado bajo escrutinio, ya que nos indica hasta qué punto
una empresa es vulnerable al riesgo que emana de los acontecimientos del mercado. En
un libro de texto de gestión de riesgos financieros, es habitual encontrar un modelo VaR y
ES, que son dos modelos destacados y comúnmente aplicados en la teoría y la práctica.
En este capítulo, después de proporcionar una introducción a estos modelos, se presentan
modelos de vanguardia para revisar y mejorar la estimación del modelo. Para ello, primero
intentamos distinguir la información que fluye en forma de ruido y de señal, lo que se
denomina eliminación de ruido. A continuación, se emplea una matriz de covarianza sin
ruido para mejorar la estimación del VaR.
Machine Translated by Google

Luego, se analiza el modelo ES como una medida de riesgo coherente. El método que
aplicamos para mejorar este modelo es un enfoque basado en la liquidez mediante el cual
revisamos el modelo eS y lo aumentamos utilizando el componente de liquidez para que sea
posible considerar el riesgo de liquidez al estimar los ES.

También es posible realizar mejoras adicionales en la estimación del riesgo de mercado, pero el
objetivo es dar una idea y herramientas para proporcionar un terreno adecuado para los
enfoques de riesgo de mercado basados en el ML. Sin embargo, puedes ir más allá y aplicar
diferentes herramientas. En el próximo capítulo, discutiremos el modelo de riesgo
crediticio sugerido por organismos reguladores como el Comité de Supervisión Bancaria
de Basilea (BCBS) y enriqueceremos este modelo utilizando un enfoque basado en ML.

Recursos adicionales
Artículos citados en este capítulo:

Antoniades, Adonis. "Riesgo de liquidez y crisis crediticia de 2007­2008: evidencia de


datos a nivel micro sobre solicitudes de préstamos hipotecarios". Revista
de análisis financiero y cuantitativo (2016): 1795­1822.

Bzdok, D., N. Altman y M. Krzywinski. "Puntos importantes: estadísticas versus


aprendizaje automático". Métodos de la naturaleza (2018): 1­7.

BIS, Cálculo de APR por riesgo de mercado, 2020.

Chordia, Tarun, Richard Roll y Avanidhar Subrahmanyam.


"Comunes en la liquidez". Revista de economía financiera 56, no. 1 (2000): 3­28.

Mancini, Loriano, Angelo Ranaldo y Jan Wrampelmeyer.


“Liquidez en el mercado cambiario: medición, puntos comunes y primas
de riesgo”. El Diario de Finanzas 68, no. 5 (2013): 1805­1841.

Pástor, Ľuboš y Robert F. Stambaugh. "Riesgo de liquidez y rentabilidad


esperada de las acciones". Revista de Economía Política 111, núm. 3
Machine Translated by Google

(2003): 642­685.

Libros citados en este capítulo:

Dowd, Kevin. Una introducción a la medición del riesgo de mercado. John Wiley e
hijos, 2003.

De Prado ML. Aprendizaje automático para gestores de activos. Prensa de la


Universidad de Cambridge, 2020.

1 Los detalles del procedimiento se pueden encontrar en este enlace [ https://hudsonthames.org/portfolio­


optimización­con­portfoliolab­estimación­de­riesgo/
Machine Translated by Google

Sobre el Autor

Abdullah Karasan nació en Berlín, Alemania. Después de estudiar Economía y


Administración de Empresas en la Universidad de Gazi­Ankara, obtuvo su
maestría en la Universidad de Michigan­Ann Arbor y su doctorado en Matemáticas
Financieras en la Universidad Técnica de Medio Oriente (METU)­Ankara. Trabajó
como Contralor del Tesoro en la Subsecretaría del Tesoro de Turquía. Más
recientemente, comenzó a trabajar como consultor e instructor senior en ciencia de
datos para empresas en Turquía y Estados Unidos.
Actualmente, es consultor de Ciencia de Datos en Datajarlabs y mentor de Ciencia
de Datos en Thinkful.

También podría gustarte