SUMMARY:

Este es un repaso de la sesión 5, donde realizaremos modelos Multivariados de Varianza Condicionada (MGARCH) y Filtros de Kalman, para modelar la media móvil a través del tiempo.

MOTIVACIÓN:

A continuación observaremos los distintos portafolios, una combinación de retornos con niveles de riesgos distintos, siendo el portafolio óptimo el punto tangente entre la línea de mercado de capital y la frontera eficiente, punto en el cual se maximiza el retorno esperado por unidad de riesgo.

Asimismo, una vez identificado nuestro portafolio óptimo, debemos elegir entre los múltiples set de portafolios y activos libres de riesgo (asset allocation), tal como se visualiza en la figura 2.

1. PAQUETES en R

A continuación realizaremos una aplicación práctica de la teoría de portafolios; para ello utilizaremos los paquete “fPortfolio”, el cual nos ayudará en el análisis de portafolios y su correspondiente análisis gráfico, y “lpsolve”, el cual nos ayudará con la optimización.

# Instalamos y llamamos a los paquetes

install.packages("fPortfolio")
install.packages("lpsolve")

library("fPortfolio")
library("lpsolve")

2. APLICACIÓN

Una vez instalado los paquetes, nos plantearemos el siguiente reto:

Nota:

# Base de datos

names(SMALLCAP)     # Base del precio de las acciones
##  [1] "MODI"   "MGF"    "MEE"    "FCEL"   "OII"    "SEB"    "RML"   
##  [8] "AEOS"   "BRC"    "CTC"    "TNL"    "IBC"    "KWD"    "TOPP"  
## [15] "RARE"   "HAR"    "BKE"    "GG"     "GYMB"   "KRON"   "MARKET"
## [22] "T90"
Data = SMALLCAP.RET # Base de rentabilidades de las acciones

# Seleccionamos los activos a analizar

Data = Data[,c("BKE", "FCEL", "GG", "OII", "SEB")]

head(Data)
## GMT
##                    BKE        FCEL          GG         OII         SEB
## 1997-01-31  0.11500000 -0.18644068 -0.11764706  0.07874016 -0.12734963
## 1997-02-28 -0.09417041 -0.01041667  0.06666667 -0.07299270  0.10285407
## 1997-03-31  0.05940594 -0.15789473  0.03125000 -0.01574803 -0.02246094
## 1997-04-30  0.10280374 -0.01250000 -0.12121213 -0.07200000 -0.01000000
## 1997-05-30  0.44067797  0.00000000  0.03448276  0.17241380  0.12323232
## 1997-06-30  0.08235294 -0.07594936 -0.05000000  0.08823530 -0.04946043

A continuación guardaremos la matriz de varianzas y covarianzas, para ello utilizaremos la función “covEstimator”:

# Matriz Var - Cor

matcovData = covEstimator(Data)

matcovData
## $mu
##        BKE       FCEL         GG        OII        SEB 
## 0.02749712 0.06882631 0.02198486 0.01845474 0.01017200 
## 
## $Sigma
##               BKE         FCEL           GG          OII          SEB
## BKE   0.022526377 -0.002610330 -0.003495562 -0.001049804  0.007319867
## FCEL -0.002610330  0.073207122  0.007283986  0.011208017 -0.005218380
## GG   -0.003495562  0.007283986  0.036070945  0.012605685 -0.001660664
## OII  -0.001049804  0.011208017  0.012605685  0.026924697 -0.004016589
## SEB   0.007319867 -0.005218380 -0.001660664 -0.004016589  0.015560084

Como se puede observar, la función “covEstimator”, nos arroja la matriz de varianzas y covarianzas (Sigma), y los valores promedios de la rentabilidad de cada acción (mu).

Ahora crearemos la especificación:

# Especificación de restriccion de media varianza

especificacion_corta = portfolioSpec() 

setSolver(especificacion_corta) = "solveRshortExact"

Y finalmente creamos la frontera eficiente:

# Frontera eficiente
# Restricción (constraints="Short"): 
# Esto quiere decir que podemos vender los activos, esto se refleja en el signo negativo 
# de Portfolio Weights:

shortFrontier = portfolioFrontier(Data,spec=especificacion_corta,constraints="Short")

# Por default reporta los portafolio: 1,13,25,37,50

shortFrontier
## 
## Title:
##  MV Portfolio Frontier 
##  Estimator:         covEstimator 
##  Solver:            solveRshortExact 
##  Optimize:          minRisk 
##  Constraints:       Short 
##  Portfolio Points:  5 of 50 
## 
## Portfolio Weights:
##        BKE    FCEL      GG     OII     SEB
## 1   0.0356 -0.0772  0.0982  0.3320  0.6113
## 13  0.2297  0.1270  0.1273  0.1729  0.3432
## 25  0.4238  0.3312  0.1563  0.0137  0.0750
## 37  0.6178  0.5354  0.1854 -0.1454 -0.1932
## 50  0.8281  0.7566  0.2169 -0.3178 -0.4838
## 
## Covariance Risk Budgets:
##        BKE    FCEL      GG     OII     SEB
## 1   0.0197  0.0400  0.0682  0.2608  0.6113
## 13  0.2374  0.1906  0.1236  0.1610  0.2874
## 25  0.2846  0.6167  0.0802  0.0056  0.0129
## 37  0.2351  0.7357  0.0460 -0.0237  0.0069
## 50  0.1958  0.7566  0.0292 -0.0221  0.0405
## 
## Target Returns and Risks:
##      mean    Cov   CVaR    VaR
## 1  0.0102 0.0932 0.1784 0.1657
## 13 0.0245 0.0807 0.1571 0.1161
## 25 0.0389 0.1136 0.2198 0.1393
## 37 0.0533 0.1670 0.3123 0.2325
## 50 0.0688 0.2319 0.4231 0.3658
## 
## Description:
##  Wed May 20 01:00:41 2020 by user: User

A continuación graficaremos la frontera eficiente:

frontera = shortFrontier

frontierPlot(frontera,frontier = "both",risk="Sigma",type="l",col = c("blue", "grey"))

Como se puede observar, la línea azul es la frontera eficiente, mientras que la gris es la frontera ineficiente.

Finalmente, podemos graficar también otros portafolios, como el de mínima varianza y otros que se encuentran dentro de la frontera:

# Frontera eficiente
frontierPlot(frontera,frontier = "both",risk="Sigma",type="l",col = c("blue", "grey"))

# Portafolio de mínima varianza
minvariancePoints(frontera,pch=19,col="red")

# Otros portafolios
singleAssetPoints(frontera,risk="Sigma",pch=19,cex=1.5,col=topo.colors(6))

3. APLICACIÓN REAL

Construir un portafolio y graficar la frontera eficiente y de mínima varianza.

Nota:

Para realizar esta aplicación requerimos del paquete “tseries”, el cual nos proveerá de la data.

install.packages("tseries")
library("tseries")

Luego de ello procedemos con la descarga de la data:

# Construimos la base de datos

sp500   = get.hist.quote(instrument="^gspc" ,start = "2010-01-01", quote="Close")
## time series starts 2010-01-04
## time series ends   2020-05-18
netflix = get.hist.quote(instrument="NFLX"  ,start = "2010-01-01", quote="Close")
## time series starts 2010-01-04
## time series ends   2020-05-18
renault = get.hist.quote(instrument="RNO.PA",start = "2010-01-01", quote="Close")
## time series starts 2010-01-04
## time series ends   2020-05-18
klm     = get.hist.quote(instrument="AF.PA" ,start = "2010-01-01", quote="Close")
## time series starts 2010-01-04
## time series ends   2020-05-18
# Unimos las bases con merge

portafolio4=merge(sp500,netflix,renault,klm, all=F)


# Renombraremos las variables con "plyr"

library("plyr")

portafolio4=rename(portafolio4,c(Close.sp500="sp500",Close.netflix="netflix",
                                 Close.renault="renault",Close.klm="klm"))


# Finalmente graficamos

plot(portafolio4, col=rainbow(4))

Asimismo construimos los retornos del portafolio:

# Unimos las bases con merge

log_portafolio=diff(log(portafolio4))


# Graficamos los retornos

plot(log_portafolio, col=rainbow(4))

En el gráfico anterior se puede observar como la volatilidad de los retornos en periodos de crisis es más inestable, como el escenario actual de COVID-19, donde los retornos (excepto Netflix) son muy inestables.

Para realizar la frontera eficiente, requerimos trabajar con series de tiempo, por lo que transformamos la data en formato series de tiempo con el siguiente comando:

retornos=timeSeries(log_portafolio)

head(retornos)
## GMT
##                    sp500      netflix      renault          klm
## 2010-01-05  0.0031108326 -0.037531711  0.002875443  0.025941222
## 2010-01-06  0.0005453718  0.034535473  0.024240459  0.026976588
## 2010-01-07  0.0039932177 -0.017404961  0.011273791  0.009670035
## 2010-01-08  0.0028775830  0.017029816 -0.007840253  0.003341691
## 2010-01-11  0.0017452316 -0.001314184 -0.004453192  0.029583094
## 2010-01-12 -0.0094254458 -0.016288219 -0.021916515 -0.024176551

A continuación guardaremos la matriz de varianzas y covarianzas, para ello utilizaremos la función “covEstimator”:

# Matriz Var - Cor

matcovData2 = covEstimator(retornos)

matcovData2
## $mu
##         sp500       netflix       renault           klm 
##  0.0003711346  0.0015807773 -0.0002705275 -0.0003865889 
## 
## $Sigma
##                sp500      netflix      renault          klm
## sp500   0.0001228571 0.0001254642 0.0001396219 0.0001066336
## netflix 0.0001254642 0.0010867448 0.0001343763 0.0001057721
## renault 0.0001396219 0.0001343763 0.0005803596 0.0003077332
## klm     0.0001066336 0.0001057721 0.0003077332 0.0007133016

Como se puede observar, la función “covEstimator”, nos arroja la matriz de varianzas y covarianzas (Sigma), y los valores promedios de la rentabilidad de cada acción (mu) de los retornos del portafolio de cuatro activos.

Ahora crearemos la especificación:

# Especificación de restriccion de media varianza

especificacion_corta2 = portfolioSpec() 

setSolver(especificacion_corta2) = "solveRshortExact"

Y finalmente creamos la frontera eficiente:

# Frontera eficiente: Retornos de cuatro activos
# Restricción (constraints="Short"): 
# Esto quiere decir que podemos vender los activos, esto se refleja en el signo negativo 
# de Portfolio Weights:

shortFrontier = portfolioFrontier(retornos,spec=especificacion_corta2,constraints="Short")

# Por default reporta los portafolio: 1,13,25,37,50

shortFrontier
## 
## Title:
##  MV Portfolio Frontier 
##  Estimator:         covEstimator 
##  Solver:            solveRshortExact 
##  Optimize:          minRisk 
##  Constraints:       Short 
##  Portfolio Points:  5 of 50 
## 
## Portfolio Weights:
##      sp500 netflix renault     klm
## 1   0.8241 -0.3311  0.2322  0.2749
## 13  0.9473 -0.1228  0.0476  0.1278
## 25  1.0706  0.0855 -0.1369 -0.0192
## 37  1.1938  0.2939 -0.3214 -0.1662
## 50  1.3273  0.5195 -0.5213 -0.3255
## 
## Covariance Risk Budgets:
##      sp500 netflix renault     klm
## 1   0.3124  0.2027  0.2101  0.2749
## 13  0.7778 -0.0045  0.0589  0.1678
## 25  0.9554  0.1304 -0.0763 -0.0095
## 37  0.5077  0.4220  0.0357  0.0346
## 50  0.2558  0.5195  0.1228  0.1019
## 
## Target Returns and Risks:
##       mean     Cov    CVaR     VaR
## 1  -0.0004  0.0179  0.0431  0.0275
## 13  0.0001  0.0122  0.0299  0.0179
## 25  0.0006  0.0116  0.0281  0.0180
## 37  0.0011  0.0169  0.0379  0.0255
## 50  0.0016  0.0250  0.0545  0.0357
## 
## Description:
##  Wed May 20 01:01:06 2020 by user: User

A continuación graficaremos la frontera eficiente:

frontera2 = shortFrontier

frontierPlot(frontera2,frontier = "both",risk="Sigma",type="l",col = c("blue", "grey"))

Como se puede observar, la línea azul es la frontera eficiente, mientras que la gris es la frontera ineficiente.

Finalmente, podemos graficar también otros portafolios, como el de mínima varianza y otros que se encuentran dentro de la frontera:

# Se recomienda correr línea por línea, para visualizar los cambios

# Frontera eficiente
frontierPlot(frontera2,frontier = "both",risk="Sigma",type="l",col = c("blue", "grey"))

# Otros portafolios
singleAssetPoints(frontera2,risk="Sigma",pch=19,cex=1.5,col=topo.colors(6))

# Portafolio de mínima varianza
minvariancePoints(frontera2,pch=19,col="red")

Se puede observar que también existe otro portafolio cercano al de mínima varianza, siendo el de mínima varianza representado por el círculo rojo.

4. INTRODUCCION MGARCH

En los puntos anteriores manteníamos a la matriz de covarianza como estática; a continuación “dinamizaremos” dicha matriz a través del modelo de Garch Multivariado o MGARCH.

Para ello haremos uso del paquete “rmgarch”

install.packages("rmgarch")
library("rmgarch")

Dentro de este paquete se encuentra la base de datos “dji30retw”, la cual utilizaremos para realizar el modelo MGARCH.

# La data contiene retornos de activos

data(dji30retw)


# Trabajaremos con los primeros ocho activos

Dat = dji30retw[,1:8,drop=F]

head(Dat)
##                      AA          AXP           BA         BAC           C
## 1987-03-27 -0.005952399 -0.007942854 -0.008866429 -0.03119837 -0.02586351
## 1987-04-03  0.005952399 -0.025849581 -0.010230268  0.00000000 -0.01762160
## 1987-04-10 -0.014947961 -0.026535554 -0.014239723 -0.03584613 -0.01342302
## 1987-04-17  0.047067511 -0.035932009 -0.023747818 -0.02587945 -0.09440968
## 1987-04-24  0.017094433 -0.055520076 -0.046456441 -0.03042060 -0.03526814
## 1987-05-01  0.025105921  0.025455920 -0.059052432 -0.01165062  0.02030527
##                     CAT         CVX           DD
## 1987-03-27  0.015873349 -0.02204814  0.006389798
## 1987-04-03  0.041136906  0.06324389  0.035457312
## 1987-04-10 -0.046400076 -0.01657913 -0.035457312
## 1987-04-17 -0.007947062 -0.03400637  0.005293819
## 1987-04-24 -0.010695289 -0.02871011 -0.031101703
## 1987-05-01  0.036943515  0.01126319 -0.019802627
# Especificamos el modelo GARCH 

uspec = ugarchspec(mean.model = list(armaOrder=c(0,0)),
                   variance.model=list(garchOrder=c(1,1),model="eGARCH"),
                   distribution.model="norm")

spec1 = dccspec(uspec=multispec(replicate(8,uspec)),
                dccOrder=c(1,1),distribution="mvnorm")

        
# Y estimamos el modelo DCC

fit1=dccfit(spec1,data=Dat)
  
fit1
## 
## *---------------------------------*
## *          DCC GARCH Fit          *
## *---------------------------------*
## 
## Distribution         :  mvnorm
## Model                :  DCC(1,1)
## No. Parameters       :  70
## [VAR GARCH DCC UncQ] : [0+40+2+28]
## No. Series           :  8
## No. Obs.             :  1141
## Log-Likelihood       :  17800.09
## Av.Log-Likelihood    :  15.6 
## 
## Optimal Parameters
## -----------------------------------
##               Estimate  Std. Error    t value Pr(>|t|)
## [AA].mu       0.000595    0.001303    0.45665 0.647920
## [AA].omega   -0.256000    0.166503   -1.53750 0.124170
## [AA].alpha1  -0.107946    0.054682   -1.97406 0.048375
## [AA].beta1    0.956697    0.027907   34.28105 0.000000
## [AA].gamma1   0.199027    0.065157    3.05456 0.002254
## [AXP].mu      0.000866    0.000782    1.10682 0.268372
## [AXP].omega  -0.101667    0.013158   -7.72677 0.000000
## [AXP].alpha1 -0.091092    0.022970   -3.96576 0.000073
## [AXP].beta1   0.983231    0.001715  573.18827 0.000000
## [AXP].gamma1  0.119157    0.021341    5.58338 0.000000
## [BA].mu       0.002355    0.002394    0.98393 0.325149
## [BA].omega   -0.060658    0.064501   -0.94041 0.347007
## [BA].alpha1  -0.056327    0.111291   -0.50613 0.612767
## [BA].beta1    0.989932    0.011005   89.95226 0.000000
## [BA].gamma1   0.103884    0.053999    1.92382 0.054378
## [BAC].mu      0.001958    0.001467    1.33472 0.181968
## [BAC].omega  -0.010052    0.025918   -0.38784 0.698137
## [BAC].alpha1 -0.064921    0.039374   -1.64882 0.099185
## [BAC].beta1   0.996892    0.004284  232.70311 0.000000
## [BAC].gamma1  0.128296    0.026939    4.76246 0.000002
## [C].mu        0.001661    0.001238    1.34110 0.179887
## [C].omega    -0.077157    0.033463   -2.30576 0.021124
## [C].alpha1   -0.056115    0.038036   -1.47533 0.140123
## [C].beta1     0.984657    0.005621  175.17454 0.000000
## [C].gamma1    0.171460    0.023412    7.32376 0.000000
## [CAT].mu      0.001794    0.001208    1.48503 0.137536
## [CAT].omega  -0.197798    0.005812  -34.03229 0.000000
## [CAT].alpha1 -0.074352    0.017873   -4.16002 0.000032
## [CAT].beta1   0.967659    0.000412 2349.03552 0.000000
## [CAT].gamma1  0.074393    0.002600   28.61074 0.000000
## [CVX].mu      0.001657    0.000938    1.76712 0.077209
## [CVX].omega  -0.712817    0.827809   -0.86109 0.389189
## [CVX].alpha1 -0.081153    0.059622   -1.36112 0.173475
## [CVX].beta1   0.896351    0.120470    7.44045 0.000000
## [CVX].gamma1  0.247109    0.158230    1.56171 0.118357
## [DD].mu       0.001135    0.000997    1.13835 0.254975
## [DD].omega   -0.109491    0.011343   -9.65248 0.000000
## [DD].alpha1  -0.036420    0.019128   -1.90406 0.056903
## [DD].beta1    0.982890    0.001516  648.16862 0.000000
## [DD].gamma1   0.099008    0.008788   11.26695 0.000000
## [Joint]dcca1  0.009425    0.003160    2.98319 0.002853
## [Joint]dccb1  0.959913    0.020461   46.91410 0.000000
## 
## Information Criteria
## ---------------------
##                     
## Akaike       -31.078
## Bayes        -30.769
## Shibata      -31.085
## Hannan-Quinn -30.961
## 
## 
## Elapsed time : 12.75073
# DCC: Modelo Dinámico de Correlación Condicional

Finalmente, luego de estimar el modelo DCC, procedemos al análisis gráfico del portafolio con valores en riesgo. Es decir presentamos al portafolio (color azul), y visualizaremos el límite máximo de ganancias (verde), y el límite máximo de pérdida (VaR), observando que existen momentos donde la pérdida del portafolio fue superior al máximo de su pérdida estimada (Hits).

x11()
plot(fit1)

Para graficar el portafolio ys sus límites, se requiere colocar el número 5 cuando la consola del R solicita la instrucción.