Exploraión de los datos

Primero descargamos y analizamos los datos utilizados en este proyecto, los cuales son empresas peruanas que accionan en la bolsa de Estados unidos. LA acción de análisis fundamental el cual se tomara se Credicorp representada con el ticker BAP.

En la siguiente tabla se encuentran los datos que vammos a utlizar a lo largo de este trabajo, el cual se puede descargar los datos para el uso del lector.

Resumen general

Ahora después de haber descargado los datos procedemos a realizar un resumen de estos, en la cual se mostrara los siguienres aspectos:

  • La medeia.
  • La desviasión estandar.
  • El valor máximo.
  • El valor mínimo.
  • Gráfico de cajas.
  • Gráfico de lineas.
  • El histograma.
Mean SD Median Min Max Boxplot Histogram Line
SCCO 35.38 13.07 32.73 18.89 81.41
BAP 169.57 44.00 155.69 81.57 250.70
BVN 11.90 3.13 12.31 3.31 17.71
CPAC 6.86 1.43 6.83 3.64 10.05
FSM 4.76 1.64 4.53 1.80 9.54

Este gráfico se puede ver en la acción BAP que su valor mínimo es de 81.57 y su máximo es de 250.70 por lo cual se decidió tomar 8 estados para hacer el pronstico de para l aacción de credicorp

library(PerformanceAnalytics)
chart.TimeSeries(precios %>% scale(),legend.loc = "left",main = "Cotizaciones de las acciones peruanas")

Implementación de la cadena de markov

Ahora tomamos la serie de BAP y hallamos matiz de estado de esta serie tomando solo 7 estados como se dijo en la primera parte.

contrucción de la matriz de estados

Lo primero es definir los estados de la serie los cuales se obtiene el comando seq() lo que permite dividir el rango entre el minimo y el máximo de la serie en una secuencia de 8 valores, de esos 8 valores se toman los limites para cada estado. Después de realizar eso queda el paso de armar la matriz de frecuencia para ver el cambio de estado a estado. lo cual se puede hacer con la función table() y resagando la serie un periodo. Como ultimo paso se divide cada fila entre su total y se obtiene la matriz de transición.

Matriz de estados transitorios
1 2 3 4 5 6 7
95 3 0 0 0 0 2
3 188 11 0 0 0 14
0 9 412 11 0 0 14
0 0 13 141 2 0 4
0 0 0 2 77 12 5
0 0 0 0 13 335 20
2 15 11 6 4 21 187

Entrenemaineto del modelo

Después de ver hallado la matriz de transción seperamos los datos en test y entrenamiento. En el caso del test se tiene los siguientes resultados plasmado en el sigueinte gráfico y cuadro.

Cuadro de resultados

Interpretación: Podemos observar que los estados predichos y la serie original concuerdan en un 100%. En este caso la predicción o el valor pronosticado es la media entre los intervalos de los estados en este caso es en el estado número 2.

Gráfico de los resultados

Interpretación: En este gráfico podemos observar que el valor predicho es constante en todo la serie esto se debe a que la predicción solo da un intervalo esto se sera explicado en el pronostico en donde se verá los intervaloes de la serie.

Predicción hacia al futuro

Vamos a realizar una predicción hacia el futuro en 10 periodos y se graficara el intervalo de confianza.

Interpretación: Como se menciono alteriormente que se tomaba la media de cada de intervalo de los 7 estados y se puede observar que el precio fluctua en el intervalo marcado de color azul.

Modelos de series de tiempo

Ahora después de haber analizado la serie con el metodo de cadenas de markov, se procede a realiazar diversos metodos de series de tiempo y de redes neuronales para comparar cual de estos modelos me da una mejor predicción.

Primero se analiza la serie para ver si hay precencia de datos atipicos.

Datos atipicos

Primero vamos a graficar el famoso diagrama de cajas el cual nos permite ver si hay datos atipicos:

Interpretación: Podemos ver el inicio y el final de la data tomada para este trabajo. Se puede observar que en los años 2016 y 2020 presentan una gran cantidad de datos atipicos, esto se observa más en el año 2020 el cual se ve reflejado el impacto del covid 19.

La segunda opción es usando un paquete de R el cual es anomalize y nos permite hallar los valores atipicos mediante un grafico en el cual me da un intervalo de confianza, los valores de rojo son aquellos atipicos.

Interpretación: Como se anlizo antes se puede observar que en donde hay más datos atipicos es en el año 2020.

Analizar los retornos

Cuando se analizan las estas series con los modelos ARIMA una condición es que esta serie sea estacionaria para esto se va analizar con el test de dicker-fuller, en el cual consiste en no rechazar la hipotesis alternativa osea que el p-value sea menor a 0.05.

El resulatdo obtenido al aplicar este test es de 0.9573389 por la cual no se rechaza la hipotesis nula por lo cual se tiene que diferrenciar la serie.

Para esto se calcula los retornos de la serie y se compara con la serie antigua,

Interpretación: Se puede observar las diferencias entre las series. La serie diferenciada se mueve entorno a una media de 0.

Después de diferenciar la serie se compara sus acf y pcaf para tomar el mejor modelo ARIMA. Antes de este paso vamos a limpiar la serie es decir que vamos a quitar el ruido, ruido seria cuando se generan anomaliaz en esta serie. Uno de los metodos es usar el filtro kalman pero este se aplicara en el codigo de python en este caso se usara el fltro de hampel.

library(pracma )
data<- data.frame("fecha"=index(d),"retornos"=as.numeric(d))
omad <- hampel(data$retornos, k=20)
data$"filtro"<- NA
data$"filtro"[omad$ind]<- data$retornos[omad$ind]
ggplot(data)+geom_line(mapping = aes(x=fecha,y=retornos),color="red",alpha=0.5)+
  geom_point(mapping = aes(y=filtro,x=fecha),color="blue")+labs(title="Filtro de hampel")+theme_elegante()

table_t(data[omad$ind,c(1,2)] %>% as.data.frame(),"blue","Fuente: Propia","Resulatdo del algoritmo")

En este cuadro se puede ver los precios y las fechas en los cuales el algoritmos los a clasificado como anomalos.

despues de esto se reemplaza los valores atipicos respecto a su mediana.

d<- diff(precios$BAP)[-1]
omad <- hampel(d, k=20)
d_new<- omad$y

ACF y PACF

Con la limpieza ya hecha ahora procedemos analizar el mejor modelo ARIMA. Para esto usaremos un ciclo for y se mostrara los resultados.

Ahora mostrareos el ACF:

ACF

Interpretación: Se puede tomar el rezago 2 y el 4 para el orden de autorregresivos.

PACF

Interpretación: Se puede tomar el rezago 2 y el 4 para el orden de medias moviles.

Implemntación del algoritmo

Para esta parte se tomara 5 rezagos para crear el modelo es decir se ira probando mediante un ciclo for cual de todos es el mejor modelo tomando como referencia el criterio de akaike.

Modelos calculados
z1 sigma logLik AIC BIC
2 ARMA(0,0) 2.985154 -4100.547 8205.093 8215.888
3 ARMA(0,1) 2.976497 -4095.810 8197.619 8213.812
4 ARMA(0,2) 2.965851 -4089.969 8187.938 8209.528
5 ARMA(0,3) 2.965256 -4089.642 8189.283 8216.271
6 ARMA(0,4) 2.964135 -4089.026 8190.053 8222.438
7 ARMA(0,5) 2.963759 -4088.821 8191.641 8229.424
8 ARMA(1,0) 2.975036 -4095.009 8196.018 8212.211
9 ARMA(1,1) 2.967814 -4091.047 8190.094 8211.684
10 ARMA(1,2) 2.964741 -4089.359 8188.717 8215.705
11 ARMA(1,3) 2.964739 -4089.357 8190.715 8223.100
12 ARMA(1,4) 2.964018 -4088.962 8191.925 8229.708
13 ARMA(1,5) 2.963703 -4088.790 8193.580 8236.761
14 ARMA(2,0) 2.964904 -4089.449 8186.897 8208.487
15 ARMA(2,1) 2.964700 -4089.336 8188.672 8215.660
16 ARMA(2,2) 2.964695 -4089.334 8190.668 8223.053
17 ARMA(2,3) 2.964643 -4089.305 8192.610 8230.393
18 ARMA(2,4) 2.952400 -4082.583 8181.166 8224.347
19 ARMA(2,5) 2.949320 -4080.889 8179.779 8228.357
20 ARMA(3,0) 2.964733 -4089.355 8188.709 8215.697
21 ARMA(3,1) 2.964746 -4089.362 8190.723 8223.109
22 ARMA(3,2) 2.964672 -4089.321 8192.642 8230.425
23 ARMA(3,3) 2.951471 -4082.076 8180.152 8223.333
24 ARMA(3,4) 2.950608 -4081.600 8181.201 8229.779
25 ARMA(3,5) 2.951049 -4081.844 8183.689 8237.664
26 ARMA(4,0) 2.964569 -4089.264 8190.529 8222.914
27 ARMA(4,1) 2.964560 -4089.259 8192.519 8230.302
28 ARMA(4,2) 2.951038 -4081.838 8179.676 8222.856
29 ARMA(4,3) 2.950548 -4081.567 8181.135 8229.713
30 ARMA(4,4) 2.951099 -4081.871 8183.743 8237.719
31 ARMA(4,5) 2.950441 -4081.508 8185.016 8244.389
32 ARMA(5,0) 2.964446 -4089.197 8192.393 8230.176
33 ARMA(5,1) 2.959271 -4086.356 8188.712 8231.893
34 ARMA(5,2) 2.949909 -4083.396 8184.793 8233.371
35 ARMA(5,3) 2.951037 -4081.838 8183.676 8237.651
36 ARMA(5,4) 2.950452 -4081.514 8185.029 8244.402
37 ARMA(5,5) 2.943817 -4078.218 8180.436 8245.207

Al obtener toda la lista de los modelos se procede a evaluar el mejor modelos de todos ellos y como se dijo antes se procede a eligir el que tiene el mejor critetio de akike (AIC). Esto se realiza con la función autoarimaprorpocionada del paquete forecast.

Mejor modelo
sigma logLik AIC BIC
2.967704 -4089.987 8185.975 8202.167

El mejor modelo para esta serie es un arma(0,0,2).

Entrenamiento del modelo

pre<- forecast(modelo,10)
data<- data.frame("fechas1"=index(test),"test"=as.numeric(test$BAP),
                  "prediccion"=as.numeric(pre$mean))
data[,2]<- as.numeric(data[,2])
data[,3]<- as.numeric(data[,3])

ggplot(data)+geom_line(mapping = aes(x=fechas1,y=test,col="test"))+
  geom_line(mapping = aes(x=fechas1,y=prediccion,color="prediccion"))+theme_elegante()+
  labs(title="Modelo ARIMA",x="",y="Precios" )

Interpretación: A diferencia del metodo de cadenas de markov podemos ver que esta ves la predicción esta por encima de los valores predichos.

Proyección

fecha<- seq(as.Date("2021-06-29"),length=10,by="1 day")
matriz3<- as.data.frame(pre$mean)
matriz<- as.data.frame(pre$lower)        
matriz1<- as.data.frame(pre$upper) 
serie<- precios$BAP
ata=ggplot()+ geom_line(mapping = aes(x=index(serie[1300:length(serie)]),y=as.numeric(serie[1300:length(serie)])),color="#0000FF")+
  geom_line(mapping = aes(x=fecha,y=matriz$`80%`,color="1"),lty=2,size=1)+
  geom_line(mapping = aes(x=fecha,y=matriz$`95%`,color="2"),lty=2,size=1)+
  geom_line(mapping = aes(x=fecha,y=matriz1$`80%`,color="1"),lty=2,size=1)+
  geom_line(mapping = aes(x=fecha,y=matriz1$`95%`,color="2"),lty=2,size=1)+
  geom_line(mapping = aes(x=fecha,y=matriz3$x,color="3"),size=1)+
  scale_color_manual(" ",values = c("#58FAF4","#FF00FF","#FF0040"),labels=c("80%","95%","poryeccion"))+
  theme_elegante()+xlab("Fechas")+ylab("Precios de las acciones")+labs(title = "Proyección de los precios de credicorp")


ata+geom_ribbon(aes(ymin=matriz$`80%`,ymax=matriz1$`80%`,x=fecha),alpha=.3,fill="blue")+
  geom_ribbon(aes(ymin=matriz$`95%`,ymax=matriz1$`95%`,x=fecha),alpha=.5,fill="blue")

Impactos de sentimientos en las acciones

En esta siguiente parte veremo como las noticias negativas tienen um impacto significativo sobre el pronostico de la acción de AMZN.

library(readr)
library(tidyverse)
library(forecast)
Sentimientos <- read_csv("C:/Users/atita/Downloads/Sentimientos.csv")
Sentimientos %>% select(count) %>% group_by(count) %>% 
  summarise(n=n()) %>% ggplot()+geom_col(aes(x=count,y=n,fill=n))+
  labs(title = "Cantidad de twets negativos por día ",
       x=" ",y="Cantidad",caption = "Elaborado por Sebastián Sosa Pérez")+
  theme_minimal()

Sentimientos %>% select(Date,Close) %>% ggplot(aes(x=Date,y=Close))+
  geom_line(color="blue",size=1)+geom_area(fill="gray",alpha=0.4)+
  labs(title = "Cotización de la AMZN",
       x=" ",y="Precios",caption = "Elaborado por Sebastián Sosa Pérez")+
  theme_minimal()

time<- Sentimientos %>% select(Close,count) %>% ts()
amzn_tr<- time[,1][1:110]
amzn_te<- time[,1][111:115]
negative_tr<- time[,2][1:110]
negative_te<- time[,2][111:115]
modelo1<- auto.arima(amzn_tr)
prediction<- forecast(modelo1,5)
plot(prediction)

plot(as.numeric(prediction$mean),type = "l",ylim = c (1730,1870))
lines(amzn_te,col="red")

modelo2<- auto.arima(amzn_tr,xreg = negative_tr)
prediction2<- forecast(modelo2,h=5,xreg = negative_tr[106:110])
plot(prediction2)

plot(as.numeric(prediction2$mean),type = "l",ylim = c (1730,1870))
lines(amzn_te,col="red")
lines(as.numeric(prediction$mean),col="blue")

modelo3<- nnetar(amzn_tr,xreg = negative_tr)
prediction3<- forecast(modelo3,h=5,xreg = negative_tr[106:110])
plot(prediction3)

plot(as.numeric(prediction2$mean),type = "l",ylim = c (1730,1870))
lines(amzn_te,col="red")
lines(as.numeric(prediction$mean),col="blue")
lines(as.numeric(prediction3$mean),col="pink")