Julián Mauricio Fajardo, MsC en Actuaría y Finanzas
Published
December 19, 2024
LOS RETORNOS: MEDIDA DE RIESGO PARA ACTIVOS RIESGOSOS
Los retornos son una medida de riesgo neutral que es no dimensionada, es decir no es afectada ni por la magnitud, ni por la divisa en la que se presentan. Piense en dos activos: el SPY 500 (valor que ronda los 5000 USD) y la acción colombiana de ETB que pertenece al indice ICOLCAP que en los últimos dias ha tenido un valor que ronda los 100 COP. La diferencia entre ellas no solo está en la divisa representativa, sino en la magnitud de los valores. ¿Como obtenemos una medida que solo capture los rendimientos reales del activo riesgoso, independiente de estos valores?. La respuesta está en los retornos o rendimientos.
TIPOS DE RETORNOS
RETORNOS DISCRETOS
Los retornos discretos miden la variación en el precio de un activo durante un período específico. La fórmula para el retorno discreto, está dada por: \[ R_t = \frac{P_t - P_{t-1}}{P_{t-1}} \] Donde: - \(R_t\) es el retorno discreto. - \(P_t\) es el precio al final del período. - \(P_{t-1}\) es el precio al inicio del período.
RETORNOS CONTINUOS O LOGARITMICOS
El retorno logarítmico se calcula utilizando logaritmos naturales: \[ R_t = \ln\left(\frac{P_t}{P_{t-1}}\right) \] Donde: - \(R_t\) es el retorno logarítmico. - \(P_t\) es el precio al final del período. - \(P_{t-1}\) es el precio al inicio del período.
Si consideramos \(t \geq 1\), podemos afirmar que \(P_t\) es un proceso estocástico real, al igual que resulta siendo \(R_t\). Cada uno de ellos, tiene sus ventajas y desventajas a la hora de hacer análisis de rendimientos. Eso si, los retornos logaritmos tiene ventajas significativas, respecto a los retornos discretos. Por ejemplo:
Log-normalidad: Si asumimos que los precios se distribuyen log-normalmente, los retornos logarítmicos también se distribuyen normalmente.
Sumabilidad en el tiempo: Los retornos logarítmicos son aditivos en el tiempo, lo que facilita su uso en análisis y modelización.
Estabilidad numérica: La adición de pequeñas cantidades es más robusta numéricamente que la multiplicación de números pequeños.
En resumen, los retornos logarítmicos son preferibles en muchos casos debido a sus propiedades matemáticas y su aplicabilidad en análisis financiero.
EJEMPLO 1.
Considere dos activos riesgosos, cuyo precios historicos están dados a continuación en las listas del código que sigue, el primeros en USD (dólar americano) y el segundo en JPY (yen japonés). Haga un análisis gráfico comparativo de los retornos.
Listamos los precios y calculamos manualmente los retornos discretos:
Code
act1 <-c(120,134,139,124,130,112,128,138,132,148) ## en USDact2 <-c(2340,2450,2400,2310,2390,2390,2480,2560,2500,2460) ## en JPYr1 <-diff(act1)/act1 ## diff se usa para calcular las di¿frencias de los terminos de la lista
Warning in diff(act1)/act1: longer object length is not a multiple of shorter
object length
Code
r1 <- r1[1:9] # y aqui tomo los primeros 9 terminos de la lista anteriorr2 <-diff(act2)/act2
Warning in diff(act2)/act2: longer object length is not a multiple of shorter
object length
Code
r2 <- r2[1:9]
Y ahora calculamos los retornos continuos:
Code
rc1 <-NULLfor (i in1:9){ rc1[i] <-log(act1[i+1]/act1[i])}rc2 <-NULLfor (i in1:9){ rc2[i] <-log(act2[i+1]/act2[i])}
A continuación veremos el comparativo entre los retornos discretos y los retornos continuos. Primero, los retornos promedio (\(\mu\))
Code
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
### comparacion graficaggplot(tabla1, aes(x =1:9, y = r1))+geom_line(color ="blue")+geom_line(y = rc1, color ="red")+labs(x ="Lista de retornos", y ="Retornos", title ="Comparación entre retornos discretos y continuos (activo 1)")+theme_minimal()
Aca se ve con claridad que si hay diferencia entre los dos tipos de retornos, pero estas son irrisorias, de manera tal que, podemos usar ambas para el mismo objetivo de analizar la rentabilidad de los activos. Eso si, teoricamente hablando, hay muchas mas ventajas en los retornos continuos, como ya se habia mencionado anteriormente.
Ahora veamos la comparación de los retornos logaritimicos de los dos activos:
Code
### comparacion graficaggplot(tabla1, aes(x =1:9, y = rc1))+geom_line(color ="blue")+geom_line(y = rc2, color ="red")+labs(x ="Lista de retornos", y ="Retornos", title ="Comparación entre retornos continuos (activo 1 y activo 2)")+theme_minimal()
En la gráfica podemos ver con claridad la diferencia de los comportamientos en volatilidad. El activo 2 (en yen japonés) tiene cambios menos bruscos y mas moderados.
USO DE LOS PAQUETES PARA DETERMINACIÓN DE RETORNOS
Usaremos algunos de los paquetes de R para calcular los retornos logaritmicos de manera directa y no como se hizo al principio, programando con código. En el caso del paquete “tseries” usaremos la función “returns0”
Code
library(tseries)
Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
Code
library(timeSeries)
Loading required package: timeDate
Attaching package: 'timeSeries'
The following object is masked from 'package:dplyr':
lag
The following objects are masked from 'package:graphics':
lines, points
Code
library(quantmod)
Loading required package: xts
Loading required package: zoo
Attaching package: 'zoo'
The following object is masked from 'package:timeSeries':
time<-
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. #
# #
###############################################################################
Attaching package: 'xts'
The following objects are masked from 'package:dplyr':
first, last
Loading required package: TTR
Code
rr1 <-returns0(act1) # aqui calculamos los retornos log del act 1rr1 <-as.timeSeries(rr1) # aqui lo trasnformamos en una serie de tiempoplot(rr1, col ="darkgreen", xlab ="Lista de retornos", ylab ="Retornos")
EJEMPLO 2.
Use la función get.hist.quote y la función de calculo de retornos para calcular la serie de tiempo de los retornos de la acción de Facebook y la de Netflix en las fechas desde el 1 de enero de 2023 hasta el 5 de julio de 2024.
Solución: Veamos el paso a paso de la solución para este ejemplo:
Code
### Usaremos los paquetes de R para DESCARGA DE INFO FINANCIERA DE # YAHOO FINANCEACT1 <-get.hist.quote(instrument ="META",# aqui colocas el token del instrumentoquote ='AdjClose', # establece que informacion de la base requieresstart ="2023-01-01", # fecha de inicio de la descargaend ="2024-07-05", #fecha final de la descargacompression ="d")
time series starts 2023-01-03
time series ends 2024-07-03
Code
ACT1 <-as.timeSeries(ACT1) # lo colocamos en formato de serie de tiempo convencionalACT2 <-get.hist.quote(instrument ="NFLX",# aqui colocas el token del instrumentoquote ='AdjClose', # establece que informacion de la base requieresstart ="2023-01-01", # fecha de inicio de la descargaend ="2024-07-05", #fecha final de la descargacompression ="d")
time series starts 2023-01-03
time series ends 2024-07-03
Code
ACT2 <-as.timeSeries(ACT2) # aqui lo transformamos en una serie de tiempoplot.ts(ACT1, col ="navy", main ="Precios Facebook")
Code
plot.ts(ACT2, col ="darkgreen", main ="Precios Netflix")
Code
rACT1 <-returns0(ACT1) # calculamos la serie de tiempo de los retornosrACT2 <-returns0(ACT2)plot.ts(rACT1, col ="navy", main ="Rentabilidad Diaria Facebook")
Code
plot.ts(rACT2, col ="darkgreen", main ="Rentabilidad Diaria Netflix")
USO DEL PAQUETE QUANTMOD PARA DETERMINACIÓN DE RETORNOS
El paquete “quantmod” es una alternativa muy buena para hacer análisis de los retornos de los precios de un activo riesgoso. Estas opciones tiene la ventaja de ser mas versatiles que los otros paquetes y de generar las series de tiempo en el fomato “xts” que viene de la frase “eXtended Time Series format”. Este formato es mucho mas conveniente para hacer analisis profesionales, ya que contiene dentro de cada series de tiempo, univariada o multivariada, mas detalles referentes al indicde de tiempo en la serie, como las horas, minutos segundos y hasta el huso horario del registro del precio financiero o de la transacción. Veamos como hacerlo de manera básica:
EJEMPLO 3
Use “quantmod” para analizar los retornos semanales de los años 2020 hasta lo que va corrido del 2024 del activo riesgoso Facebook.
Code
getSymbols("META", # colocamos el ticket del activo riesgoso en Yahoo!from='2020-01-01', # colocamos la fecha de inicioto='2024-12-18', # colocamos la fecha final (este argumento es opcional)periodicity ="weekly"# colocamos la periodicidad )
[1] "META"
Code
META <-Ad(META) # sacamos los precios de CIERRE AJUSTADOrMETA <-returns0(META, method ="continuous") # calculamos retornos logaritmicosggplot(rMETA, aes(x =index(rMETA), y = META.Adjusted)) +geom_line(color ="blue") +labs(x ="Fecha", y ="Retornos", title ="Serie de Tiempo de los retornos semanales de Facebook") +theme_minimal()
Allí vemos el comportamiento de la serie de tiempo de rentabilidad, y podemos evidencia caracteristicas propias de este tipo de series financieras, tales como su comportamiento estacionario, y la heterocedasticidad de los retornos.
PORTAFOLIOS
Los portafolios de inversión (o carteras de inversión) es un conjunto de al menos dos activos riesgosos o libres de riesgo, en los cuales invertimos una determinada cantidad de capital, repartiéndolo estratégicamente entre los activos que componen dicho portafolio. El objetivo de estos instrumentos de inversión es aumentar la rentabilidad y diversificar el riesgo subyacente en la inversión.
Diversificación: Uno de los principales objetivos de un portafolio es diversificar el riesgo. Al invertir en diferentes tipos de activos, sectores o regiones, se reduce la exposición a eventos adversos que puedan afectar a un solo activo. La diversificación puede ayudar a mitigar las pérdidas y suavizar la volatilidad del portafolio.
Asignación de activos: La asignación de activos se refiere a cómo se distribuyen los recursos entre diferentes clases de activos. Por ejemplo, cuánto se invierte en acciones, cuánto en bonos y cuánto en efectivo. La asignación de activos debe basarse en los objetivos del inversionista, su horizonte temporal y su tolerancia al riesgo.
Rendimiento y riesgo: Los inversionistas buscan maximizar el rendimiento de su portafolio mientras minimizan el riesgo. El rendimiento esperado está relacionado con la rentabilidad histórica y las expectativas futuras de los activos. El riesgo se mide en términos de volatilidad y la posibilidad de pérdidas.
Horizonte temporal: El horizonte temporal del inversionista influye en la elección de activos. Por ejemplo, un inversionista con un horizonte a largo plazo puede asumir más riesgo y tener una mayor exposición a acciones.
Rebalanceo: Con el tiempo, la composición del portafolio puede cambiar debido a las fluctuaciones del mercado. El rebalanceo periódico es importante para mantener la asignación de activos deseada.
Estrategias de inversión: Hay diferentes estrategias de inversión, como el enfoque pasivo (por ejemplo, replicar un índice) o el enfoque activo (seleccionar activos específicos). Algunas personas también consideran factores como la sostenibilidad y la responsabilidad social al construir su portafolio.
Dicho esto, podemos dar la definición formal y matemática de lo que es un portafolio:
PORTAFOLIO. DEFINICIÓN FORMALIZADA
Un portafolio es un n-vector \(P=(x_1,x_2,...,x_n)\) que cumple una unica condición: \[\displaystyle \sum_{k=1}^{n} x_k=1\] Generalmente los \(x_k\) representan los pesos (o los porcentajes) del total de la inversión invertidos en el k-ésimo activo. Este portafolio se le llama “full investment” o de inversión total. Notese que los \(x_k\) pueden ser, eventualmente negativos.
EL PORTAFOLIO MINIMAL:
El portafolio minimal es el portafolio más pequeño posible, que es el que se compone exactamente de dos activos riesgosos. Analizaremos este portafolio para entender, más adelante, el portafolio general, que se compone de n activos. Veremos como calcular las medidas de riesgo básicas como lo son la rentabilidad media y la volatilidad del portafolio.
Code
### función de riesgo y rentabilidad para portafolio de dos activos riesgososACT1 <-get.hist.quote('MMM', ## colcamos aqui el nombre del ticket de activoquote ='AdjClose', ## descarga precios de cierre ajustadostart ="2023-10-01", compression ="d")## promedios diarios de los precios
time series starts 2023-10-02
time series ends 2024-12-17
Code
ACT1 <-as.timeSeries(ACT1) ACT2 <-get.hist.quote("AMZN", quote ="AdjClose", start ="2023-10-01", # si se ignora "end" se toma la ultima fechacompression ="d")
time series starts 2023-10-02
time series ends 2024-12-17
Code
ACT2 <-as.timeSeries(ACT2)
Programaremos una función de R para determinar el retorno promedio y la volatilidad, según lo que ya se ha visto con anterioridad.
Code
## esta funcion es para cuando descargamos los preciosport<-function(act1, # ponga aqui la primera serie de precios act2, # ponga aqui la segunda serie de precios w # ponga aqui el porcentaje invertidi en el primer activo ){ ra1<-returns0(act1)*100 ra2<-returns0(act2)*100 mu1<-mean(ra1) mu2<-mean(ra2) mup<-w*mu1+(1-w)*mu2 s1<-sd(ra1) s2<-sd(ra2) sp<-sqrt(w^2*var(ra1)+(1-w)^2*var(ra2)+2*w*(1-w)*s1*s2*cor(ra1,ra2))return(c(mup,sp))}
Y programaremos una función en el caso de que solo se den los parámetros (rentabilidad, riesgo y correlación de los dos activos), como se verá a continuación:
Code
port2<-function(mu1,# retorno medio del primer activo mu2,# retorno medio del segundo activo sd1,# volatilidad del primer activo sd2,# volatilidad del segundo activo w, # porcentaje invertido en el primer activo cor # correlación entre los retornos ){ mup<-w*mu1+(1-w)*mu2 sp<-sqrt(w^2*sd1^2+(1-w)^2*sd2^2+2*w*(1-w)*sd1*sd2*cor)return(c(mup,sp))}
EJEMPLO 3.
Use las descargas de precios hecha para las acciones de 3M y Amazon para determinar la rentabilidad media diaria y la volatilidad diaria de los retornos del portafolio \(\pi=(0.1,0.9)\) y del portafolio uniforme.
Primero hagamos los cálculos para el portafolio \(\pi\).
Code
port(act1 = ACT1, # precios MMMact2 = ACT2, # precios AMZNw =0.1) #10% INVERTIDO EN EL PRIMER ACTIVO
[1] 0.1892415 1.6308312
Tenemos una rentabilidad positiva para el portafolio de 0.22% diario y una volatilidad, también diaria de 1.5% aproximadamente.
Luego hagamoslo para el portafolio uniforme, es decir \(\pi_2=(0.5,0.5)\).
Code
port(act1 = ACT1, # precios MMMact2 = ACT2, # precios AMZNw =0.5) #50% INVERTIDO EN EL PRIMER ACTIVO
[1] 0.1884366 1.3902994
Vemos una leve variación en los resultados obtenidos. En promedio, este portafolio será un poco menos rentable que el anterior y así mismo, será menos volátil.
EJEMPLO 4
Use el portafolio anterior para hacer un análisis de rentabilidades y riesgo, confrontando los resultados mediante una gráfica bidimensional.
Code
p <-seq(-0.3,1,by=0.1)r <-port(act1 = ACT1, act2 = ACT2, w = p)
Warning in w^2 * var(ra1): Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Warning in (1 - w)^2 * var(ra2): Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Warning in 2 * w * (1 - w) * s1 * s2 * cor(ra1, ra2): Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Code
n <-length(r)mup <- r[1:(n/2)]sp <- r[((n/2)+1):n]plot(sp,mup, col ="navy", main ="Grafico Riesgo-Retorno", xlab ="Riesgo", ylab ="Retorno")lines(sp,mup, col ="blue")
EJEMPLO 5.
Considere un portafolio de dos activos riesgosos. Para éste tenemos la siguiente información: \(\mu_1=0.098, \mu_2=0.057\) en sus rentabilidades. \(\sigma_1=0.15, \sigma_2=0.082\) en sus volatilidades. La correlación entre los activos del portafolio es \(\rho=0.2\). Suponga que se decide invertir 70% en el primer activo. Determine la rentabilidad y la volatilidad de este portafolio.
Usaremos la función ya programada port2. Lo único que hay que hacer es incluir los parámetros del problema de manera ordenada en el entorno:
Code
port2(mu1=0.098, mu2 =0.057, sd1=0.15, sd2 =0.082, w =0.7, cor =0.2)
[1] 0.0857000 0.1125316
En donde verificamos lo hecho con proceso analítico.