Riesgo-Retornos y Rendimientos”

Rendimiento: Sean

\[S_1, S_2, \cdots, S_n\] n precios de un activo financiero equi-distados, se define el rendimiento de \(S\)

\[ R_t:=\frac{S_{t}-S_{t-1}}{S_{t-1}} \] # Cuál es la unidad de \(R\)?

No tiene unidades pues ees una tasa, puede ser positivo o negativo.

Movimiento Browniano Geométrico.

\[ S_t= S_0e^{(\mu-\frac{1}{2}\sigma^2)t + \sigma B_t} \]

Proceso estacionario de segundo orden

Procso que presenta media constante y varianza constante

z<-rnorm(1000)
plot(z,type = "l")

# Instala las librerías si no las tienes:
# install.packages(c("quantmod", "nortest", "ggplot2"))

library(quantmod)
## Warning: package 'quantmod' was built under R version 4.4.3
## 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
## Warning: package 'TTR' was built under R version 4.4.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(nortest)
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
## 
## ######################### 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(tidyr)
## Warning: package 'tidyr' was built under R version 4.4.3
# 1. Descargar datos mensuales del S&P 500 desde el año 2000 hasta hoy
getSymbols("^GSPC", src = "yahoo", from = "2000-01-01", periodicity = "monthly")
## [1] "GSPC"
# 2. Calcular los rendimientos logarítmicos basados en el precio de cierre ajustado
precios <- Ad(GSPC)
rendimientos <- diff(log(precios)) %>% na.omit()

# Convertir a un dataframe limpio para R
df_rendimientos <- data.frame(
  Fecha = index(rendimientos),
  Rendimiento = as.numeric(rendimientos)
)

# ===================================================
# PRUEBA DE NORMALIDAD (Lilliefors)
# ===================================================
cat("\n--- TEST DE LILLIEFORS PARA RENDIMIENTOS MENSUALES DEL S&P 500 ---\n")
## 
## --- TEST DE LILLIEFORS PARA RENDIMIENTOS MENSUALES DEL S&P 500 ---
prueba_norm <- lillie.test(df_rendimientos$Rendimiento)
print(prueba_norm)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  df_rendimientos$Rendimiento
## D = 0.088971, p-value = 2.324e-06
# ===================================================
# GRAFICAR EL HISTOGRAMA VS CURVA NORMAL
# ===================================================
ggplot(df_rendimientos, aes(x = Rendimiento)) +
  geom_histogram(aes(y = ..density..), bins = 30, 
                 fill = "#2c3e50", color = "white", alpha = 0.8) +
  # Curva de densidad real de los rendimientos (azul)
  geom_density(color = "#2980b9", linewidth = 1.2) +
  # Curva normal teórica de comparación (roja)
  stat_function(fun = dnorm, 
                args = list(mean = mean(df_rendimientos$Rendimiento), 
                            sd = sd(df_rendimientos$Rendimiento)), 
                color = "#e74c3c", linewidth = 1, linetype = "dashed") +
  labs(
    title = "Rendimientos Mensuales del S&P 500 (^GSPC)",
    subtitle = "Demostración de convergencia a la Distribución Normal",
    x = "Rendimientos Logarítmicos",
    y = "Densidad",
    caption = paste("P-valor de Lilliefors:", round(prueba_norm$p.value, 4))
  ) +
  theme_minimal()
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

plot(df_rendimientos$Rendimiento, type="l")

qqnorm(df_rendimientos$Rendimiento)

Por lo tanto el activo financiero se comporta como un browniano geométrico.

mean(df_rendimientos$Rendimiento)
## [1] 0.005290796
sd(df_rendimientos$Rendimiento)
## [1] 0.04409503

Movimiento browniano geométrico

# 1. Extraer los parámetros reales del S&P 500 (Media y Desviación Estándar)
mu    <- mean(df_rendimientos$Rendimiento)
sigma <- sd(df_rendimientos$Rendimiento)

# 2. Tomar el último precio real registrado como punto de partida
precio_inicial <- as.numeric(tail(precios, 1))

# --- CONFIGURACIÓN DE LA PROYECCIÓN ---
n_trayectorias <- 100   # Número de caminos a simular
meses_futuros  <- 24    # Horizonte de tiempo (2 años)
# --------------------------------------

set.seed(777) # Para replicabilidad

# 3. Crear matriz para almacenar los precios simulados
# Tendrá (meses_futuros + 1) filas para incluir el punto de partida (Mes 0)
matriz_precios <- matrix(NA, nrow = meses_futuros + 1, ncol = n_trayectorias)
matriz_precios[1, ] <- precio_inicial # Fijar el último precio real en el inicio

# 4. Simulación del Movimiento Browniano Geométrico
for (j in 1:n_trayectorias) {
  # Generar rendimientos normales usando la media y desviación estándar reales
  rendimientos_simulados <- rnorm(meses_futuros, mean = mu, sd = sigma)
  
  # El precio evoluciona multiplicándose por e^(rendimiento) acumulado
  # Fórmula: P_t = P_0 * exp(cumsum(r))
  matriz_precios[-1, j] <- precio_inicial * exp(cumsum(rendimientos_simulados))
}

# 5. Dar formato a los datos para graficarlos con ggplot2
df_simulacion <- as.data.frame(matriz_precios)
colnames(df_simulacion) <- paste0("Trayectoria_", 1:n_trayectorias)
df_simulacion$Mes <- 0:meses_futuros

df_largo_sim <- df_simulacion %>%
  pivot_longer(cols = starts_with("Trayectoria_"), 
               names_to = "Trayectoria", 
               values_to = "Precio")

# 6. Graficar las 100 trayectorias con colores diferentes
ggplot(df_largo_sim, aes(x = Mes, y = Precio, group = Trayectoria, color = Trayectoria)) +
  # Dibujar los caminos futuristas
  geom_line(linewidth = 0.5, alpha = 0.6) +
  # Destacar el punto de partida real
  annotate("point", x = 0, y = precio_inicial, color = "white", size = 4) +
  annotate("text", x = 1.5, y = precio_inicial, label = "Último precio\nreal", 
           color = "white", size = 3, hjust = 0) +
  # Estética financiera de fondo oscuro
  labs(
    title = "Proyección de 100 Trayectorias Futuras para el S&P 500",
    subtitle = paste("Basado en Movimiento Browniano con parámetros históricos reales\n(Media =", 
                     round(mu, 4), "| Desv. Est = ", round(sigma, 4), ")"),
    x = "Meses en el Futuro",
    y = "Precio Proyectado (USD)"
  ) +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "#121212", color = NA),
    plot.background = element_rect(fill = "#121212", color = NA),
    panel.grid.major = element_line(color = "#2c2c2c", linewidth = 0.5),
    panel.grid.minor = element_blank(),
    text = element_text(color = "white"),
    plot.title = element_text(face = "bold", size = 14, color = "#00ffcc"),
    axis.text = element_text(color = "white"),
    legend.position = "none" # Ocultamos la leyenda porque 100 nombres saturarían el gráfico
  )

# 1. Preparar los datos históricos reales para el gráfico
# Filtramos los últimos 24 meses históricos para que el gráfico guarde simetría (2 años atrás, 2 años adelante)
df_pasado <- data.frame(
  Mes = -24:0,
  Precio = as.numeric(tail(precios, 25)),
  Trayectoria = "Histórico Real"
)

# 2. Ajustar el dataframe de las simulaciones para que coincida en estructura
df_futuro_grafico <- df_largo_sim %>%
  select(Mes, Precio, Trayectoria)

# 3. Graficar Pasado (Línea gruesa blanca) + Futuro (100 trayectorias de colores)
ggplot() +
  # CAPA 1: Las 100 trayectorias simuladas (Futuro)
  geom_line(data = df_futuro_grafico, aes(x = Mes, y = Precio, group = Trayectoria, color = Trayectoria), 
            linewidth = 0.5, alpha = 0.5) +
  
  # CAPA 2: El comportamiento histórico real (Pasado)
  geom_line(data = df_pasado, aes(x = Mes, y = Precio), 
            color = "#ffffff", linewidth = 1.5) +
  
  # CAPA 3: Punto de unión (Último precio real / Mes 0)
  annotate("point", x = 0, y = precio_inicial, color = "#00ffcc", size = 4) +
  annotate("text", x = 0, y = precio_inicial * 1.05, label = "Presente", 
           color = "#00ffcc", fontface = "bold", size = 4, hjust = 0.5) +
  
  # Línea vertical divisoria en el Mes 0
  geom_vline(xintercept = 0, linetype = "dashed", color = "gray50", linewidth = 0.5) +
  
  # Estética y Etiquetas
  labs(
    title = "S&P 500: Histórico Real vs. 100 Proyecciones Futuras",
    subtitle = "Izquierda (Línea Blanca): Pasado Real | Derecha (Colores): Movimiento Browniano Geométrico",
    x = "Línea Temporal (Meses relativos al presente)",
    y = "Precio del Índice (USD)"
  ) +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "#121212", color = NA),
    plot.background = element_rect(fill = "#121212", color = NA),
    panel.grid.major = element_line(color = "#2c2c2c", linewidth = 0.5),
    panel.grid.minor = element_blank(),
    text = element_text(color = "white"),
    plot.title = element_text(face = "bold", size = 14, color = "#00ffcc", hjust = 0.5),
    plot.subtitle = element_text(size = 10, color = "gray70", hjust = 0.5),
    axis.text = element_text(color = "white"),
    legend.position = "none" # Ocultar leyenda de trayectorias
  )

Son estacionarios en media

ARCH o GARCH

# 1. Extraer los parámetros reales del S&P 500 (Media y Desviación Estándar)
mu    <- mean(df_rendimientos$Rendimiento)
sigma <- sd(df_rendimientos$Rendimiento)

# 2. Tomar el último precio real registrado como punto de partida
precio_inicial <- as.numeric(tail(precios, 1))

# --- CONFIGURACIÓN DE LA PROYECCIÓN ---
n_trayectorias <- 100   # Número de caminos a simular
meses_futuros  <- 6    # Horizonte de tiempo (2 años)
# --------------------------------------

set.seed(777) # Para replicabilidad

# 3. Crear matriz para almacenar los precios simulados
# Tendrá (meses_futuros + 1) filas para incluir el punto de partida (Mes 0)
matriz_precios <- matrix(NA, nrow = meses_futuros + 1, ncol = n_trayectorias)
matriz_precios[1, ] <- precio_inicial # Fijar el último precio real en el inicio

# 4. Simulación del Movimiento Browniano Geométrico
for (j in 1:n_trayectorias) {
  # Generar rendimientos normales usando la media y desviación estándar reales
  rendimientos_simulados <- rnorm(meses_futuros, mean = mu, sd = sigma)
  
  # El precio evoluciona multiplicándose por e^(rendimiento) acumulado
  # Fórmula: P_t = P_0 * exp(cumsum(r))
  matriz_precios[-1, j] <- precio_inicial * exp(cumsum(rendimientos_simulados))
}

# 5. Dar formato a los datos para graficarlos con ggplot2
df_simulacion <- as.data.frame(matriz_precios)
colnames(df_simulacion) <- paste0("Trayectoria_", 1:n_trayectorias)
df_simulacion$Mes <- 0:meses_futuros

df_largo_sim <- df_simulacion %>%
  pivot_longer(cols = starts_with("Trayectoria_"), 
               names_to = "Trayectoria", 
               values_to = "Precio")

# 6. Graficar las 100 trayectorias con colores diferentes
ggplot(df_largo_sim, aes(x = Mes, y = Precio, group = Trayectoria, color = Trayectoria)) +
  # Dibujar los caminos futuristas
  geom_line(linewidth = 0.5, alpha = 0.6) +
  # Destacar el punto de partida real
  annotate("point", x = 0, y = precio_inicial, color = "white", size = 4) +
  annotate("text", x = 1.5, y = precio_inicial, label = "Último precio\nreal", 
           color = "white", size = 3, hjust = 0) +
  # Estética financiera de fondo oscuro
  labs(
    title = "Proyección de 100 Trayectorias Futuras para el S&P 500",
    subtitle = paste("Basado en Movimiento Browniano con parámetros históricos reales\n(Media =", 
                     round(mu, 4), "| Desv. Est = ", round(sigma, 4), ")"),
    x = "Meses en el Futuro",
    y = "Precio Proyectado (USD)"
  ) +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "#121212", color = NA),
    plot.background = element_rect(fill = "#121212", color = NA),
    panel.grid.major = element_line(color = "#2c2c2c", linewidth = 0.5),
    panel.grid.minor = element_blank(),
    text = element_text(color = "white"),
    plot.title = element_text(face = "bold", size = 14, color = "#00ffcc"),
    axis.text = element_text(color = "white"),
    legend.position = "none" # Ocultamos la leyenda porque 100 nombres saturarían el gráfico
  )

# 1. Preparar los datos históricos reales para el gráfico
# Filtramos los últimos 24 meses históricos para que el gráfico guarde simetría (2 años atrás, 2 años adelante)
df_pasado <- data.frame(
  Mes = -24:0,
  Precio = as.numeric(tail(precios, 25)),
  Trayectoria = "Histórico Real"
)

# 2. Ajustar el dataframe de las simulaciones para que coincida en estructura
df_futuro_grafico <- df_largo_sim %>%
  select(Mes, Precio, Trayectoria)

# 3. Graficar Pasado (Línea gruesa blanca) + Futuro (100 trayectorias de colores)
ggplot() +
  # CAPA 1: Las 100 trayectorias simuladas (Futuro)
  geom_line(data = df_futuro_grafico, aes(x = Mes, y = Precio, group = Trayectoria, color = Trayectoria), 
            linewidth = 0.5, alpha = 0.5) +
  
  # CAPA 2: El comportamiento histórico real (Pasado)
  geom_line(data = df_pasado, aes(x = Mes, y = Precio), 
            color = "#ffffff", linewidth = 1.5) +
  
  # CAPA 3: Punto de unión (Último precio real / Mes 0)
  annotate("point", x = 0, y = precio_inicial, color = "#00ffcc", size = 4) +
  annotate("text", x = 0, y = precio_inicial * 1.05, label = "Presente", 
           color = "#00ffcc", fontface = "bold", size = 4, hjust = 0.5) +
  
  # Línea vertical divisoria en el Mes 0
  geom_vline(xintercept = 0, linetype = "dashed", color = "gray50", linewidth = 0.5) +
  
  # Estética y Etiquetas
  labs(
    title = "S&P 500: Histórico Real vs. 100 Proyecciones Futuras",
    subtitle = "Izquierda (Línea Blanca): Pasado Real | Derecha (Colores): Movimiento Browniano Geométrico",
    x = "Línea Temporal (Meses relativos al presente)",
    y = "Precio del Índice (USD)"
  ) +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "#121212", color = NA),
    plot.background = element_rect(fill = "#121212", color = NA),
    panel.grid.major = element_line(color = "#2c2c2c", linewidth = 0.5),
    panel.grid.minor = element_blank(),
    text = element_text(color = "white"),
    plot.title = element_text(face = "bold", size = 14, color = "#00ffcc", hjust = 0.5),
    plot.subtitle = element_text(size = 10, color = "gray70", hjust = 0.5),
    axis.text = element_text(color = "white"),
    legend.position = "none" # Ocultar leyenda de trayectorias
  )

# Caminata aleatoria.
z<-rnorm(1000,0,1)
plot(z,type="l")

# Supuestos del ruido blanco
mean(z)
## [1] 0.01201237
library(lmtest)
## Warning: package 'lmtest' was built under R version 4.4.3
# Homocedasticidad en el ruido
# H0: Ruido tiene varianza constante
plot(density(z))

y<-cumsum(z)
plot(y,type = "l")

# Instala las librerías si no las tienes:
# install.packages(c("ggplot2", "dplyr", "tidyr"))

library(ggplot2)
library(dplyr)
library(tidyr)

# --- CONFIGURACIÓN DE LA SIMULACIÓN ---
num_caminatas <- 12
num_pasos     <- 1000
# --------------------------------------

# 1. Generar los datos de las caminatas
set.seed(42) # Semilla opcional para replicabilidad

datos_caminatas <- data.frame(paso = 0:num_pasos)

for(i in 1:num_caminatas) {
  # Generar pasos aleatorios (-1, 0, 1) para X e Y
  pasos_x <- sample(c(-1, 0, 1), num_pasos, replace = TRUE)
  pasos_y = sample(c(-1, 0, 1), num_pasos, replace = TRUE)
  
  # Calcular la trayectoria acumulada empezando en 0
  x <- c(0, cumsum(pasos_x))
  y <- c(0, cumsum(pasos_y))
  
  # Guardar en el dataframe
  datos_caminatas[[paste0("X_", i)]] <- x
  datos_caminatas[[paste0("Y_", i)]] <- y
}

# 2. Reestructurar los datos para que ggplot los entienda fácilmente
df_long <- datos_caminatas %>%
  pivot_longer(cols = -paso, names_to = "variable", values_to = "valor") %>%
  separate(variable, into = c("eje", "id"), sep = "_") %>%
  pivot_wider(names_from = eje, values_from = valor)

# Extraer el punto final de cada caminata para colocar el punto brillante
puntos_finales <- df_long %>% 
  filter(paso == num_pasos)

# 3. Graficar con ggplot2
ggplot(df_long, aes(x = X, y = Y, group = id, color = id)) +
  # Dibujar las líneas de las caminatas
  geom_path(linewidth = 0.6, alpha = 0.8) +
  # Dibujar los puntos de destino final
  geom_point(data = puntos_finales, aes(x = X, y = Y, color = id), size = 2) +
  # Dibujar los puntos de destino con un borde blanco simulado (destello)
  geom_point(data = puntos_finales, aes(x = X, y = Y), color = "white", size = 0.7) +
  # Dibujar la estrella blanca en el origen (0,0)
  annotate("point", x = 0, y = 0, color = "white", size = 5, shape = 11) +
  # Estética y colores de fondo oscuro
  scale_color_discrete(name = "Caminatas") +
  labs(title = paste("Simulación de", num_caminatas, "Caminatas Aleatorias en 2D"),
       subtitle = paste("Trayectoria de", num_pasos, "pasos por camino"),
       x = "Eje X", y = "Eje Y") +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "#111111", color = NA),
    plot.background = element_rect(fill = "#111111", color = NA),
    panel.grid.major = element_line(color = "#333333", linewidth = 0.3),
    panel.grid.minor = element_blank(),
    text = element_text(color = "white"),
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "gray70"),
    axis.text = element_text(color = "white"),
    legend.background = element_rect(fill = "#222222", color = "white"),
    legend.text = element_text(color = "white"),
    legend.title = element_text(color = "white", face = "bold")
  )

# Instala las librerías si no las tienes:
# install.packages(c("ggplot2", "dplyr", "tidyr"))



# --- CONFIGURACIÓN DE LA SIMULACIÓN ---
num_caminatas <- 200  # Cuántas líneas simular
num_pasos     <- 500   # Cuántos pasos en el tiempo
# --------------------------------------

set.seed(123) # Para reproducibilidad

# 1. Crear el dataframe base con el eje del tiempo (pasos)
datos_1d <- data.frame(paso = 0:num_pasos)

# 2. Generar las caminatas (solo sube +1 o baja -1)
for(i in 1:num_caminatas) {
  # Cada paso puede ser arriba (1) o abajo (-1)
  pasos <- sample(c(-1, 1), num_pasos, replace = TRUE)
  
  # Posición acumulada empezando desde 0
  trayectoria <- c(0, cumsum(pasos))
  
  datos_1d[[paste0("Camino_", i)]] <- trayectoria
}

# 3. Transformar los datos a formato largo para ggplot
df_long_1d <- datos_1d %>%
  pivot_longer(cols = -paso, names_to = "caminata", values_to = "posicion")

# 4. Graficar
ggplot(df_long_1d, aes(x = paso, y = posicion, color = caminata)) +
  # Dibujar las líneas temporales
  geom_line(linewidth = 0.7, alpha = 0.8) +
  # Estética de fondo oscuro y neón
  labs(
    title = "Simulación de Caminatas Aleatorias en 1 Dimensión",
    subtitle = paste(num_caminatas, "partículas avanzando en el tiempo"),
    x = "Tiempo (Número de Pasos)",
    y = "Posición"
  ) +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "#111111", color = NA),
    plot.background = element_rect(fill = "#111111", color = NA),
    panel.grid.major = element_line(color = "#282828", linewidth = 0.5),
    panel.grid.minor = element_blank(),
    text = element_text(color = "white"),
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "gray70"),
    axis.text = element_text(color = "white"),
    legend.position = "none" # Ocultamos la leyenda para que se aprecie más el gráfico
  )

# Recordemos Bt ~ N(0,t), Bt-Bs~N(0,t-s)
#Var(Bt)=t entonces SD(Bt)=raiz(t)

# Instalar los paquetes necesarios si no los tienes:
# install.packages(c("ggplot2", "nortest"))

library(ggplot2)
library(nortest)
# Lillie.test

# --- CONFIGURACIÓN DE LA SIMULACIÓN ---
num_caminatas <- 100  # Más caminatas para que el test de normalidad sea robusto
num_pasos     <- 300   # Simulamos suficientes pasos para llegar al 250
paso_evaluar  <- 250   # El paso exacto que quieres analizar
# --------------------------------------

set.seed(123) # Para que obtengas exactamente los mismos resultados

# 1. Simular las posiciones finales en el paso 250
# Cada caminata es la suma de 250 pasos aleatorios de (-1 o 1)
posiciones_paso_250 <- replicate(num_caminatas, {
  pasos <- sample(c(-1, 1), paso_evaluar, replace = TRUE)
  sum(pasos) # Posición final acumulada en el paso 250
})

# Guardar en un dataframe para graficar
df_posiciones <- data.frame(posicion = posiciones_paso_250)

# ==========================================
# REQUISITO 1: PRUEBA DE LILLIEFORS
# ==========================================
cat("\n--- TEST DE NORMALIDAD DE LILLIEFORS ---\n")
## 
## --- TEST DE NORMALIDAD DE LILLIEFORS ---
resultado_lillie <- lillie.test(df_posiciones$posicion)
print(resultado_lillie)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  df_posiciones$posicion
## D = 0.064114, p-value = 0.3971
# H0: X_250 ~ N
# Ha: X_250 !~ N
# D = 0.064114, p-value = 0.3971 > 0.05
# No se rechaza supuesto de normalidad
# ==========================================
# REQUISITO 2: HISTOGRAMA
# ==========================================
ggplot(df_posiciones, aes(x = posicion)) +
  # Histograma con barras gris oscuro y bordes negros
  geom_histogram(aes(y = ..density..), bins = 25, 
                 fill = "#2c3e50", color = "white", alpha = 0.8) +
  # Curva de densidad real de los datos (línea azul)
  geom_density(color = "#2980b9", linewidth = 1.2) +
  # Curva normal teórica de comparación (línea roja segmentada)
  stat_function(fun = dnorm, 
                args = list(mean = mean(df_posiciones$posicion), 
                            sd = sd(df_posiciones$posicion)), 
                color = "#e74c3c", linewidth = 1, linetype = "dashed") +
  # Estética del gráfico
  labs(
    title = paste("Distribución de Posiciones en el Paso", paso_evaluar),
    subtitle = paste("Basado en", num_caminatas, "caminatas aleatorias"),
    x = "Posición alcanzada",
    y = "Densidad",
    caption = paste("P-valor de Lilliefors:", round(resultado_lillie$p.value, 4))
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray40")
  )

# Retornos y rendimientos

Retornos logaritmicos

\[ R_t:= log(\frac{S_t}{S_{t-1}}) \]