Aplicación 1.3: Datos financieros

Propiedades estadísticas básicas de los activos bursátiles

El objetivo de esta aplicación es familiarizarse con la descarga, manejo y visualización de datos bursátiles procedentes de la plataforma Yahoo!Finanzas, así como entender las propiedades estadísticas básicas de las series temporales asociadas.

Se usará el enfoque tidyverse para este tipo de datos, por lo que esta aplicación puede entenderse como un “análisis financiero ordenado” (tidy finance). Para una exposición completa de todos los métodos y modelos empíricos recientes de economía financiera puede consultarse la página https://www.tidy-finance.org/ y los libros online (usando R o Python) asociados a la misma.

Code
# Lectura de librerías
library(tidyverse)
library(tidyquant)
library(scales)
#
# Descarga de los datos de un activo bursátil desde Yahoo!Finanzas
#
# Para acceder a los datos diarios del precio de las acciones 
# se usa el comando tq_get de la librería tidyquant.
# Solicitaremos los datos del Banco Santander, S.A. (ticker: SAN.MC)
# desde el año 2000:
# https://es.finance.yahoo.com/quote/SAN.MC?p=SAN.MC&.tsrc=fin-srch
#
pSAN <- tq_get("SAN.MC",
  get = "stock.prices",
  from = "2000-01-01",
  to = "2023-12-31"
)
head(pSAN)
# A tibble: 6 × 8
  symbol date        open  high   low close  volume adjusted
  <chr>  <date>     <dbl> <dbl> <dbl> <dbl>   <dbl>    <dbl>
1 SAN.MC 2000-01-03  9.95  9.99  9.74  9.85 8797337     2.71
2 SAN.MC 2000-01-04  9.73  9.78  9.53  9.62 8811013     2.64
3 SAN.MC 2000-01-05  9.43  9.56  9.30  9.38 9333517     2.58
4 SAN.MC 2000-01-06  9.38  9.38  9.38  9.38       0     2.58
5 SAN.MC 2000-01-07  9.45  9.82  9.44  9.80 9603132     2.69
6 SAN.MC 2000-01-10  9.88  9.88  9.62  9.71 6747710     2.67
Code
tail(pSAN)
# A tibble: 6 × 8
  symbol date        open  high   low close   volume adjusted
  <chr>  <date>     <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>
1 SAN.MC 2023-12-20  3.80  3.81  3.74  3.79 27342468     3.63
2 SAN.MC 2023-12-21  3.79  3.81  3.76  3.79 15816650     3.64
3 SAN.MC 2023-12-22  3.79  3.83  3.79  3.81 20983223     3.65
4 SAN.MC 2023-12-27  3.79  3.82  3.76  3.81 33514637     3.65
5 SAN.MC 2023-12-28  3.81  3.82  3.78  3.79 17505114     3.63
6 SAN.MC 2023-12-29  3.79  3.80  3.77  3.78 15848727     3.62
Code
# Gráfica de serie temporal: evolución temporal de los precios
pSAN %>%
  ggplot(aes(x = date, y = adjusted)) +
  geom_line() +
  labs(
    x = NULL,
    y = NULL,
    title = "Precio de las acciones del Banco Santander (EUR)"
  )

Code
# Cálculo de los rendimientos netos diarios (returns)
rSAN <- pSAN %>%
  arrange(date) %>%
  mutate(ret = 100*(adjusted / lag(adjusted) - 1)) %>%
  select(symbol, date, ret)
head(rSAN)
# A tibble: 6 × 3
  symbol date          ret
  <chr>  <date>      <dbl>
1 SAN.MC 2000-01-03 NA    
2 SAN.MC 2000-01-04 -2.37 
3 SAN.MC 2000-01-05 -2.43 
4 SAN.MC 2000-01-06  0    
5 SAN.MC 2000-01-07  4.43 
6 SAN.MC 2000-01-10 -0.883
Code
tail(rSAN)
# A tibble: 6 × 3
  symbol date           ret
  <chr>  <date>       <dbl>
1 SAN.MC 2023-12-20 -0.0923
2 SAN.MC 2023-12-21  0.106 
3 SAN.MC 2023-12-22  0.395 
4 SAN.MC 2023-12-27  0.0525
5 SAN.MC 2023-12-28 -0.591 
6 SAN.MC 2023-12-29 -0.211 
Code
# Eliminación de datos perdidos (missing data)
rSAN <- rSAN %>%
  drop_na(ret)
# Evolución temporal de las rentabilidades diarias
rSAN %>%
  ggplot(aes(x = date, y = ret)) +
  geom_line() +
  labs(
    x = NULL,
    y = NULL,
    title = "Rendimiento de las acciones del Banco Santander (%)"
  )

Code
# Distribución de los rendimientos diarios 
# (detección de asimetrías y exceso de curtosis)
q5 <- quantile(rSAN %>% pull(ret), probs = 0.05)
q95 <- quantile(rSAN %>% pull(ret), probs = 0.95)
rSAN %>%
  ggplot(aes(x = ret)) +
  geom_histogram(bins = 100) +
  geom_vline(aes(xintercept = q5), linetype = "dashed") +
  geom_vline(aes(xintercept = q95), linetype = "dashed") +
  labs(
    x = NULL,
    y = NULL,
    title = "Distribución de los rendimientos del Banco Santander"
  ) +
  scale_x_continuous(labels = percent)

Code
# Estadística resumen global
rSAN %>%
  summarize(across(
    ret,
    list(
      media = mean,
      desv_típica = sd,
      mínimo = min,
      máximo = max
    )
  ))
# A tibble: 1 × 4
  ret_media ret_desv_típica ret_mínimo ret_máximo
      <dbl>           <dbl>      <dbl>      <dbl>
1    0.0290            2.22      -19.9       23.2
Code
# Estadística resumen por años
rSAN %>%
  group_by(year = year(date)) %>%
  summarize(across(
    ret,
    list(
      media = mean,
      desv_típica = sd,
      mínimo = min,
      máximo = max
    ),
    .names = "{.fn}"
  )) %>%
  print(n = Inf)
# A tibble: 24 × 5
    year    media desv_típica mínimo máximo
   <dbl>    <dbl>       <dbl>  <dbl>  <dbl>
 1  2000  0.0424        2.30   -6.86   9.09
 2  2001 -0.0279        2.52   -9.88  10.1 
 3  2002 -0.0757        3.13  -10.7    9.43
 4  2003  0.176         2.09   -5.58   8.99
 5  2004  0.0135        1.15   -4.42   3.57
 6  2005  0.0948        0.885  -3.13   3.56
 7  2006  0.113         1.10   -3.48   3.45
 8  2007  0.0419        1.32   -4.40   4.15
 9  2008 -0.200         3.41  -11.9   14.3 
10  2009  0.283         2.91   -8.16  13.4 
11  2010 -0.0833        2.86   -9.40  23.2 
12  2011 -0.0516        2.39   -8.33   9.56
13  2012  0.0911        2.41   -7.32  10.7 
14  2013  0.0795        1.64   -5.70   5.16
15  2014  0.0704        1.41   -4.03   3.78
16  2015 -0.121         2.06  -14.1    5.93
17  2016  0.0917        2.78  -19.9    7.58
18  2017  0.0698        1.40   -3.83   5.82
19  2018 -0.109         1.37   -5.43   3.73
20  2019  0.00873       1.54   -4.29   4.29
21  2020 -0.0676        3.63  -16.9   19.2 
22  2021  0.0852        1.92   -8.92   6.87
23  2022  0.0216        2.21   -7.69   7.25
24  2023  0.150         1.79   -7.35   5.73
Code
# Lectura de librerías
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from plotnine import *
from datetime import datetime
from mizani.formatters import percent_format
import yfinance as yf
import warnings
warnings.filterwarnings("ignore")
#
# Descarga de los datos diarios del precio de las acciones del Santander
#
# Creación del ticker del Banco Santander
SAN = yf.Ticker("SAN.MC")
# Lectura de los datos para el período seleccionado
pSAN = yf.download("SAN.MC", start="2000-01-01", end="2023-12-31")

[*********************100%%**********************]  1 of 1 completed
Code
print(pSAN)
                Open      High       Low     Close  Adj Close    Volume
Date                                                                   
2000-01-03  9.953261  9.987881  9.736886  9.849401   2.705216   8797337
2000-01-04  9.728231  9.780161  9.529166  9.615716   2.641033   8811013
2000-01-05  9.433961  9.555131  9.304136  9.382031   2.576851   9333517
2000-01-06  9.382031  9.382031  9.382031  9.382031   2.576851         0
2000-01-07  9.451271  9.823436  9.442616  9.797471   2.690955   9603132
...              ...       ...       ...       ...        ...       ...
2023-12-21  3.787500  3.808000  3.759000  3.793000   3.635945  15816650
2023-12-22  3.790500  3.827000  3.785000  3.808000   3.650324  20983223
2023-12-27  3.787000  3.817000  3.759500  3.810000   3.652241  33514637
2023-12-28  3.814000  3.817500  3.775000  3.787500   3.630672  17505114
2023-12-29  3.785500  3.802000  3.772000  3.779500   3.623004  15848727

[6165 rows x 6 columns]
Code
pSAN = (pSAN.reset_index())
pSAN.head()
        Date      Open      High       Low     Close  Adj Close   Volume
0 2000-01-03  9.953261  9.987881  9.736886  9.849401   2.705216  8797337
1 2000-01-04  9.728231  9.780161  9.529166  9.615716   2.641033  8811013
2 2000-01-05  9.433961  9.555131  9.304136  9.382031   2.576851  9333517
3 2000-01-06  9.382031  9.382031  9.382031  9.382031   2.576851        0
4 2000-01-07  9.451271  9.823436  9.442616  9.797471   2.690955  9603132
Code
pSAN.tail()
           Date    Open    High     Low   Close  Adj Close    Volume
6160 2023-12-21  3.7875  3.8080  3.7590  3.7930   3.635945  15816650
6161 2023-12-22  3.7905  3.8270  3.7850  3.8080   3.650324  20983223
6162 2023-12-27  3.7870  3.8170  3.7595  3.8100   3.652241  33514637
6163 2023-12-28  3.8140  3.8175  3.7750  3.7875   3.630672  17505114
6164 2023-12-29  3.7855  3.8020  3.7720  3.7795   3.623004  15848727
Code
# Gráfica de serie temporal: evolución temporal de los precios
(
  ggplot(pSAN, aes(y="Adj Close", x="Date")) 
  + geom_line() 
  + labs(x="Día", y="", title="Precio de las acciones del Banco Santander (EUR)")
)
<Figure Size: (640 x 480)>

Code
# Cálculo de los rendimientos netos diarios
def ret(x):
    x_change = 100*(x/x.shift(1)-1)
    return x_change
pSAN['ret'] = ret(pSAN['Adj Close'])
pSAN['ret']
0            NaN
1      -2.372573
2      -2.430178
3       0.000000
4       4.428051
          ...   
6160    0.105572
6161    0.395469
6162    0.052513
6163   -0.590556
6164   -0.211214
Name: ret, Length: 6165, dtype: float64
Code
# Eliminación de datos perdidos (missing data)
pSAN = pSAN.dropna()
# Evolución temporal de las rentabilidades diarias
(
  ggplot(pSAN, aes(y="ret", x="Date"))
 + geom_line()
 + labs(x="Día", y="", 
 title="Rendimiento de las acciones del Banco Santander (%)")
)
<Figure Size: (640 x 480)>

Code
# Distribución de los rendimientos diarios 
# (detección de asimetrías y exceso de curtosis)
q5 = pSAN["ret"].quantile(0.05)
q95 = pSAN["ret"].quantile(0.95)
(
  ggplot(pSAN, aes(x="ret"))
 + geom_histogram(bins=100)
 + geom_vline(aes(xintercept=q5), linetype="dashed")
 + geom_vline(aes(xintercept=q95), linetype="dashed")
 + labs(x=None, y=None, 
 title="Distribución de los rendimientos del Banco Santander")
 + scale_x_continuous(labels=percent_format())
)
<Figure Size: (640 x 480)>

Code
# Estadística resumen global
est_res = pSAN['ret'].agg({
    'media': 'mean',
    'desv_típica': 'std',
    'mínimo': 'min',
    'máximo': 'max'
})
est_res.round(3)
media           0.029
desv_típica     2.221
mínimo        -19.886
máximo         23.217
Name: ret, dtype: float64
Code
# Estadística resumen por años
pSAN['year'] = pSAN["Date"].dt.year
est_anual = pSAN.groupby('year').agg({'ret': ['mean', 'std', 'min', 'max']})
est_anual.round(3)
        ret                       
       mean    std     min     max
year                              
2000  0.042  2.295  -6.863   9.085
2001 -0.028  2.525  -9.884  10.101
2002 -0.076  3.127 -10.743   9.434
2003  0.176  2.085  -5.581   8.989
2004  0.013  1.155  -4.417   3.571
2005  0.095  0.885  -3.128   3.565
2006  0.113  1.097  -3.480   3.455
2007  0.042  1.318  -4.396   4.151
2008 -0.200  3.410 -11.942  14.328
2009  0.283  2.907  -8.163  13.391
2010 -0.083  2.859  -9.403  23.217
2011 -0.052  2.393  -8.332   9.560
2012  0.091  2.409  -7.321  10.675
2013  0.079  1.640  -5.700   5.165
2014  0.070  1.412  -4.029   3.777
2015 -0.121  2.064 -14.090   5.932
2016  0.092  2.779 -19.886   7.582
2017  0.070  1.402  -3.828   5.820
2018 -0.100  1.376  -5.432   3.729
2019  0.009  1.541  -4.286   4.290
2020 -0.068  3.633 -16.858  19.222
2021  0.085  1.923  -8.918   6.872
2022  0.022  2.214  -7.691   7.249
2023  0.150  1.793  -7.355   5.726

Comportamiento temporal de los activos bursátiles

En esta aplicación se analizará gráficamente la relación existente entre las variables financieras \(rSAN_t\) y \(rIBEX_t\), donde \(rSAN\) es el rendimiento (no el precio) de las acciones del Banco Santander y \(rIBEX\) es el rendimiento del índice bursátil Ibex 35 (https://en.wikipedia.org/wiki/IBEX_35).

Durante la aplicación, se tendrán que ejecutar comandos específicos de filtrado, selección, transformación, fusión de ficheros, agrupación, ordenación y resumen, todas ellos asociados a operaciones básicas en la gestión de datos.

Code
# Comportamiento Banco Santander/Ibex 35
# Lectura de librerías
library(tidyverse)
library(lubridate)
library(scales)
# Lectura de datos de las 30 mayores empresas del Ibex 35
datos_acciones <- read_csv("data/IBEX_top30.csv")
head(datos_acciones)
# A tibble: 6 × 10
   ...1 symbol date        open  high   low close volume adjusted company_name  
  <dbl> <chr>  <date>     <dbl> <dbl> <dbl> <dbl>  <dbl>    <dbl> <chr>         
1     1 RED.MC 2000-01-03  1.52  1.54  1.48  1.49 775472    0.510 Redeia Corpor…
2     2 RED.MC 2000-01-04  1.50  1.50  1.41  1.41 786100    0.484 Redeia Corpor…
3     3 RED.MC 2000-01-05  1.41  1.49  1.40  1.43 702520    0.490 Redeia Corpor…
4     4 RED.MC 2000-01-07  1.48  1.51  1.44  1.5  319884    0.514 Redeia Corpor…
5     5 RED.MC 2000-01-10  1.51  1.52  1.50  1.5  256932    0.514 Redeia Corpor…
6     6 RED.MC 2000-01-11  1.5   1.52  1.5   1.5  290704    0.514 Redeia Corpor…
Code
tail(datos_acciones)
# A tibble: 6 × 10
    ...1 symbol date        open  high   low close  volume adjusted company_name
   <dbl> <chr>  <date>     <dbl> <dbl> <dbl> <dbl>   <dbl>    <dbl> <chr>       
1 143543 GRF.MC 2023-12-20  14.5  14.7  14.4  14.5 1160818     14.5 Grifols, S.…
2 143544 GRF.MC 2023-12-21  14.3  14.4  14.2  14.3  648586     14.3 Grifols, S.…
3 143545 GRF.MC 2023-12-22  14.2  14.4  14.1  14.3  614762     14.3 Grifols, S.…
4 143546 GRF.MC 2023-12-27  14.3  14.5  14.1  14.2  877076     14.2 Grifols, S.…
5 143547 GRF.MC 2023-12-28  14.2  14.2  14.1  14.2  665813     14.2 Grifols, S.…
6 143548 GRF.MC 2023-12-29  14.2  15.9  14.2  15.5 4301699     15.5 Grifols, S.…
Code
# filter
SAN <- datos_acciones %>% filter(symbol == "SAN.MC")
# select
pSAN <- SAN %>% select(date, adjusted)
head(pSAN)
# A tibble: 6 × 2
  date       adjusted
  <date>        <dbl>
1 2000-01-03     2.60
2 2000-01-04     2.54
3 2000-01-05     2.48
4 2000-01-06     2.48
5 2000-01-07     2.59
6 2000-01-10     2.57
Code
tail(pSAN)
# A tibble: 6 × 2
  date       adjusted
  <date>        <dbl>
1 2023-12-20     3.79
2 2023-12-21     3.79
3 2023-12-22     3.81
4 2023-12-27     3.81
5 2023-12-28     3.79
6 2023-12-29     3.78
Code
# Lectura de datos del índice Ibex 35 
IBEX <- read_csv("data/IBEX.csv")
# select
pIBEX <- IBEX %>% select(date,adjusted)
head(pIBEX)
# A tibble: 6 × 2
  date       adjusted
  <date>        <dbl>
1 2000-01-03   11610.
2 2000-01-04   11207.
3 2000-01-05   10863.
4 2000-01-07   11102.
5 2000-01-10   11173.
6 2000-01-11   11012.
Code
tail(pIBEX)
# A tibble: 6 × 2
  date       adjusted
  <date>        <dbl>
1 2023-12-20   10101 
2 2023-12-21   10104.
3 2023-12-22   10112.
4 2023-12-27   10122.
5 2023-12-28   10086.
6 2023-12-29   10102.
Code
# join
IBEX_SAN <- inner_join(pIBEX, pSAN, by = "date") %>% 
  rename(pIBEX = adjusted.x, pSAN = adjusted.y)
# mutate
IBEX_SAN <- IBEX_SAN %>% 
  mutate(year = year(date), month = month(date))
IBEX_SAN  <- IBEX_SAN %>% 
  mutate(rSAN = 100*(pSAN / lag(pSAN) - 1), 
         rIBEX = 100*(pIBEX / lag(pIBEX) - 1))
head(IBEX_SAN)
# A tibble: 6 × 7
  date        pIBEX  pSAN  year month   rSAN  rIBEX
  <date>      <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>
1 2000-01-03 11610.  2.60  2000     1 NA     NA    
2 2000-01-04 11207.  2.54  2000     1 -2.37  -3.47 
3 2000-01-05 10863.  2.48  2000     1 -2.43  -3.07 
4 2000-01-07 11102.  2.59  2000     1  4.43   2.20 
5 2000-01-10 11173.  2.57  2000     1 -0.883  0.639
6 2000-01-11 11012.  2.48  2000     1 -3.39  -1.44 
Code
tail(IBEX_SAN)
# A tibble: 6 × 7
  date        pIBEX  pSAN  year month    rSAN   rIBEX
  <date>      <dbl> <dbl> <dbl> <dbl>   <dbl>   <dbl>
1 2023-12-20 10101   3.79  2023    12 -0.0923 -0.0564
2 2023-12-21 10104.  3.79  2023    12  0.106   0.0327
3 2023-12-22 10112.  3.81  2023    12  0.395   0.0752
4 2023-12-27 10122.  3.81  2023    12  0.0525  0.0979
5 2023-12-28 10086.  3.79  2023    12 -0.591  -0.352 
6 2023-12-29 10102.  3.78  2023    12 -0.211   0.158 
Code
# Eliminación de datos perdidos (missing data)
IBEX_SAN <- IBEX_SAN |> drop_na()
# ggplot
p1 <- ggplot(data = IBEX_SAN, aes(x = date)) +
  geom_line(aes(y = rSAN), linewidth = 0.5) +
  labs(y = "Rendimiento de las acciones de Banco Santander", 
       x = "Fecha (día)")
p1

Code
p2 <- ggplot(data = IBEX_SAN, aes(x = date)) +
  geom_line(aes(y = rIBEX), linewidth = 0.5) +
  labs(y = "Rendimiento del Ibex 35", 
       x = "Fecha (día)")
p2

Code
p3 <- ggplot(IBEX_SAN, aes(x = rIBEX, y = rSAN)) + 
               geom_point() +  
               stat_smooth(method = lm, se = FALSE) +  
               labs(x = "Rendimiento Ibex 35",
                    y = "Rendimiento acciones Banco Santander")
p3

Code
# Comportamiento Banco Santander/Ibex 35
# Lectura de librerías
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from plotnine import *
from datetime import datetime
# Lectura de datos 30 mayores empresas del Ibex 35
datos_acciones = pd.read_csv('data/IBEX_top30.csv')
datos_acciones.head()
   Unnamed: 0  symbol        date  ...  volume  adjusted              company_name
0           1  RED.MC  2000-01-03  ...  775472  0.510131  Redeia Corporación, S.A.
1           2  RED.MC  2000-01-04  ...  786100  0.483597  Redeia Corporación, S.A.
2           3  RED.MC  2000-01-05  ...  702520  0.490445  Redeia Corporación, S.A.
3           4  RED.MC  2000-01-07  ...  319884  0.513555  Redeia Corporación, S.A.
4           5  RED.MC  2000-01-10  ...  256932  0.513555  Redeia Corporación, S.A.

[5 rows x 10 columns]
Code
datos_acciones.tail()
        Unnamed: 0  symbol        date  ...   volume  adjusted   company_name
143543      143544  GRF.MC  2023-12-21  ...   648586    14.345  Grifols, S.A.
143544      143545  GRF.MC  2023-12-22  ...   614762    14.280  Grifols, S.A.
143545      143546  GRF.MC  2023-12-27  ...   877076    14.180  Grifols, S.A.
143546      143547  GRF.MC  2023-12-28  ...   665813    14.230  Grifols, S.A.
143547      143548  GRF.MC  2023-12-29  ...  4301699    15.455  Grifols, S.A.

[5 rows x 10 columns]
Code
# filter
SAN = datos_acciones[datos_acciones['symbol']=='SAN.MC']
# select
pSAN = SAN[['date','adjusted']]
pSAN['date'] = pd.to_datetime(pSAN['date'])
pSAN.head()
            date  adjusted
49011 2000-01-03  2.603297
49012 2000-01-04  2.541533
49013 2000-01-05  2.479767
49014 2000-01-06  2.479767
49015 2000-01-07  2.589572
Code
pSAN.tail()
            date  adjusted
55171 2023-12-21    3.7930
55172 2023-12-22    3.8080
55173 2023-12-27    3.8100
55174 2023-12-28    3.7875
55175 2023-12-29    3.7795
Code
# Lectura de datos del índice Ibex 35
IBEX = pd.read_csv('data/IBEX.csv')
# select
pIBEX = IBEX[['date','adjusted']]
# mutate
pIBEX['date'] = pd.to_datetime(pIBEX['date'])
pIBEX.head()
        date      adjusted
0 2000-01-03  11609.988281
1 2000-01-04  11206.587891
2 2000-01-05  10863.088867
3 2000-01-07  11102.388672
4 2000-01-10  11173.288086
Code
pIBEX.tail()
           date      adjusted
6097 2023-12-21  10104.299805
6098 2023-12-22  10111.900391
6099 2023-12-27  10121.799805
6100 2023-12-28  10086.200195
6101 2023-12-29  10102.099609
Code
# merge (join)
IBEX_SAN = pd.merge(pIBEX, pSAN, how='inner', on='date').\
    rename(columns={'adjusted_x':'pIBEX','adjusted_y':'pSAN'})
# time
IBEX_SAN['year'] = IBEX_SAN['date'].dt.year
IBEX_SAN['month'] = IBEX_SAN['date'].dt.month
# Cálculo de los rendimientos netos diarios
IBEX_SAN['rSAN'] = 100*(IBEX_SAN['pSAN']/IBEX_SAN['pSAN'].shift(1)-1)
IBEX_SAN['rIBEX'] = 100*(IBEX_SAN['pIBEX']/IBEX_SAN['pIBEX'].shift(1)-1)
IBEX_SAN.head()
        date         pIBEX      pSAN  year  month      rSAN     rIBEX
0 2000-01-03  11609.988281  2.603297  2000      1       NaN       NaN
1 2000-01-04  11206.587891  2.541533  2000      1 -2.372548 -3.474598
2 2000-01-05  10863.088867  2.479767  2000      1 -2.430243 -3.065153
3 2000-01-07  11102.388672  2.589572  2000      1  4.428031  2.202871
4 2000-01-10  11173.288086  2.566696  2000      1 -0.883399  0.638596
Code
IBEX_SAN.tail()
           date         pIBEX    pSAN  year  month      rSAN     rIBEX
6096 2023-12-21  10104.299805  3.7930  2023     12  0.105567  0.032668
6097 2023-12-22  10111.900391  3.8080  2023     12  0.395468  0.075221
6098 2023-12-27  10121.799805  3.8100  2023     12  0.052517  0.097899
6099 2023-12-28  10086.200195  3.7875  2023     12 -0.590552 -0.351712
6100 2023-12-29  10102.099609  3.7795  2023     12 -0.211218  0.157635
Code
# Eliminación de datos perdidos (missing data)
IBEX_SAN = IBEX_SAN.dropna()
# ggplot (plotnine)
(ggplot(IBEX_SAN) + geom_line(aes('date','rSAN'), size = 0.5) + 
labs(y = "Rendimiento de las acciones de Banco Santander", x = "Fecha (día)") + 
theme_bw())
<Figure Size: (640 x 480)>

Code
(ggplot(IBEX_SAN) + geom_line(aes('date','rIBEX'), size = 0.5) + 
labs(y = "Rendimiento del Ibex 35", x = "Fecha (día)") + 
theme_bw())
<Figure Size: (640 x 480)>

Code
(ggplot(IBEX_SAN, aes('rIBEX','rSAN')) + geom_point() + 
geom_smooth(method = 'lm', se = False, color = "blue") + 
labs(x="Rendimiento Ibex 35", y="Rendimiento acciones Banco Santander") + 
theme_bw())
<Figure Size: (640 x 480)>