En este documento se realiza un análisis financiero detallado que incluye el cálculo de rendimientos logarítmicos de acciones, la evaluación de la volatilidad y el diseño de portafolios óptimos basados en métricas de riesgo y retorno. Se utilizan modelos estadísticos y financieros para comprender el comportamiento de las acciones y su relación con el mercado.
Se cargan las librerías necesarias para la manipulación y análisis de
datos, como readxl para leer archivos Excel,
dplyr para la manipulación de datos, ggplot2
para la visualización, y kableExtra para la presentación de
tablas.
library(readxl)
library(dplyr)
library(ggplot2)
library(knitr)
library(kableExtra)
En esta sección, se importan los datos históricos de precios de las acciones desde un archivo Excel. Se realiza una limpieza preliminar para eliminar valores faltantes y se obtienen los nombres de las hojas para su posterior análisis.
# Cargar el archivo Excel
file_path= 'precios_historicos.xlsx'
sheets <- read_excel(file_path)
sheets <- na.omit(sheets)
sheets
## # A tibble: 60 × 7
## Date Open High Low `Close*` `Adj Close**` Volume
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 Nov 01, 2024 138.35 138.89 131.51 133.58 133.58 5,665,100
## 2 Oct 01, 2024 146.47 147.21 133.60 138.11 138.11 21,089,900
## 3 Sep 01, 2024 142.85 150.68 142.52 146.24 146.24 22,343,500
## 4 Aug 01, 2024 142.99 149.00 138.89 143.12 142.35 18,937,700
## 5 Jul 01, 2024 129.48 144.30 127.20 142.36 141.60 18,090,100
## 6 Jun 01, 2024 131.13 133.35 127.10 129.16 128.47 19,087,900
## 7 May 01, 2024 122.12 135.71 122.09 130.77 129.33 31,191,800
## 8 Apr 01, 2024 122.44 123.10 113.34 122.32 120.98 32,059,400
## 9 Mar 01, 2024 118.18 122.41 116.38 122.21 120.87 33,228,200
## 10 Feb 01, 2024 123.86 125.36 116.70 118.54 116.56 33,213,600
## # ℹ 50 more rows
sheet_names <- excel_sheets(file_path) # Obtener los nombres de las hojas
Se define una función para calcular los rendimientos logarítmicos de las acciones y se aplica a los datos de cada hoja. Los resultados se almacenan en un marco de datos combinado que incluye los rendimientos logarítmicos de todas las acciones. Se muestran ejemplos de los rendimientos calculados.
# Función para calcular rendimientos logarítmicos
calculate_log_returns <- function(prices) {
log_returns <- log(prices / lag(prices))
return(na.omit(log_returns))
}
# Crear un marco de datos para almacenar los rendimientos logarítmicos de todas las acciones
log_returns_all <- data.frame(Date = as.Date(character()))
# Bucle para calcular y agregar los rendimientos logarítmicos de cada hoja
for (sheet in sheet_names) {
# Leer los datos
df <- read_excel(file_path, sheet = sheet)
df <- na.omit(df)
# Limpiar y convertir los precios de cierre ajustados
df$`Adj Close**` <- as.numeric(gsub(",", "", df$`Adj Close**`))
df$Date <- as.Date(df$Date, format = "%b %d, %Y")
# Calcular los rendimientos logarítmicos
log_returns <- calculate_log_returns(df$`Adj Close**`)
# Agregar la fecha correspondiente (omitiendo el primer valor que es NA)
df_log_returns <- data.frame(Date = df$Date[-1], Log_Returns = log_returns)
colnames(df_log_returns)[2] <- paste0("Log_Returns_", sheet)
# Combinar los datos en el marco de datos principal
log_returns_all <- merge(log_returns_all, df_log_returns, by = "Date", all = TRUE)
}
# Mostrar los primeros rendimientos logarítmicos calculados
head(log_returns_all, 59)
## Date Log_Returns_awk Log_Returns_ato Log_Returns_tsla Log_Returns_pfe
## 1 2019-12-01 -0.1031634135 -0.0451530618 -0.44149976 0.050481781
## 2 2020-01-01 0.0965481744 0.1252209815 -0.02639516 0.098213943
## 3 2020-02-01 0.0300740998 0.0349079463 0.24281706 0.023503297
## 4 2020-03-01 -0.0176900406 -0.0272307864 -0.40039454 -0.161309622
## 5 2020-04-01 -0.0426894087 -0.0078956436 -0.06570080 0.004322534
## 6 2020-05-01 -0.0176681548 0.0256679652 -0.25708582 0.145359050
## 7 2020-06-01 -0.1350803850 -0.0623437463 -0.28134169 -0.162865690
## 8 2020-07-01 0.0410965564 0.0599930428 -0.55478131 0.008549871
## 9 2020-08-01 -0.0284251035 0.0375941298 0.14980559 0.029152676
## 10 2020-09-01 -0.0381137041 0.0419641991 0.10032272 0.033889827
## 11 2020-10-01 -0.0189458516 -0.0450937293 -0.38028275 -0.129478167
## 12 2020-11-01 -0.0039836514 -0.0015033249 -0.21771659 0.029796779
## 13 2020-12-01 -0.0354929007 0.0697442515 -0.11735781 0.025146393
## 14 2021-01-01 0.1140371152 0.0505697171 0.16102339 0.058484406
## 15 2021-02-01 -0.0584653407 -0.1621800216 0.01129956 -0.078523862
## 16 2021-03-01 -0.0396941170 -0.0468675133 -0.06030752 -0.064738501
## 17 2021-04-01 0.0062433739 0.0436590135 0.12635634 -0.002097379
## 18 2021-05-01 0.0017910041 0.0249411799 -0.08354665 -0.020735340
## 19 2021-06-01 -0.0986641238 -0.0254933305 -0.01097369 -0.089134598
## 20 2021-07-01 -0.0689095763 0.0109897315 -0.06820969 -0.082329836
## 21 2021-08-01 0.0717872762 0.0940273775 -0.05261969 0.068745927
## 22 2021-09-01 -0.0299321923 -0.0434329301 -0.36223415 -0.017049593
## 23 2021-10-01 0.0327553693 0.0196828740 -0.02725558 -0.205670588
## 24 2021-11-01 -0.1172453806 -0.1556036840 0.07997719 -0.103113657
## 25 2021-12-01 0.1608407930 -0.0230989907 0.12059742 0.113970603
## 26 2022-01-01 0.0622748211 -0.0238495298 0.07340856 0.107932313
## 27 2022-02-01 -0.0951323840 -0.0908909919 -0.21351577 -0.097821438
## 28 2022-03-01 0.0716636094 0.0522383740 0.21313672 0.053514821
## 29 2022-04-01 0.0185222357 -0.0252684136 0.13834176 -0.077864593
## 30 2022-05-01 0.0121662807 0.0307401254 0.11865879 0.003593704
## 31 2022-06-01 -0.0439041199 -0.0796132841 -0.28049499 0.037105206
## 32 2022-07-01 0.0460167968 0.0682318887 0.07525024 0.102677914
## 33 2022-08-01 0.1272567441 0.1015021501 0.03831405 0.033179572
## 34 2022-09-01 -0.1102644047 -0.0451356586 0.15334673 -0.061749515
## 35 2022-10-01 -0.0432226672 -0.1205717640 0.15586613 -0.074107972
## 36 2022-11-01 -0.0090919039 0.0637377425 0.45781321 -0.030518546
## 37 2022-12-01 -0.0263261460 -0.0476454412 -0.34091576 0.148658789
## 38 2023-01-01 0.1086284080 0.0411228687 -0.17190495 0.075764626
## 39 2023-02-01 -0.0467685171 -0.0024118750 -0.00847114 -0.005852637
## 40 2023-03-01 -0.0119854247 -0.0156281908 0.23318366 0.048087493
## 41 2023-04-01 0.0259736529 -0.0099837460 -0.21602191 0.022517135
## 42 2023-05-01 0.0070321759 -0.0155027972 -0.24968946 0.025076973
## 43 2023-06-01 -0.0322391447 -0.0452015066 -0.02139159 0.017074304
## 44 2023-07-01 0.0607989502 0.0484969894 0.03558824 0.008048933
## 45 2023-08-01 0.1086921478 0.0839907771 0.03092908 0.064598385
## 46 2023-09-01 0.0511802642 -0.0161697460 0.21983196 0.081800318
## 47 2023-10-01 -0.1139308837 -0.0555234030 -0.17846363 0.003123376
## 48 2023-11-01 -0.0068808498 -0.0253268397 -0.03439016 0.043330642
## 49 2023-12-01 0.0623066350 0.0170519229 0.28270414 0.060987664
## 50 2024-01-01 0.0452049628 0.0090881086 -0.07501524 0.004640380
## 51 2024-02-01 -0.0363094260 -0.0585434556 0.13838336 -0.043979794
## 52 2024-03-01 -0.0009096548 0.0082178172 -0.04172494 0.079888170
## 53 2024-04-01 -0.0667420347 0.0169032759 0.02878215 -0.112007719
## 54 2024-05-01 0.0066718634 -0.0133728981 -0.10542790 0.009020447
## 55 2024-06-01 -0.0973107672 -0.0919089362 -0.15937826 -0.087403954
## 56 2024-07-01 -0.0052826325 -0.0221003470 0.08054915 0.037216744
## 57 2024-08-01 -0.0269602940 -0.0653895789 -0.20044139 0.002415877
## 58 2024-09-01 0.0571986386 -0.0005045227 0.04607055 0.022362917
## 59 2024-10-01 0.0333499198 -0.0007203054 -0.14393833 0.033779712
## Log_Returns_hpq Log_Returns_hlt Log_Returns_ba Log_Returns_aapl
## 1 -0.045373227 0.028389719 0.023243057 -0.052625740
## 2 0.024952778 0.103475874 0.145747137 0.124178275
## 3 0.180414337 0.352241399 0.606343031 0.069930185
## 4 0.103345063 -0.103894728 0.055983738 -0.144425754
## 5 0.024152117 -0.046380593 -0.033676972 -0.078944126
## 6 -0.140857433 0.076706459 -0.228545459 -0.140104852
## 7 -0.018409461 -0.021485733 0.148529122 -0.152929482
## 8 -0.106207063 -0.185723987 -0.083852384 -0.194212759
## 9 0.029125387 0.057368755 0.038927426 0.106437959
## 10 0.046290276 -0.028693361 0.135002019 0.061873524
## 11 -0.199233955 -0.165664489 -0.377964809 -0.089499349
## 12 -0.114787987 -0.071069176 -0.015773569 -0.110171000
## 13 0.002310003 0.092935506 0.097419288 0.005481158
## 14 -0.174427390 -0.198749639 -0.087796382 0.084523237
## 15 -0.091630323 0.022537793 -0.183531459 -0.008806196
## 16 -0.078050159 -0.062307806 0.083519878 -0.073391999
## 17 0.154259975 0.026954524 -0.052824280 0.053468221
## 18 -0.032370158 0.037861225 0.030665398 -0.096150682
## 19 0.038509855 -0.086006436 0.056147267 -0.062957346
## 20 -0.029581224 0.051455002 0.031304408 -0.040162743
## 21 0.083349115 -0.056434901 -0.002002549 0.068988081
## 22 -0.109535379 -0.085851617 0.060491072 -0.056978761
## 23 -0.151390621 0.063706586 0.045354542 -0.098495220
## 24 -0.065398602 -0.143997437 -0.017386514 -0.073044194
## 25 0.018338284 0.072257557 0.005379035 0.015848192
## 26 0.066969334 -0.025484774 -0.025150495 0.056827020
## 27 -0.054957177 -0.019145448 0.069779333 -0.057117423
## 28 -0.016182553 -0.023151314 0.252015905 0.102139486
## 29 -0.058594164 0.097510114 0.124625797 0.057514112
## 30 0.169784828 0.233192439 -0.039688933 0.083506018
## 31 -0.024935675 -0.139092822 -0.152916951 -0.172859270
## 32 0.151184679 0.005527494 -0.005883106 0.033126307
## 33 0.141478454 0.053258124 0.280283612 0.127514351
## 34 -0.111636913 -0.114529973 -0.162960689 -0.103925585
## 35 -0.084126962 -0.053012230 -0.227303017 0.035230268
## 36 0.111687762 0.119921923 -0.062884510 0.128771403
## 37 -0.090398847 -0.138258219 -0.111692466 -0.104855416
## 38 -0.013043663 0.004030302 0.055254676 -0.021385638
## 39 0.005776189 0.024457645 -0.052575033 -0.113604990
## 40 -0.021136377 -0.022087480 0.026957096 -0.028618997
## 41 0.021860752 0.056419698 0.005236629 -0.043640542
## 42 -0.054982134 -0.068076782 -0.026197343 -0.091493273
## 43 -0.075601076 -0.066063641 -0.123219600 -0.012735085
## 44 0.099899390 0.045038975 0.064055768 0.044684663
## 45 0.144940472 -0.011284376 0.155952657 0.091492340
## 46 -0.033156622 -0.008910226 0.025681728 0.002586411
## 47 -0.108263959 -0.100316704 -0.214995685 -0.106431161
## 48 -0.025070951 -0.084308126 -0.118075605 -0.014811973
## 49 0.037846142 -0.047560208 0.211169187 0.043149170
## 50 0.013302371 -0.067620390 0.035301187 0.019958328
## 51 -0.064809928 -0.043856577 0.054108128 0.051389753
## 52 0.064086339 0.078135384 0.139627229 0.006745883
## 53 -0.261668515 -0.016662438 -0.056578991 -0.121086709
## 54 0.041204863 -0.084858228 -0.024471495 -0.092618682
## 55 -0.037579144 0.016321420 -0.046115361 -0.052950823
## 56 -0.002511512 -0.022903699 0.092617062 -0.030719745
## 57 0.008677451 -0.048944189 0.133416285 -0.018452466
## 58 0.001406668 -0.018696150 0.018118963 0.030901764
## 59 -0.038386599 -0.048130965 0.014504251 0.014221313
## Log_Returns_bac Log_Returns_pypl Log_Returns_s&p500
## 1 0.0650743981 -0.0515290066 1.629417e-03
## 2 0.1412553382 0.0531944400 8.785952e-02
## 3 0.2946866607 0.1204024463 1.336678e-01
## 4 -0.1310747968 -0.2505481714 -1.194209e-01
## 5 -0.0032520354 -0.2313052756 -4.428649e-02
## 6 0.0158956129 -0.1168866345 -1.822138e-02
## 7 -0.0536702974 -0.1180954729 -5.363678e-02
## 8 -0.0338122221 -0.0403342946 -6.771910e-02
## 9 0.0660364761 0.0354500316 4.001810e-02
## 10 0.0092679069 0.0569106471 2.805568e-02
## 11 -0.1723401888 -0.1400912512 -1.021464e-01
## 12 -0.0736320416 -0.0896388456 -3.644900e-02
## 13 0.0157772489 -0.0004695738 1.119912e-02
## 14 -0.1574208974 -0.1034595165 -2.575690e-02
## 15 -0.1085780825 0.0677017512 -4.156281e-02
## 16 -0.0513783248 -0.0770479716 -5.109732e-02
## 17 -0.0447560875 0.0086922107 -5.471507e-03
## 18 0.0276707813 -0.1142128417 -2.197084e-02
## 19 0.0678968981 0.0562748772 -2.249323e-02
## 20 -0.0846951934 -0.0465530094 -2.857805e-02
## 21 -0.0165207681 0.1037605276 4.873776e-02
## 22 -0.1233995937 0.1122117504 -6.685821e-02
## 23 0.0717607369 0.2295161933 8.368651e-03
## 24 -0.0004861449 -0.0197612664 -4.268861e-02
## 25 -0.0411815896 0.0923767413 5.401815e-02
## 26 0.0428841317 0.4292719028 3.186279e-02
## 27 0.0698104263 -0.0326947128 -3.514824e-02
## 28 0.1395531414 0.2740273453 9.206783e-02
## 29 -0.0417339435 0.0314222456 -5.324247e-05
## 30 0.1781850462 0.1989118863 8.765157e-02
## 31 -0.0885009218 -0.2142842631 -8.720134e-02
## 32 0.0060003338 -0.0768283445 4.336702e-02
## 33 0.1068750537 0.0821586004 9.804920e-02
## 34 -0.1830849829 0.0293566616 -7.683460e-02
## 35 -0.0492512931 0.0638527868 -5.235794e-02
## 36 0.1337309894 0.0961777924 6.078180e-02
## 37 -0.0747465418 -0.1347066355 -5.992116e-02
## 38 0.0337584799 0.1018352876 2.645943e-02
## 39 0.1817086239 -0.0312985291 -3.445125e-02
## 40 -0.0300583919 -0.0007897855 -1.453620e-02
## 41 0.0523641494 0.2037602586 -2.479248e-03
## 42 -0.0318191846 -0.0736815452 -6.271891e-02
## 43 -0.1170544382 -0.1277074832 -3.066393e-02
## 44 0.1097975123 0.1930355661 1.787525e-02
## 45 0.0375734806 0.0669837843 4.994609e-02
## 46 0.0390405492 0.1209526104 2.222484e-02
## 47 -0.1464260402 -0.1063060145 -8.542444e-02
## 48 -0.1073141018 -0.0638765246 -4.327898e-02
## 49 -0.0099443339 0.0009775172 -1.577073e-02
## 50 -0.0148812270 0.0165999374 -5.042750e-02
## 51 -0.1010677106 -0.1045481208 -3.054741e-02
## 52 0.0243255238 -0.0137871875 4.250575e-02
## 53 -0.0773662891 0.0753545584 -4.690384e-02
## 54 0.0055866067 0.0820158654 -3.408230e-02
## 55 -0.0196678049 -0.1253557226 -1.125774e-02
## 56 -0.0109263565 -0.0963047374 -2.257788e-02
## 57 0.0267817283 -0.0744727899 -1.999562e-02
## 58 -0.0591013923 -0.0161447605 9.946079e-03
## 59 -0.0823576511 -0.0262599869 -3.844045e-02
Se crea una visualización que muestra cómo varían los rendimientos logarítmicos de las diferentes acciones a lo largo del tiempo. Esto permite observar patrones de volatilidad y tendencias en el comportamiento de las acciones.
# Graficar los rendimientos logarítmicos para cada acción
library(tidyr)
log_returns_long <- pivot_longer(log_returns_all, -Date, names_to = "Stock", values_to = "Log_Returns")
ggplot(log_returns_long, aes(x = Date, y = Log_Returns, color = Stock)) +
geom_line() +
theme_minimal() +
labs(title = "Rendimientos Logarítmicos de las Acciones", x = "Fecha", y = "Rendimiento Logarítmico")
Se calcula la volatilidad anual de cada acción utilizando la desviación estándar de los rendimientos logarítmicos, ajustada para un período anual. Se presenta una tabla con los resultados de la volatilidad y se visualizan las diferencias en volatilidad entre las acciones mediante un gráfico de barras.
# Inicializar un marco de datos para almacenar los resultados
volatility_results <- data.frame(Stock = character(), Annualized_Volatility = numeric(), stringsAsFactors = FALSE)
# Bucle para calcular la volatilidad de cada hoja
for (sheet in sheet_names) {
# Leer los datos de cada hoja
df <- read_excel(file_path, sheet = sheet)
# Limpiar los datos y convertir la columna de precios a numérica
df$`Adj Close**` <- as.numeric(gsub(",", "", df$`Adj Close**`))
# Calcular los rendimientos logarítmicos
log_returns <- calculate_log_returns(df$`Adj Close**`)
# Calcular la volatilidad anual (desviación estándar de los rendimientos logarítmicos * sqrt(12))
annualized_volatility <- sd(log_returns) * sqrt(12)
# Agregar los resultados al marco de datos
volatility_results <- rbind(volatility_results, data.frame(Stock = sheet, Annualized_Volatility = annualized_volatility))
}
# Mostrar la tabla de resultados
print(volatility_results)
## Stock Annualized_Volatility
## 1 awk 0.2296703
## 2 ato 0.1724383
## 3 tsla 0.6970255
## 4 pfe 0.2771655
## 5 hpq 0.3721300
## 6 hlt 0.2659250
## 7 ba 0.4197662
## 8 aapl 0.2685091
## 9 bac 0.3340926
## 10 pypl 0.4349711
## 11 s&p500 0.1822441
# Graficar la volatilidad anual de las acciones
ggplot(volatility_results, aes(x = Stock, y = Annualized_Volatility)) +
geom_bar(stat = "identity", fill = "steelblue") +
theme_minimal() +
labs(title = "Volatilidad Anual de las Acciones", x = "Acción", y = "Volatilidad Anual")
En este análisis, hemos calculado los rendimientos logarítmicos mensuales de varias acciones americanas y del índice S&P 500. La representación gráfica de estos rendimientos a lo largo del tiempo nos permite observar la variabilidad y las tendencias de cada acción, destacando periodos de alta y baja volatilidad.
Además, la volatilidad anual calculada muestra diferencias significativas entre las acciones analizadas. Tesla (TSLA), por ejemplo, presenta una volatilidad significativamente mayor en comparación con otras acciones, lo que sugiere un riesgo más alto asociado con sus rendimientos. Por otro lado, el índice S&P 500 muestra una volatilidad más baja, lo que es coherente con la naturaleza diversificada y menos riesgosa del índice.
Se calculan y analizan la matriz de coeficientes de correlación y la matriz de covarianzas de los rendimientos logarítmicos. La matriz de correlación muestra la relación lineal entre las acciones, mientras que la matriz de covarianzas proporciona información sobre cómo varían los rendimientos conjuntamente.
# Seleccionar solo las columnas con los rendimientos logarítmicos (omitimos la columna de fechas)
log_returns_matrix <- log_returns_all %>% select(-Date) %>% na.omit()
# Calcular la matriz de coeficientes de correlación
correlation_matrix <- cor(log_returns_matrix, use = "pairwise.complete.obs")
# Calcular la matriz de covarianzas
covariance_matrix <- cov(log_returns_matrix, use = "pairwise.complete.obs")
# Mostrar la matriz de coeficientes de correlación
kable(correlation_matrix, caption = "Matriz de Coeficientes de Correlación") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
row_spec(0, bold = TRUE, background = "#D3D3D3") %>% # Encabezado con color
column_spec(1, bold = TRUE, color = "white", background = "#4682B4") # Primera columna con color
| Log_Returns_awk | Log_Returns_ato | Log_Returns_tsla | Log_Returns_pfe | Log_Returns_hpq | Log_Returns_hlt | Log_Returns_ba | Log_Returns_aapl | Log_Returns_bac | Log_Returns_pypl | Log_Returns_s&p500 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Log_Returns_awk | 1.0000000 | 0.6429464 | 0.2625250 | 0.5441420 | 0.3472170 | 0.1885170 | 0.3007542 | 0.5404377 | 0.2572392 | 0.4090158 | 0.5538921 |
| Log_Returns_ato | 0.6429464 | 1.0000000 | 0.2044695 | 0.4277278 | 0.4265234 | 0.3446326 | 0.3786872 | 0.4560129 | 0.4245558 | 0.2802908 | 0.6021273 |
| Log_Returns_tsla | 0.2625250 | 0.2044695 | 1.0000000 | 0.1111783 | 0.3350303 | 0.3868780 | 0.2794198 | 0.6905233 | 0.3100983 | 0.4251475 | 0.5455507 |
| Log_Returns_pfe | 0.5441420 | 0.4277278 | 0.1111783 | 1.0000000 | 0.2922070 | 0.1032468 | 0.0962574 | 0.3447579 | 0.2044936 | 0.1307161 | 0.4268015 |
| Log_Returns_hpq | 0.3472170 | 0.4265234 | 0.3350303 | 0.2922070 | 1.0000000 | 0.5033155 | 0.5260152 | 0.5386077 | 0.5795902 | 0.2664267 | 0.6130497 |
| Log_Returns_hlt | 0.1885170 | 0.3446326 | 0.3868780 | 0.1032468 | 0.5033155 | 1.0000000 | 0.5186176 | 0.4506884 | 0.7159141 | 0.4057529 | 0.7403812 |
| Log_Returns_ba | 0.3007542 | 0.3786872 | 0.2794198 | 0.0962574 | 0.5260152 | 0.5186176 | 1.0000000 | 0.4135098 | 0.5973720 | 0.2915161 | 0.6126407 |
| Log_Returns_aapl | 0.5404377 | 0.4560129 | 0.6905233 | 0.3447579 | 0.5386077 | 0.4506884 | 0.4135098 | 1.0000000 | 0.3989357 | 0.4955514 | 0.7623548 |
| Log_Returns_bac | 0.2572392 | 0.4245558 | 0.3100983 | 0.2044936 | 0.5795902 | 0.7159141 | 0.5973720 | 0.3989357 | 1.0000000 | 0.5031098 | 0.7595649 |
| Log_Returns_pypl | 0.4090158 | 0.2802908 | 0.4251475 | 0.1307161 | 0.2664267 | 0.4057529 | 0.2915161 | 0.4955514 | 0.5031098 | 1.0000000 | 0.6026257 |
| Log_Returns_s&p500 | 0.5538921 | 0.6021273 | 0.5455507 | 0.4268015 | 0.6130497 | 0.7403812 | 0.6126407 | 0.7623548 | 0.7595649 | 0.6026257 | 1.0000000 |
# Mostrar la matriz de covarianzas
kable(covariance_matrix, caption = "Matriz de Covarianzas") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
row_spec(0, bold = TRUE, background = "#D3D3D3") %>% # Encabezado con color
column_spec(1, bold = TRUE, color = "white", background = "#4682B4") # Primera columna con color
| Log_Returns_awk | Log_Returns_ato | Log_Returns_tsla | Log_Returns_pfe | Log_Returns_hpq | Log_Returns_hlt | Log_Returns_ba | Log_Returns_aapl | Log_Returns_bac | Log_Returns_pypl | Log_Returns_s&p500 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Log_Returns_awk | 0.0043610 | 0.0024861 | 0.0034602 | 0.0027499 | 0.0021374 | 0.0011767 | 0.0028504 | 0.0029334 | 0.0015984 | 0.0033916 | 0.0019243 |
| Log_Returns_ato | 0.0024861 | 0.0034286 | 0.0023896 | 0.0019167 | 0.0023280 | 0.0019073 | 0.0031823 | 0.0021947 | 0.0023391 | 0.0020608 | 0.0018549 |
| Log_Returns_tsla | 0.0034602 | 0.0023896 | 0.0398358 | 0.0016981 | 0.0062332 | 0.0072983 | 0.0080039 | 0.0113281 | 0.0058236 | 0.0106548 | 0.0057284 |
| Log_Returns_pfe | 0.0027499 | 0.0019167 | 0.0016981 | 0.0058565 | 0.0020845 | 0.0007468 | 0.0010572 | 0.0021686 | 0.0014725 | 0.0012561 | 0.0017183 |
| Log_Returns_hpq | 0.0021374 | 0.0023280 | 0.0062332 | 0.0020845 | 0.0086891 | 0.0044344 | 0.0070371 | 0.0041267 | 0.0050835 | 0.0031184 | 0.0030064 |
| Log_Returns_hlt | 0.0011767 | 0.0019073 | 0.0072983 | 0.0007468 | 0.0044344 | 0.0089334 | 0.0070350 | 0.0035013 | 0.0063668 | 0.0048155 | 0.0036815 |
| Log_Returns_ba | 0.0028504 | 0.0031823 | 0.0080039 | 0.0010572 | 0.0070371 | 0.0070350 | 0.0205974 | 0.0048779 | 0.0080669 | 0.0052534 | 0.0046257 |
| Log_Returns_aapl | 0.0029334 | 0.0021947 | 0.0113281 | 0.0021686 | 0.0041267 | 0.0035013 | 0.0048779 | 0.0067559 | 0.0030853 | 0.0051145 | 0.0032966 |
| Log_Returns_bac | 0.0015984 | 0.0023391 | 0.0058236 | 0.0014725 | 0.0050835 | 0.0063668 | 0.0080669 | 0.0030853 | 0.0088533 | 0.0059441 | 0.0037599 |
| Log_Returns_pypl | 0.0033916 | 0.0020608 | 0.0106548 | 0.0012561 | 0.0031184 | 0.0048155 | 0.0052534 | 0.0051145 | 0.0059441 | 0.0157667 | 0.0039809 |
| Log_Returns_s&p500 | 0.0019243 | 0.0018549 | 0.0057284 | 0.0017183 | 0.0030064 | 0.0036815 | 0.0046257 | 0.0032966 | 0.0037599 | 0.0039809 | 0.0027677 |
La matriz de correlación muestra la relación lineal entre los rendimientos logarítmicos de las acciones. Los valores van desde -1 (correlación negativa perfecta) hasta 1 (correlación positiva perfecta), con 0 indicando la ausencia de correlación.
Observamos que algunas acciones, como Log_Returns_aapl y Log_Returns_s&p500, tienen una correlación positiva fuerte (0.76), lo que sugiere que tienden a moverse en la misma dirección. Esto es consistente con el comportamiento general de las acciones tecnológicas dentro del mercado.
Por otro lado, Log_Returns_tsla muestra correlaciones más débiles con otras acciones, lo que indica que los rendimientos de Tesla podrían ser más independientes y estar menos sincronizados con el resto del mercado.
La matriz de covarianzas proporciona una medida de cómo los rendimientos de las acciones varían conjuntamente. Valores más altos sugieren que las acciones tienen rendimientos que varían de manera significativa en la misma dirección.
Los valores de la diagonal representan la varianza de cada acción, lo que es un indicador del riesgo asociado. Por ejemplo, Log_Returns_tsla tiene una varianza relativamente alta, lo que confirma su carácter volátil y riesgoso en comparación con otras acciones.
Se introducen los conceptos de rendimientos en exceso y beta. Se calculan los rendimientos en exceso de las acciones (rendimientos por encima de la tasa libre de riesgo) y se estima el coeficiente beta para cada acción mediante regresiones lineales. El coeficiente beta mide la sensibilidad de una acción al mercado.
# Cargar los datos del bono a 10 años
bono_data <- read_excel("bono_10_anos.xlsx")
# Convertir las fechas y los valores numéricos del bono
bono_data$Fecha <- as.Date(bono_data$Fecha, format = "%d.%m.%Y")
#bono_data$Ultimo <- as.numeric(gsub(",", ".", bono_data$Ultimo)) # Reemplazar comas
# Quitar los puntos como separadores de miles
bono_data$Ultimo <- as.numeric(gsub("\\.", "", bono_data$Ultimo))
# Calcular los rendimientos logarítmicos del bono
bono_log_returns <- calculate_log_returns(bono_data$Ultimo)
bono_log_returns_df <- data.frame(Date = bono_data$Fecha[-1], Bono_Log_Returns = bono_log_returns)
# Unir directamente los rendimientos logarítmicos del bono con los de las acciones
log_returns_all$Bono_Log_Returns <- bono_log_returns # Simplemente agregar la columna de rendimientos logarítmicos
# Calcular los rendimientos en exceso (rendimientos de las acciones menos rendimientos del bono)
excess_returns <- log_returns_all %>%
mutate(across(starts_with("Log_Returns_"), ~ . - Bono_Log_Returns))
# Calcular beta mediante regresión lineal
beta_results <- data.frame(Stock = character(), Beta = numeric(), stringsAsFactors = FALSE)
# Realizar la regresión lineal para cada acción
for (stock in names(excess_returns)[-1]) { # Omitimos la columna de fechas
# Seleccionar los datos válidos para la regresión
valid_data <- excess_returns %>%
select(Bono_Log_Returns, all_of(stock)) %>%
na.omit()
# Solo realizar la regresión si hay suficientes datos
if (nrow(valid_data) > 1) {
model <- lm(valid_data[[stock]] ~ valid_data$Bono_Log_Returns)
beta <- coef(model)[2] # Obtener el coeficiente beta
beta_results <- rbind(beta_results, data.frame(Stock = stock, Beta = beta))
}
}
# Asegúrate de que beta_results solo contenga caracteres limpios y números
beta_results$Stock <- as.character(beta_results$Stock)
beta_results$Beta <- as.numeric(beta_results$Beta)
# Seleccionar solo las columnas Stock y Beta de beta_results
beta_results_clean <- beta_results %>%
select(Stock, Beta)
head(log_returns_all, 10)
## Date Log_Returns_awk Log_Returns_ato Log_Returns_tsla Log_Returns_pfe
## 1 2019-12-01 -0.10316341 -0.045153062 -0.44149976 0.050481781
## 2 2020-01-01 0.09654817 0.125220982 -0.02639516 0.098213943
## 3 2020-02-01 0.03007410 0.034907946 0.24281706 0.023503297
## 4 2020-03-01 -0.01769004 -0.027230786 -0.40039454 -0.161309622
## 5 2020-04-01 -0.04268941 -0.007895644 -0.06570080 0.004322534
## 6 2020-05-01 -0.01766815 0.025667965 -0.25708582 0.145359050
## 7 2020-06-01 -0.13508039 -0.062343746 -0.28134169 -0.162865690
## 8 2020-07-01 0.04109656 0.059993043 -0.55478131 0.008549871
## 9 2020-08-01 -0.02842510 0.037594130 0.14980559 0.029152676
## 10 2020-09-01 -0.03811370 0.041964199 0.10032272 0.033889827
## Log_Returns_hpq Log_Returns_hlt Log_Returns_ba Log_Returns_aapl
## 1 -0.04537323 0.02838972 0.02324306 -0.05262574
## 2 0.02495278 0.10347587 0.14574714 0.12417828
## 3 0.18041434 0.35224140 0.60634303 0.06993018
## 4 0.10334506 -0.10389473 0.05598374 -0.14442575
## 5 0.02415212 -0.04638059 -0.03367697 -0.07894413
## 6 -0.14085743 0.07670646 -0.22854546 -0.14010485
## 7 -0.01840946 -0.02148573 0.14852912 -0.15292948
## 8 -0.10620706 -0.18572399 -0.08385238 -0.19421276
## 9 0.02912539 0.05736875 0.03892743 0.10643796
## 10 0.04629028 -0.02869336 0.13500202 0.06187352
## Log_Returns_bac Log_Returns_pypl Log_Returns_s&p500 Bono_Log_Returns
## 1 0.065074398 -0.05152901 0.001629417 -0.03464046
## 2 0.141255338 0.05319444 0.087859521 -0.12331300
## 3 0.294686661 0.12040245 0.133667769 0.03170744
## 4 -0.131074797 -0.25054817 -0.119420896 0.03122893
## 5 -0.003252035 -0.23130528 -0.044286490 0.08527419
## 6 0.015895613 -0.11688663 -0.018221381 0.02495914
## 7 -0.053670297 -0.11809547 -0.053636778 0.03898153
## 8 -0.033812222 -0.04033429 -0.067719102 -0.10721329
## 9 0.066036476 0.03545003 0.040018103 0.01134764
## 10 0.009267907 0.05691065 0.028055680 -0.08227840
print(beta_results_clean)
## Stock Beta
## valid_data$Bono_Log_Returns Log_Returns_awk -1.0057477
## valid_data$Bono_Log_Returns1 Log_Returns_ato -0.9921689
## valid_data$Bono_Log_Returns2 Log_Returns_tsla -0.9812872
## valid_data$Bono_Log_Returns3 Log_Returns_pfe -1.0159780
## valid_data$Bono_Log_Returns4 Log_Returns_hpq -0.9951783
## valid_data$Bono_Log_Returns5 Log_Returns_hlt -0.9845988
## valid_data$Bono_Log_Returns6 Log_Returns_ba -0.9950849
## valid_data$Bono_Log_Returns7 Log_Returns_aapl -0.9956418
## valid_data$Bono_Log_Returns8 Log_Returns_bac -0.9779827
## valid_data$Bono_Log_Returns9 Log_Returns_pypl -0.9665428
## valid_data$Bono_Log_Returns10 Log_Returns_s&p500 -0.9950609
## valid_data$Bono_Log_Returns11 Bono_Log_Returns 1.0000000
Para calcular el rendimiento anual esperado de cada acción utilizando el modelo CAPM, se puede usar la fórmula:
\(𝐸(𝑅𝑖)=𝑅_𝑓+𝛽_𝑖×MRP\)
donde:
# Definir la tasa libre de riesgo y la prima de riesgo de mercado
Rf <- 0.05 # 5%
MRP <- 0.072 # 7.2%
# Calcular el rendimiento esperado para cada acción usando el modelo CAPM
beta_results_clean$Expected_Return <- Rf + beta_results_clean$Beta * MRP
print(beta_results_clean)
## Stock Beta Expected_Return
## valid_data$Bono_Log_Returns Log_Returns_awk -1.0057477 -0.02241383
## valid_data$Bono_Log_Returns1 Log_Returns_ato -0.9921689 -0.02143616
## valid_data$Bono_Log_Returns2 Log_Returns_tsla -0.9812872 -0.02065268
## valid_data$Bono_Log_Returns3 Log_Returns_pfe -1.0159780 -0.02315042
## valid_data$Bono_Log_Returns4 Log_Returns_hpq -0.9951783 -0.02165284
## valid_data$Bono_Log_Returns5 Log_Returns_hlt -0.9845988 -0.02089112
## valid_data$Bono_Log_Returns6 Log_Returns_ba -0.9950849 -0.02164611
## valid_data$Bono_Log_Returns7 Log_Returns_aapl -0.9956418 -0.02168621
## valid_data$Bono_Log_Returns8 Log_Returns_bac -0.9779827 -0.02041475
## valid_data$Bono_Log_Returns9 Log_Returns_pypl -0.9665428 -0.01959108
## valid_data$Bono_Log_Returns10 Log_Returns_s&p500 -0.9950609 -0.02164439
## valid_data$Bono_Log_Returns11 Bono_Log_Returns 1.0000000 0.12200000
Tasa libre de riesgo: 5% representa el rendimiento
esperado sin asumir riesgo alguno.
Prima de riesgo de mercado: 7.2% es la compensación
adicional que los inversores esperan por asumir el riesgo de
mercado.
Beta: Medida de sensibilidad de la acción en
relación con el mercado.
Parece que los rendimientos esperados calculados también son negativos, excepto para el bono libre de riesgo. Esto sucede porque las betas obtenidas en el punto anterior son todas negativas. En el modelo CAPM, una beta negativa implica que la acción tiene una relación inversa con el mercado: cuando el mercado sube, se espera que la acción baje, y viceversa. Esto resulta en un rendimiento esperado más bajo o incluso negativo cuando se multiplica por la prima de riesgo de mercado positiva.
Portafolio Óptimo de Mínimo Riesgo (solo acciones)
Este portafolio busca minimizar la volatilidad total.
Usamos la matriz de covarianzas y optimizamos las ponderaciones para minimizar el riesgo.
Portafolio Óptimo de Máxima Razón de Sharpe (solo acciones)
Maximiza la razón de Sharpe, que es la relación entre el exceso de rendimiento del portafolio sobre la tasa libre de riesgo y su volatilidad.
Calculamos las ponderaciones que maximizan esta razón.
Portafolio Óptimo que Incluya el Activo de Libre Riesgo
Diseñamos un portafolio que incorpore el bono de riesgo cero y logre un rendimiento objetivo del 8% al mínimo riesgo posible.
Ajustamos las ponderaciones para incluir la inversión en el activo libre de riesgo.
library(quadprog)
# Matriz de covarianzas
cov_matrix <- covariance_matrix
# Vector de rendimientos esperados de las acciones
expected_returns <- beta_results_clean$Expected_Return
# Remover el rendimiento del bono del tesoro de expected_returns
expected_returns <- expected_returns[-which(beta_results_clean$Stock == "Bono_Log_Returns")]
# Configura los parámetros para la optimización cuadrática
Dmat <- cov_matrix
dvec <- rep(0, ncol(cov_matrix))
Amat <- cbind(1, diag(ncol(cov_matrix)))
bvec <- c(1, rep(0, ncol(cov_matrix)))
# Optimiza para minimizar la varianza
result <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)
weights_min_risk <- result$solution
# Cálculo de la volatilidad del portafolio
volatility_min_risk <- sqrt(t(weights_min_risk) %*% cov_matrix %*% weights_min_risk)
length(weights_min_risk)
## [1] 11
length(expected_returns)
## [1] 11
# Cálculo del rendimiento anual del portafolio
return_min_risk <- sum(weights_min_risk * expected_returns)
return_min_risk
## [1] -0.02181768
Rf <- 0.05 # Tasa libre de riesgo
# Configura la función objetivo para maximizar la razón de Sharpe
optimize_sharpe <- function(weights) {
weights <- weights / sum(weights) # Normaliza las ponderaciones
return_portfolio <- sum(weights * expected_returns)
volatility_portfolio <- sqrt(t(weights) %*% cov_matrix %*% weights)
-((return_portfolio - Rf) / volatility_portfolio) # Negativo porque minimizamos
}
# Usar optimizador
weights_sharpe <- optim(rep(1 / ncol(cov_matrix), ncol(cov_matrix)),
optimize_sharpe,
method = "L-BFGS-B",
lower = rep(0, ncol(cov_matrix)),
upper = rep(1, ncol(cov_matrix)))$par
# Calcular rendimiento y volatilidad
return_sharpe <- sum(weights_sharpe * expected_returns)
volatility_sharpe <- sqrt(t(weights_sharpe) %*% cov_matrix %*% weights_sharpe)
volatility_sharpe
## [,1]
## [1,] 0.199589
target_return <- 0.08 # 8% rendimiento objetivo
# Calcular la proporción del portafolio de solo acciones
w_a <- (target_return - Rf) / (return_sharpe - Rf)
# Calcular la volatilidad del portafolio mixto
volatility_target <- w_a * volatility_sharpe
# Calcular las ponderaciones finales (acción y bono)
weights_risk_free <- c(w_a * weights_sharpe, 1 - w_a)
weights_risk_free
## [1] 0.0000000 0.0000000 -0.4246124 0.0000000 0.0000000 0.0000000
## [7] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.4246124
library(kableExtra)
# Crear la tabla de resultados
results_table <- data.frame(
Portafolio = c("Mínimo Riesgo", "Máxima Razón de Sharpe", "Con Activo Libre de Riesgo"),
Volatilidad = c(volatility_min_risk, volatility_sharpe, volatility_target),
Rendimiento_Anual = c(return_min_risk, return_sharpe, target_return)
)
results_table
## Portafolio Volatilidad Rendimiento_Anual
## 1 Mínimo Riesgo 0.04833300 -0.02181768
## 2 Máxima Razón de Sharpe 0.19958901 -0.02065268
## 3 Con Activo Libre de Riesgo -0.08474796 0.08000000
# Mostrar la tabla
kable(results_table, caption = "Resumen de Resultados de los Portafolios") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
| Portafolio | Volatilidad | Rendimiento_Anual |
|---|---|---|
| Mínimo Riesgo | 0.048333 | -0.0218177 |
| Máxima Razón de Sharpe | 0.199589 | -0.0206527 |
| Con Activo Libre de Riesgo | -0.084748 | 0.0800000 |