Introducción

La distribución logística es ampliamente utilizada en modelado financiero, especialmente para modelar retornos de activos. En este análisis, exploraremos cómo la distribución logística se ajusta a los retornos del S&P 500, comparándola con la distribución normal.

Definición de la Distribución Logística

La distribución logística está definida por la siguiente función de densidad de probabilidad (PDF):

\[ f(x | \mu, s) = \frac{e^{-\frac{x - \mu}{s}}}{s(1+e^{-\frac{x - \mu}{s}})^2}, \quad -\infty < x < \infty. \]

Donde: - \(\mu\) es el parámetro de ubicación, que define la media de la distribución. - \(s\) es el parámetro de escala, que determina la dispersión de los datos.

La función de distribución acumulativa (CDF) está dada por:

\[ F(x | \mu, s) = \frac{1}{1+e^{-\frac{x - \mu}{s}}}. \]

Tabla de Significado de Columnas

A continuación, presentamos una tabla con la descripción de las principales columnas del archivo Excel:

Descripción de las Columnas del Archivo Excel
Columna Descripción
S&P 500 Valor del índice S&P 500 en distintas fechas.
Return Retorno diario del índice calculado como la variación porcentual respecto al día anterior.
Ranked return Retornos ordenados de menor a mayor.
Empirical CDF Función de distribución acumulativa empírica basada en los datos observados.
Normal CDF Función de distribución acumulativa de una normal ajustada a los datos.
Logistic CDF Función de distribución acumulativa de la distribución logística ajustada a los datos.

Carga de Datos

Cargamos los datos del archivo de Excel:

library(readxl)
library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(MASS)
## 
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
## 
##     select
df_logistic <- read_excel("NEDL_Distributions.xlsx", sheet = "NEDL_Logistic")
## Warning: Expecting numeric in B1262 / R1262C2: got 'average'
## Warning: Expecting numeric in D1262 / R1262C4: got 'Logistic CDF:'
## Warning: Expecting numeric in B1263 / R1263C2: got 'stdev'
## Warning: Expecting numeric in B1264 / R1264C2: got 'a (scale)'
## New names:
## • `` -> `...1`
head(df_logistic)
## # A tibble: 6 × 8
##   ...1                `S&P 500`    Return  Rank `Ranked return` `Empirical CDF`
##   <dttm>                  <dbl>     <dbl> <dbl>           <dbl>           <dbl>
## 1 2014-12-31 00:00:00     2059. NA           NA         NA            NA       
## 2 2015-01-02 00:00:00     2058. -0.000340     1         -0.0410        0.000795
## 3 2015-01-05 00:00:00     2021. -0.0183       2         -0.0394        0.00159 
## 4 2015-01-06 00:00:00     2003. -0.00889      3         -0.0375        0.00238 
## 5 2015-01-07 00:00:00     2026.  0.0116       4         -0.0359        0.00318 
## 6 2015-01-08 00:00:00     2062.  0.0179       5         -0.0329        0.00397 
## # ℹ 2 more variables: `Normal CDF` <dbl>, `Logistic CDF` <dbl>

Exploración de los Retornos

Filtramos valores faltantes e infinitos en la columna Return:

df_logistic <- df_logistic %>% 
  filter(!is.na(Return) & is.finite(Return))

Visualizamos la distribución de los retornos con etiquetas:

ggplot(df_logistic, aes(x = `Return`)) +
  geom_histogram(aes(y = ..density..), bins = 50, fill = "steelblue", alpha = 0.6) +
  geom_density(color = "blue", size = 1) +
  ggtitle("Distribución de los Retornos del S&P 500") +
  theme_minimal() +
  labs(x = "Retorno del S&P 500", y = "Densidad", 
       caption = "El histograma representa la distribución empírica de los retornos, mientras que la línea roja muestra la estimación de densidad.")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Ajuste de la Distribución Logística

Ajustamos una distribución logística a los datos:

fit_log <- fitdistr(df_logistic$`Return`, "logistic")
## Warning in densfun(x, parm[1], parm[2], ...): NaNs produced
## Warning in densfun(x, parm[1], parm[2], ...): NaNs produced
## Warning in densfun(x, parm[1], parm[2], ...): NaNs produced
## Warning in densfun(x, parm[1], parm[2], ...): NaNs produced
## Warning in densfun(x, parm[1], parm[2], ...): NaNs produced
## Warning in densfun(x, parm[1], parm[2], ...): NaNs produced
fit_log
##      location        scale    
##   6.306995e-04   4.359456e-03 
##  (2.078378e-04) (8.945205e-05)

Comparación con la Distribución Normal y KDE

ggplot(df_logistic, aes(x = `Return`)) +
  geom_histogram(aes(y = ..density..), bins = 50, fill = "gray", alpha = 0.4) +
  stat_function(fun = dnorm, args = list(mean = mean(df_logistic$`Return`, na.rm = TRUE),
                                         sd = sd(df_logistic$`Return`, na.rm = TRUE)),
                color = "orange", linetype = "dashed", size = 1) +
  stat_function(fun = dlogis, args = list(location = fit_log$estimate[1],
                                          scale = fit_log$estimate[2]),
                color = "red", linetype = "solid", size = 1) +
  geom_density(color = "blue", size = 1, linetype = "dotdash") +
  ggtitle("Comparación de Distribuciones: Normal vs Logística vs KDE") +
  theme_minimal() +
  annotate("text", x = 0.02, y = 25,
           label = "Distribución Normal", 
           color = "orange", size = 4, hjust = 0) +
  annotate("text", x = 0.02, y = 22, 
           label = "Distribución Logística", 
           color = "red", size = 4, hjust = 0) +
  annotate("text", x = 0.02, y = 19, 
           label = "KDE Estimado", color = "blue",
           size = 4, hjust = 0) +
  labs(x = "Retorno del S&P 500", y = "Densidad", 
       caption = "El histograma representa la distribución empírica de los retornos.")