The following objects are masked from 'package:base':
as.Date, as.Date.numeric
Cargando paquete requerido: TTR
Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
library(ggplot2)
Warning: package 'ggplot2' was built under R version 4.5.2
library(dplyr)
######################### Warning from 'xts' package ##########################
# #
# The dplyr lag() function breaks how base R's lag() function is supposed to #
# work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
# source() into this session won't work correctly. #
# #
# Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
# conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
# dplyr from breaking base R's lag() function. #
# #
# Code in packages is not affected. It's protected by R's namespace mechanism #
# Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
# #
###############################################################################
Adjuntando el paquete: 'dplyr'
The following objects are masked from 'package:xts':
first, last
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
library(markovchain)
Warning: package 'markovchain' was built under R version 4.5.2
Cargando paquete requerido: Matrix
Package: markovchain
Version: 0.10.0
Date: 2024-11-14 00:00:02 UTC
BugReport: https://github.com/spedygiorgio/markovchain/issues
Adjuntando el paquete: 'markovchain'
The following object is masked from 'package:zoo':
is.regular
library(reshape2)cat("ANÁLISIS DE CADENAS DE MARKOV - JOHNSON & JOHNSON\n")
ANÁLISIS DE CADENAS DE MARKOV - JOHNSON & JOHNSON
2.1 CARGA Y LIMPIEZA DE DATOS
# Cargar datos de Johnson & Johnson desde enero 2025Johnson <-getSymbols('JNJ', src='yahoo', from ='2025-01-01', to =Sys.Date(), auto.assign =FALSE)# Limpieza de datoscat("Datos originales:", nrow(Johnson), "registros\n")
Datos originales: 225 registros
cat("Valores NA:", sum(is.na(Cl(Johnson))), "\n")
Valores NA: 0
Johnson_clean <-na.omit(Johnson)cat("Datos después de limpieza:", nrow(Johnson_clean), "registros\n")
Datos después de limpieza: 225 registros
2.2 DEFINICIÓN DE ESTADOS
# Calcular retornos y definir 5 estadoscat("=== DEFINICIÓN DE 5 ESTADOS ===\n")
=== DEFINICIÓN DE 5 ESTADOS ===
retornos <-dailyReturn(Cl(Johnson_clean))# dailyReturn(): Función que AUTOMÁTICAMENTE calcula:# Retorno_t = (Precio_t - Precio_{t-1}) / Precio_{t-1}# EJEMPLO PRÁCTICO:# Si ayer JNJ cerró a $150 y hoy cerró a $153:# Retorno = (153 - 150) / 150 = 3/150 = 0.02 = 2%colnames(retornos) <-"Retorno"# Calcular percentiles para 5 estadosumbrales <-quantile(retornos$Retorno, probs =c(0.2, 0.4, 0.6, 0.8), na.rm =TRUE)cat("Umbrales para 5 estados:\n")
# Convertir los retornos a dataframe para gráfico básicoretornos_df <-data.frame(Fecha =index(retornos),Retorno =as.numeric(retornos$Retorno))plot(retornos_df$Retorno, type ="l", col ="blue", main ="Retornos Diarios de JNJ", ylab ="Retorno (%)", xlab ="Días")abline(h =0, col ="red", lwd =2) # Línea roja en cero
#######################################################################################################################library(ggplot2)ggplot(retornos_df, aes(x = Fecha, y = Retorno)) +geom_line(color ="blue", alpha =0.7) +geom_hline(yintercept =0, color ="red", linewidth =1, linetype ="dashed") +labs(title ="Retornos Diarios de JNJ - 2025",subtitle ="Línea roja indica retorno cero (sin ganancias/pérdidas)",x ="Fecha", y ="Retorno (%)") +theme_minimal()
######################################################################################################################## Gráfico profesional de análisis técnicochartSeries(Johnson_clean, name ="JNJ - Precios y Retornos 2025",theme ="white")
# Agregar panel de retornosaddROC(n =1, type ="discrete", col ="blue")
#######################################################################################################################plot(as.numeric(retornos$Retorno), type ="l", col ="blue",main ="Retornos Diarios de JNJ - 2025",ylab ="Retorno (%)", xlab ="Días de Trading")abline(h =0, col ="red", lwd =2) # Línea horizontal en cero# Agregar estadísticasmedia_retornos <-mean(retornos$Retorno, na.rm =TRUE)abline(h = media_retornos, col ="green", lwd =2, lty =2) # Línea de medialegend("topright", legend =c("Retornos JNJ", "Cero", paste("Media:", round(media_retornos*100, 2), "%")),col =c("blue", "red", "green"), lty =c(1, 1, 2), lwd =2)
2.3 CONSTRUCCIÓN DE LA CADENA DE MARKOV
# Crear la cadena de Markovcat("=== CONSTRUCCIÓN DE LA CADENA DE MARKOV ===\n")
=== CONSTRUCCIÓN DE LA CADENA DE MARKOV ===
secuencia_estados <- datos_estados$Estadomatriz_transicion <-createSequenceMatrix(secuencia_estados, toRowProbs =TRUE, sanitize =TRUE)cat("Matriz de Transición de Probabilidades:\n")
cadena_markov <-new("markovchain", states =rownames(matriz_transicion),transitionMatrix = matriz_transicion,name ="JNJ_5Estados")cat("\nResumen de la Cadena de Markov:\n")
Resumen de la Cadena de Markov:
print(summary(cadena_markov))
JNJ_5Estados Markov chain that is composed by:
Closed classes:
Alcista Bajista Fuertemente Alcista Fuertemente Bajista Neutral
Recurrent classes:
{Alcista,Bajista,Fuertemente Alcista,Fuertemente Bajista,Neutral}
Transient classes:
NONE
The Markov chain is irreducible
The absorbing states are: NONE
$closedClasses
$closedClasses[[1]]
[1] "Alcista" "Bajista" "Fuertemente Alcista"
[4] "Fuertemente Bajista" "Neutral"
$recurrentClasses
$recurrentClasses[[1]]
[1] "Alcista" "Bajista" "Fuertemente Alcista"
[4] "Fuertemente Bajista" "Neutral"
$transientClasses
list()
2.4 PREGUNTAS DE PROBABILIDAD
# Preguntas de probabilidad condicionalcat("=== PREGUNTAS DE PROBABILIDAD CONDICIONAL ===\n")
=== PREGUNTAS DE PROBABILIDAD CONDICIONAL ===
cat("1. ¿Cuál es la probabilidad de que JNJ estando 'Fuertemente Alcista' pase a 'Fuertemente Bajista'?\n")
1. ¿Cuál es la probabilidad de que JNJ estando 'Fuertemente Alcista' pase a 'Fuertemente Bajista'?
cat("\nInterpretación de la distribución estacionaria:\n")
Interpretación de la distribución estacionaria:
cat("• JNJ en estado 'Fuertemente Bajista' a largo plazo:", round(dist_estacionaria[1, "Fuertemente Bajista"] *100, 2), "%\n")
• JNJ en estado 'Fuertemente Bajista' a largo plazo: 20.15 %
cat("• JNJ en estado 'Bajista' a largo plazo:", round(dist_estacionaria[1, "Bajista"] *100, 2), "%\n")
• JNJ en estado 'Bajista' a largo plazo: 20.11 %
cat("• JNJ en estado 'Neutral' a largo plazo:", round(dist_estacionaria[1, "Neutral"] *100, 2), "%\n")
• JNJ en estado 'Neutral' a largo plazo: 19.62 %
cat("• JNJ en estado 'Alcista' a largo plazo:", round(dist_estacionaria[1, "Alcista"] *100, 2), "%\n")
• JNJ en estado 'Alcista' a largo plazo: 20.03 %
cat("• JNJ en estado 'Fuertemente Alcista' a largo plazo:", round(dist_estacionaria[1, "Fuertemente Alcista"] *100, 2), "%\n")
• JNJ en estado 'Fuertemente Alcista' a largo plazo: 20.09 %
estado_max <-colnames(dist_estacionaria)[which.max(dist_estacionaria)]cat("\n• Estado más probable a largo plazo:", estado_max, "(", round(max(dist_estacionaria) *100, 2), "%)\n")
• Estado más probable a largo plazo: Fuertemente Bajista ( 20.15 %)
estado_actual <-tail(secuencia_estados, 1)cat("Estado actual de JNJ:", estado_actual, "\n")
Estado actual de JNJ: Fuertemente Alcista
# Predicciones para 3 periodos (como en el RPUBS)predicciones <-predict(cadena_markov, newdata = estado_actual, n.ahead =3)cat("Predicciones para los próximos 3 periodos:\n")
Predicciones para los próximos 3 periodos:
for(i in1:length(predicciones)) {cat("Periodo", i, ":", predicciones[i], "\n")}
Periodo 1 : Bajista
Periodo 2 : Alcista
Periodo 3 : Neutral
2.8 GRÁFICO DE LA CADENA
# Gráfico de la cadena de Markovcat("=== GRÁFICO DE LA CADENA DE MARKOV ===\n")
=== GRÁFICO DE LA CADENA DE MARKOV ===
plot(cadena_markov, main ="Cadena de Markov - Estados de JNJ")
2.9 VISUALIZACIÓN DE ESTADOS EN EL TIEMPO
# Gráfico de estados a lo largo del tiempoggplot(datos_estados, aes(x = Fecha, y = Retorno, color = Estado)) +geom_point(alpha =0.7, size =2) +geom_hline(yintercept = umbrales, linetype ="dashed", alpha =0.5) +labs(title ="Estados de Mercado JNJ - Cadena de Markov",subtitle ="Evolución de los 5 estados en el tiempo",x ="Fecha", y ="Retorno Diario") +theme_minimal() +scale_color_manual(values =c("red", "orange", "gray", "lightblue", "darkblue"))
2.10 HEATMAP DE LA MATRIZ DE TRANSICIÓN
# Heatmap de la matriz de transiciónmatriz_melt <-melt(matriz_transicion)colnames(matriz_melt) <-c("Desde", "Hacia", "Probabilidad")ggplot(matriz_melt, aes(x = Desde, y = Hacia, fill = Probabilidad)) +geom_tile(color ="white") +geom_text(aes(label =round(Probabilidad, 3)), color ="black", size =4) +scale_fill_gradient2(low ="white", high ="blue", midpoint =0.2) +labs(title ="Matriz de Transición - Estados JNJ",subtitle ="Probabilidades de transición entre estados",x ="Estado Actual", y ="Próximo Estado") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1))
2.11 ANÁLISIS DE SENSIBILIDAD
# Análisis de sensibilidad - diferentes umbralescat("=== ANÁLISIS DE SENSIBILIDAD ===\n")
=== ANÁLISIS DE SENSIBILIDAD ===
# Probar con diferentes percentilesumbrales_alt <-quantile(retornos$Retorno, probs =c(0.15, 0.35, 0.65, 0.85), na.rm =TRUE)cat("Umbrales alternativos (15%, 35%, 65%, 85%):\n")