JYJ

Published

Invalid Date

1 COCA COLA

2 librerias

# Cargar librerías necesarias
library(quantmod)
Cargando paquete requerido: xts
Cargando paquete requerido: zoo

Adjuntando el paquete: 'zoo'
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 2025
Johnson <- getSymbols('JNJ', src='yahoo', from = '2025-01-01', to = Sys.Date(), auto.assign = FALSE)

# Limpieza de datos

cat("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 estados
cat("=== 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 estados
umbrales <- quantile(retornos$Retorno, probs = c(0.2, 0.4, 0.6, 0.8), na.rm = TRUE)
cat("Umbrales para 5 estados:\n")
Umbrales para 5 estados:
print(umbrales)
          20%           40%           60%           80% 
-0.0060338665 -0.0003526837  0.0040041570  0.0099326629 
# Asignar estados
estados <- character(length(retornos$Retorno))
for(i in 1:length(retornos$Retorno)) {
  if(retornos$Retorno[i] < umbrales[1]) {
    estados[i] <- "Fuertemente Bajista"
  } else if(retornos$Retorno[i] < umbrales[2]) {
    estados[i] <- "Bajista"
  } else if(retornos$Retorno[i] < umbrales[3]) {
    estados[i] <- "Neutral"
  } else if(retornos$Retorno[i] < umbrales[4]) {
    estados[i] <- "Alcista"
  } else {
    estados[i] <- "Fuertemente Alcista"
  }
}

# Crear dataframe con estados
datos_estados <- data.frame(
  Fecha = index(retornos),
  Retorno = retornos$Retorno,
  Estado = estados
)

cat("\nDistribución de estados:\n")

Distribución de estados:
print(table(datos_estados$Estado))

            Alcista             Bajista Fuertemente Alcista Fuertemente Bajista 
                 45                  45                  45                  45 
            Neutral 
                 45 
print(sum(estados=="Fuertemente Alcista"))
[1] 45
# Convertir los retornos a dataframe para gráfico básico
retornos_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écnico
chartSeries(Johnson_clean, 
            name = "JNJ - Precios y Retornos 2025",
            theme = "white")

# Agregar panel de retornos
addROC(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ísticas
media_retornos <- mean(retornos$Retorno, na.rm = TRUE)
abline(h = media_retornos, col = "green", lwd = 2, lty = 2)  # Línea de media

legend("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 Markov
cat("=== CONSTRUCCIÓN DE LA CADENA DE MARKOV ===\n")
=== CONSTRUCCIÓN DE LA CADENA DE MARKOV ===
secuencia_estados <- datos_estados$Estado
matriz_transicion <- createSequenceMatrix(secuencia_estados, toRowProbs = TRUE, sanitize = TRUE)

cat("Matriz de Transición de Probabilidades:\n")
Matriz de Transición de Probabilidades:
print(round(matriz_transicion, 4))
                    Alcista Bajista Fuertemente Alcista Fuertemente Bajista
Alcista              0.2000  0.1333              0.2222              0.1778
Bajista              0.2889  0.1778              0.1556              0.2000
Fuertemente Alcista  0.1136  0.2727              0.1818              0.2500
Fuertemente Bajista  0.1556  0.2000              0.2667              0.2444
Neutral              0.2444  0.2222              0.1778              0.1333
                    Neutral
Alcista              0.2667
Bajista              0.1778
Fuertemente Alcista  0.1818
Fuertemente Bajista  0.1333
Neutral              0.2222
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 condicional
cat("=== 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("   Respuesta:", round(matriz_transicion["Fuertemente Alcista", "Fuertemente Bajista"], 4), 
    "(", round(matriz_transicion["Fuertemente Alcista", "Fuertemente Bajista"] * 100, 2), "%)\n\n")
   Respuesta: 0.25 ( 25 %)
cat("2. ¿Cuál es la probabilidad de que JNJ estando 'Neutral' permanezca 'Neutral'?\n")
2. ¿Cuál es la probabilidad de que JNJ estando 'Neutral' permanezca 'Neutral'?
cat("   Respuesta:", round(matriz_transicion["Neutral", "Neutral"], 4), 
    "(", round(matriz_transicion["Neutral", "Neutral"] * 100, 2), "%)\n\n")
   Respuesta: 0.2222 ( 22.22 %)
cat("3. ¿Cuál es la probabilidad de que JNJ estando 'Bajista' pase a 'Alcista'?\n")
3. ¿Cuál es la probabilidad de que JNJ estando 'Bajista' pase a 'Alcista'?
cat("   Respuesta:", round(matriz_transicion["Bajista", "Alcista"], 4), 
    "(", round(matriz_transicion["Bajista", "Alcista"] * 100, 2), "%)\n\n")
   Respuesta: 0.2889 ( 28.89 %)
cat("4. ¿Cuál es la probabilidad de que JNJ estando 'Fuertemente Bajista' pase a 'Neutral'?\n")
4. ¿Cuál es la probabilidad de que JNJ estando 'Fuertemente Bajista' pase a 'Neutral'?
cat("   Respuesta:", round(matriz_transicion["Fuertemente Bajista", "Neutral"], 4), 
    "(", round(matriz_transicion["Fuertemente Bajista", "Neutral"] * 100, 2), "%)\n\n")
   Respuesta: 0.1333 ( 13.33 %)
cat("5. ¿Cuál es la probabilidad de que JNJ estando 'Alcista' pase a 'Fuertemente Alcista'?\n")
5. ¿Cuál es la probabilidad de que JNJ estando 'Alcista' pase a 'Fuertemente Alcista'?
cat("   Respuesta:", round(matriz_transicion["Alcista", "Fuertemente Alcista"], 4), 
    "(", round(matriz_transicion["Alcista", "Fuertemente Alcista"] * 100, 2), "%)\n\n")
   Respuesta: 0.2222 ( 22.22 %)

2.5 MATRICES DE TRANSICIÓN MÚLTIPLES

library(expm)
Warning: package 'expm' was built under R version 4.5.2

Adjuntando el paquete: 'expm'
The following object is masked from 'package:Matrix':

    expm
# Matrices de transición para múltiples periodos
cat("=== MATRICES DE TRANSICIÓN PARA MÚLTIPLES PERIODOS ===\n")
=== MATRICES DE TRANSICIÓN PARA MÚLTIPLES PERIODOS ===
# Matriz para 2 periodos
p_2 <- matriz_transicion %^% 2
cat("Matriz de transición para 2 periodos:\n")
Matriz de transición para 2 periodos:
print(round(p_2, 4))
                    Alcista Bajista Fuertemente Alcista Fuertemente Bajista
Alcista              0.1966  0.2058              0.2004              0.1968
Bajista              0.2014  0.1921              0.2051              0.1984
Fuertemente Alcista  0.2055  0.2036              0.1997              0.2056
Fuertemente Bajista  0.1898  0.2075              0.2031              0.2119
Neutral              0.2084  0.1966              0.1963              0.1946
                    Neutral
Alcista              0.2004
Bajista              0.2031
Fuertemente Alcista  0.1856
Fuertemente Bajista  0.1877
Neutral              0.2042
# Matriz para 3 periodos  
p_3 <- matriz_transicion %^% 3
cat("\nMatriz de transición para 3 periodos:\n")

Matriz de transición para 3 periodos:
print(round(p_3, 4))
                    Alcista Bajista Fuertemente Alcista Fuertemente Bajista
Alcista              0.2011  0.2013              0.2002              0.2010
Bajista              0.1996  0.2017              0.2009              0.2011
Fuertemente Alcista  0.2000  0.2004              0.2015              0.2022
Fuertemente Bajista  0.1998  0.2017              0.2013              0.2028
Neutral              0.2010  0.2006              0.2008              0.2002
                    Neutral
Alcista              0.1962
Bajista              0.1967
Fuertemente Alcista  0.1960
Fuertemente Bajista  0.1944
Neutral              0.1975
# Matriz para 5 periodos
p_5 <- matriz_transicion %^% 5
cat("\nMatriz de transición para 5 periodos:\n")

Matriz de transición para 5 periodos:
print(round(p_5, 4))
                    Alcista Bajista Fuertemente Alcista Fuertemente Bajista
Alcista              0.2003  0.2011              0.2009              0.2015
Bajista              0.2003  0.2011              0.2009              0.2015
Fuertemente Alcista  0.2003  0.2012              0.2009              0.2015
Fuertemente Bajista  0.2003  0.2012              0.2009              0.2015
Neutral              0.2003  0.2011              0.2009              0.2014
                    Neutral
Alcista              0.1962
Bajista              0.1962
Fuertemente Alcista  0.1961
Fuertemente Bajista  0.1961
Neutral              0.1962

2.6 DISTRIBUCIÓN ESTACIONARIA

# Distribución estacionaria
cat("=== DISTRIBUCIÓN ESTACIONARIA ===\n")
=== DISTRIBUCIÓN ESTACIONARIA ===
dist_estacionaria <- steadyStates(cadena_markov)
cat("Distribución estacionaria (largo plazo):\n")
Distribución estacionaria (largo plazo):
print(round(dist_estacionaria, 4))
     Alcista Bajista Fuertemente Alcista Fuertemente Bajista Neutral
[1,]  0.2003  0.2011              0.2009              0.2015  0.1962
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 %)

2.7 PREDICCIONES

# Predicciones futuras
cat("=== PREDICCIONES FUTURAS ===\n")
=== PREDICCIONES FUTURAS ===
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 in 1: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 Markov
cat("=== 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 tiempo
ggplot(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ón
matriz_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 umbrales
cat("=== ANÁLISIS DE SENSIBILIDAD ===\n")
=== ANÁLISIS DE SENSIBILIDAD ===
# Probar con diferentes percentiles
umbrales_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")
Umbrales alternativos (15%, 35%, 65%, 85%):
print(umbrales_alt)
         15%          35%          65%          85% 
-0.007645406 -0.001769965  0.005006559  0.011374055 
# Comparar con los umbrales originales
cat("\nComparación con umbrales originales (20%, 40%, 60%, 80%):\n")

Comparación con umbrales originales (20%, 40%, 60%, 80%):
print(umbrales)
          20%           40%           60%           80% 
-0.0060338665 -0.0003526837  0.0040041570  0.0099326629 

2.12 RESUMEN

cat("ANÁLISIS COMPLETO DE CADENAS DE MARKOV - JNJ\n\n")
ANÁLISIS COMPLETO DE CADENAS DE MARKOV - JNJ
cat("RESULTADOS PRINCIPALES:\n")
RESULTADOS PRINCIPALES:
cat("• Período analizado:", as.character(index(Johnson_clean)[1]), "a", as.character(index(Johnson_clean)[nrow(Johnson_clean)]), "\n")
• Período analizado: 2025-01-02 a 2025-11-24 
cat("• Total de observaciones:", nrow(Johnson_clean), "\n")
• Total de observaciones: 225 
cat("• Estados definidos: 5 (basados en percentiles de retornos)\n")
• Estados definidos: 5 (basados en percentiles de retornos)
cat("• Estado actual:", estado_actual, "\n")
• Estado actual: Fuertemente Alcista 
cat("• Estado más probable largo plazo:", estado_max, "(", round(max(dist_estacionaria) * 100, 2), "%)\n")
• Estado más probable largo plazo: Fuertemente Bajista ( 20.15 %)
cat("• Probabilidad de mantener estado actual:", round(matriz_transicion[estado_actual, estado_actual], 4), "\n\n")
• Probabilidad de mantener estado actual: 0.1818 
cat("RECOMENDACIONES:\n")
RECOMENDACIONES:
prob_alcista <- sum(dist_estacionaria[1, c("Alcista", "Fuertemente Alcista")])
prob_bajista <- sum(dist_estacionaria[1, c("Bajista", "Fuertemente Bajista")])

if(prob_alcista > 0.5) {
  cat("• Perspectiva: ALCISTA (", round(prob_alcista * 100, 1), "% de probabilidad)\n")
  cat("• Recomendación: Considerar posiciones largas\n")
} else if(prob_bajista > 0.5) {
  cat("• Perspectiva: BAJISTA (", round(prob_bajista * 100, 1), "% de probabilidad)\n") 
  cat("• Recomendación: Considerar posiciones cortas o esperar\n")
} else {
  cat("• Perspectiva: NEUTRAL (mercado balanceado)\n")
  cat("• Recomendación: Mantener posición actual\n")
}
• Perspectiva: NEUTRAL (mercado balanceado)
• Recomendación: Mantener posición actual

.