#install.packages("quantmod")
#install.packages("tidyquant")
# Manipulación de datos
library(readxl)       # Para leer archivos Excel
library(dplyr)        # Para manipular data frames
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Análisis financiero
library(PerformanceAnalytics)  # Para cálculos financieros, incluyendo alpha de Jensen
## 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
## 
## ######################### 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: 'xts'
## The following objects are masked from 'package:dplyr':
## 
##     first, last
## 
## Adjuntando el paquete: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
library(quantmod)              # Para trabajar con series temporales financieras
## Cargando paquete requerido: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(tidyquant)             # Para combinar tidyverse y datos financieros
## ── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
## ✖ zoo::as.Date()                 masks base::as.Date()
## ✖ zoo::as.Date.numeric()         masks base::as.Date.numeric()
## ✖ dplyr::filter()                masks stats::filter()
## ✖ xts::first()                   masks dplyr::first()
## ✖ dplyr::lag()                   masks stats::lag()
## ✖ xts::last()                    masks dplyr::last()
## ✖ PerformanceAnalytics::legend() masks graphics::legend()
## ✖ quantmod::summary()            masks base::summary()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# Visualización (opcional pero útil)
library(ggplot2)
library(readxl)

# Cambia la ruta si los archivos están en otra ubicación
data1 <- read_excel("data.xlsx")
## New names:
## • `` -> `...1`
data2 <- read_excel("Data2.xlsx")
## New names:
## • `` -> `...1`
# Ver primeras filas para inspeccionar
head(data1)
## # A tibble: 6 × 51
##   ...1                APPLE MICROSOFT AMAZON.COM `ALPHABET A`
##   <dttm>              <dbl>     <dbl>      <dbl>        <dbl>
## 1 2004-12-31 00:00:00  1.15      26.7       2.21         4.82
## 2 2005-01-31 00:00:00  1.37      26.3       2.16         4.90
## 3 2005-02-28 00:00:00  1.60      25.2       1.76         4.70
## 4 2005-03-31 00:00:00  1.49      24.2       1.71         4.52
## 5 2005-04-29 00:00:00  1.29      25.3       1.62         5.51
## 6 2005-05-31 00:00:00  1.42      25.8       1.78         6.94
## # ℹ 46 more variables: `JOHNSON & JOHNSON` <dbl>, WALMART <dbl>,
## #   `JP MORGAN CHASE & CO.` <dbl>, `PROCTER & GAMBLE` <dbl>,
## #   `UNITEDHEALTH GROUP` <dbl>, INTEL <dbl>, `HOME DEPOT` <dbl>,
## #   `VERIZON COMMUNICATIONS` <dbl>, NVIDIA <dbl>, `AT&T` <dbl>,
## #   `WALT DISNEY` <dbl>, PFIZER <dbl>, NETFLIX <dbl>, `BANK OF AMERICA` <dbl>,
## #   `EXXON MOBIL` <dbl>, `COCA COLA` <dbl>, `ADOBE (NAS)` <dbl>,
## #   `MERCK & COMPANY` <dbl>, `CISCO SYSTEMS` <dbl>, CHEVRON <dbl>, …
head(data2)
## # A tibble: 6 × 4
##   ...1                `S&P 500 COMPOSITE - PRICE INDEX` S&P 500 COMPOSITE - TO…¹
##   <dttm>                                          <dbl>                    <dbl>
## 1 2004-12-31 00:00:00                             1212.                    1800.
## 2 2005-01-31 00:00:00                             1181.                    1756.
## 3 2005-02-28 00:00:00                             1204.                    1793.
## 4 2005-03-31 00:00:00                             1181.                    1761.
## 5 2005-04-29 00:00:00                             1157.                    1727.
## 6 2005-05-31 00:00:00                             1192.                    1782.
## # ℹ abbreviated name: ¹​`S&P 500 COMPOSITE - TOT RETURN IND`
## # ℹ 1 more variable: `US T-BILL SEC MARKET 3 MONTH (D) - MIDDLE RATE` <dbl>
library(readxl)
library(dplyr)
library(tibble)
library(PerformanceAnalytics)


data_prices <- read_excel("data.xlsx")
## New names:
## • `` -> `...1`
data_market <- read_excel("Data2.xlsx")
## New names:
## • `` -> `...1`
# Asegurar formato de fecha
data_prices[[1]] <- as.Date(data_prices[[1]])
data_market[[1]] <- as.Date(data_market[[1]])

# Renombrar columnas para facilitar el uso
colnames(data_market)[2:4] <- c("SP500_Price", "SP500_TotalReturn", "RiskFree")

# Calcular retornos logarítmicos
returns_assets <- data_prices %>%
  arrange(data_prices[[1]]) %>%
  mutate(across(-1, ~ log(. / lag(.)))) %>%
  slice(-1)  # eliminar el primer NA

returns_market <- data_market %>%
  arrange(data_market[[1]]) %>%
  mutate(
    MarketReturn = log(SP500_TotalReturn / lag(SP500_TotalReturn)),
    RiskFreeRate = log(1 + RiskFree / 100 / 12)  # aproximando mensual
  ) %>%
  select(Date = 1, MarketReturn, RiskFreeRate) %>%
  slice(-1)

# Combinar fechas con retornos de activos
returns_assets <- rename(returns_assets, Date = 1)

# Unir datasets
full_data <- inner_join(returns_assets, returns_market, by = "Date")
# Crear una función para calcular Jensen's alpha
calcular_alpha <- function(retorno_activo, retorno_mercado, riesgo_libre) {
  exceso_retorno_activo <- retorno_activo - riesgo_libre
  exceso_retorno_mercado <- retorno_mercado - riesgo_libre
  
  modelo <- lm(exceso_retorno_activo ~ exceso_retorno_mercado)
  alpha <- coef(modelo)[1]
  return(alpha)
}

# Aplicar a cada activo (excepto las columnas de fecha, MarketReturn y RiskFreeRate)
nombres_activos <- colnames(full_data)[!(colnames(full_data) %in% c("Date", "MarketReturn", "RiskFreeRate"))]

alphas <- sapply(nombres_activos, function(nombre_activo) {
  calcular_alpha(
    retorno_activo = full_data[[nombre_activo]],
    retorno_mercado = full_data$MarketReturn,
    riesgo_libre = full_data$RiskFreeRate
  )
})

# Convertir a data frame para ordenarlo
tabla_alphas <- data.frame(Asset = nombres_activos, JensenAlpha = alphas)
tabla_alphas <- tabla_alphas %>%
  filter(JensenAlpha > 0) %>%
  arrange(desc(JensenAlpha))

# Mostrar los 10 mejores
top_10 <- head(tabla_alphas, 10)
print(top_10)
##                                                         Asset JensenAlpha
## NETFLIX.(Intercept)                                   NETFLIX 0.017002618
## NVIDIA.(Intercept)                                     NVIDIA 0.013335182
## APPLE.(Intercept)                                       APPLE 0.012637688
## AMAZON.COM.(Intercept)                             AMAZON.COM 0.009879615
## SALESFORCE.(Intercept)                             SALESFORCE 0.007986925
## ELI LILLY.(Intercept)                               ELI LILLY 0.006481438
## ALPHABET A.(Intercept)                             ALPHABET A 0.006320645
## COSTCO WHOLESALE.(Intercept)                 COSTCO WHOLESALE 0.005679584
## THERMO FISHER SCIENTIFIC.(Intercept) THERMO FISHER SCIENTIFIC 0.005536472
## AMERICAN TOWER.(Intercept)                     AMERICAN TOWER 0.004911322
# Extraer solo los nombres de los top 10 activos
top_10_nombres <- top_10$Asset

# Filtrar las columnas de esos activos en el full_data
retornos_top10 <- full_data %>%
  select(all_of(top_10_nombres))

# Calcular el rendimiento promedio (igualmente ponderado) en cada periodo
portafolio_igual <- rowMeans(retornos_top10, na.rm = TRUE)

# Agregar columna al full_data
full_data$EqualWeightedPortfolio <- portafolio_igual

# Ver primeros valores
head(full_data[, c("Date", "EqualWeightedPortfolio")])
## # A tibble: 6 × 2
##   Date       EqualWeightedPortfolio
##   <date>                      <dbl>
## 1 2005-01-31               -0.0235 
## 2 2005-02-28                0.0173 
## 3 2005-03-31               -0.0608 
## 4 2005-04-29               -0.00969
## 5 2005-05-31                0.139  
## 6 2005-06-30                0.0161
# Crear xts del portafolio para usar funciones de PerformanceAnalytics
portafolio_xts <- xts(full_data$EqualWeightedPortfolio, order.by = full_data$Date)

# Rendimiento acumulado
chart.CumReturns(portafolio_xts, main = "Rendimiento Acumulado del Portafolio", wealth.index = TRUE, ylab = "Crecimiento del $1")

# Crear xts para benchmark también
benchmark_xts <- xts(full_data$MarketReturn, order.by = full_data$Date)

# Juntar ambos en un solo objeto
compare_xts <- merge(portafolio_xts, benchmark_xts)
colnames(compare_xts) <- c("Portafolio", "Benchmark")

# Gráfica de rendimientos acumulados
chart.CumReturns(compare_xts, legend.loc = "topleft", main = "Comparación del Portafolio vs Benchmark", wealth.index = TRUE, ylab = "Crecimiento del $1")

# Calcular Jensen's alpha del portafolio frente al benchmark
exceso_portafolio <- full_data$EqualWeightedPortfolio - full_data$RiskFreeRate
exceso_mercado <- full_data$MarketReturn - full_data$RiskFreeRate

modelo_portafolio <- lm(exceso_portafolio ~ exceso_mercado)
alpha_portafolio <- coef(modelo_portafolio)[1]

cat("Jensen's alpha del portafolio igual ponderado:", round(alpha_portafolio, 6), "\n")
## Jensen's alpha del portafolio igual ponderado: 0.008977
# Promedio y desviación estándar mensual del portafolio
avg_return <- mean(full_data$EqualWeightedPortfolio, na.rm = TRUE)
std_dev <- sd(full_data$EqualWeightedPortfolio, na.rm = TRUE)

cat("Promedio mensual:", round(avg_return, 6), "\n")
## Promedio mensual: 0.017198
cat("Desviación estándar mensual:", round(std_dev, 6), "\n")
## Desviación estándar mensual: 0.058469
# Promedio del risk-free rate
avg_riskfree <- mean(full_data$RiskFreeRate, na.rm = TRUE)

# Sharpe ratio
sharpe_ratio <- (avg_return - avg_riskfree) / std_dev
cat("Sharpe Ratio:", round(sharpe_ratio, 4), "\n")
## Sharpe Ratio: 0.2735
# Crear xts del portafolio para usar UpsidePotentialRatio
portafolio_xts <- # Convertir el portafolio en objeto xts si no lo hiciste aún
portafolio_xts <- xts(full_data$EqualWeightedPortfolio, order.by = full_data$Date)

# Calcular la tasa libre de riesgo promedio mensual
avg_riskfree <- mean(full_data$RiskFreeRate, na.rm = TRUE)

# Calcular el Upside-Potential Ratio
up_ratio <- UpsidePotentialRatio(portafolio_xts, MAR = avg_riskfree)

# Mostrar resultado
cat("Upside-Potential Ratio:", round(up_ratio[1,1], 4), "\n")
## Upside-Potential Ratio: 0.7181