3 votos

Finanzas: Cartera - Construcción de carteras largas y cortas

Estoy tratando de construir una cartera larga/corta en R. Digamos que tengo dos carteras Tech y Mature y quiero ir en largo en el Tech cartera y corta en la Mature cartera.

Recojo y descargo los datos utilizando:

tickers <- c("GOOG", "MSFT", "GE", "WAL")

library(tidyquant)
library(dplyr)
library(tidyverse)
library(glue)

data <- tq_get(tickers,
               get = "stock.prices",
               from = "2010-01-01",
               to = "2015-01-01") %>%
  group_by(symbol) %>%
  tq_transmute(select = adjusted,
                 mutate_fun = periodReturn,
                 period = "monthly",
                 type = "arithmetic") %>%
  mutate(portfolio = case_when(
    symbol == "GOOG" ~ "Tech",
    symbol == "MSFT" ~ "Tech",
    symbol == "GE"  ~ "Mature",
    symbol == "WAL" ~ "Mature"
    ),
    date = ceiling_date(date, "month") - days(1)) %>% # set the date to the end of the month
  group_by(portfolio, date) %>%
  summarise(
    Port_Monthly_Rets = mean(monthly.returns)
  )

Lo que parece:

# A tibble: 120 x 3
# Groups:   portfolio [2]
   portfolio date       Port_Monthly_Rets
   <chr>     <date>                 <dbl>
 1 Mature    2010-01-31            0.173 
 2 Mature    2010-02-28            0.0639
 3 Mature    2010-03-31            0.0605
 4 Mature    2010-04-30            0.283 
 5 Mature    2010-05-31           -0.104 
 6 Mature    2010-06-30           -0.111 
 7 Mature    2010-07-31            0.0659
 8 Mature    2010-08-31           -0.130 
 9 Mature    2010-09-30            0.113 
10 Mature    2010-10-31           -0.0563
# ... with 110 more rows

También descargo los Factores Franceses de Fama:

# Collect Fama French Factors:

temp <- tempfile()
base <- "http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/"
factor <- "North_America_3_Factors"
format<-"_CSV.zip"
full_url <-glue(base,factor,format,sep ="")
download.file(full_url,temp,quiet = TRUE)

FF_Factors <- read_csv(unz(temp, "North_America_3_Factors.csv"), skip = 6) %>%
  rename(date = X1) %>%
  mutate_at(vars(-date), as.numeric) %>%
  mutate(date = rollback(ymd(parse_date_time(date, "%Y%m") + months(1)))) %>%
  drop_na(date) %>%
  rename(Mkt_Rf_3 = `Mkt-RF`,
         SMB_3 = SMB,
         HML_3 = HML,
         RF_3 = RF)

Lo uno todo y calculo el exceso de rentabilidad:

# Join factors with portfolios

df <- data %>%
  left_join(FF_Factors, by = "date") %>%
  mutate(R_excess = Port_Monthly_Rets - RF_3)

Que ahora parece:

# A tibble: 120 x 8
# Groups:   portfolio [2]
   portfolio date       Port_Monthly_Rets Mkt_Rf_3 SMB_3 HML_3  RF_3 R_excess
   <chr>     <date>                 <dbl>    <dbl> <dbl> <dbl> <dbl>    <dbl>
 1 Mature    2010-01-31            0.173     -3.63  0.45  0.89  0      0.173 
 2 Mature    2010-02-28            0.0639     3.71  0.86  2.35  0      0.0639
 3 Mature    2010-03-31            0.0605     6.27  1.5   1.48  0.01   0.0505
 4 Mature    2010-04-30            0.283      1.92  3.73  1.9   0.01   0.273 
 5 Mature    2010-05-31           -0.104     -7.86  0.74 -2.32  0.01  -0.114 
 6 Mature    2010-06-30           -0.111     -5.5  -1.07 -3.73  0.01  -0.121 
 7 Mature    2010-07-31            0.0659     6.95  0.02  1.03  0.01   0.0559
 8 Mature    2010-08-31           -0.130     -4.44 -1.61 -2.35  0.01  -0.140 
 9 Mature    2010-09-30            0.113      9.47  3.67 -1.85  0.01   0.103 
10 Mature    2010-10-31           -0.0563     3.89  0.98 -1.55  0.01  -0.0663
# ... with 110 more rows

Hago regresiones Fama French en mis carteras:

summary(lm(R_excess ~ Mkt_Rf_3 + SMB_3 + HML_3, data = subset(df, portfolio == "Mature")))
summary(lm(R_excess ~ Mkt_Rf_3 + SMB_3 + HML_3, data = subset(df, portfolio == "Tech")))

Por ejemplo, el Tech cartera parece:

Call:
lm(formula = R_excess ~ Mkt_Rf_3 + SMB_3 + HML_3, data = subset(df, 
    portfolio == "Mature"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.10673 -0.03100 -0.01297  0.02820  0.18958 

Coefficients:
            Estimate Std. Error t value  Pr(>|t|)    
(Intercept) 0.010782   0.007560   1.426   0.15934    
Mkt_Rf_3    0.009913   0.002130   4.654 0.0000204 ***
SMB_3       0.008572   0.004173   2.054   0.04463 *  
HML_3       0.011192   0.004137   2.705   0.00903 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05491 on 56 degrees of freedom
Multiple R-squared:  0.5271,    Adjusted R-squared:  0.5018 
F-statistic: 20.81 on 3 and 56 DF,  p-value: 0.00000000349

Quiero ir en largo en el tech cartera y corta en la mature cartera. Aquí está mi intento de crear la cartera Long/Short.

LS_Portfolio <- df %>%
  select(-Port_Monthly_Rets) %>%
  pivot_wider(names_from = portfolio, values_from = c(R_excess)) %>%
  mutate(Long_Short = Tech - Mature)

summary(lm(Long_Short ~ Mkt_Rf_3 + SMB_3 + HML_3, data = LS_Portfolio))

Qué salidas:

Call:
lm(formula = Long_Short ~ Mkt_Rf_3 + SMB_3 + HML_3, data = LS_Portfolio)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.248952 -0.027568  0.003106  0.029772  0.191031 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.017876   0.009873  -1.810  0.07559 . 
Mkt_Rf_3     0.002387   0.002782   0.858  0.39457   
SMB_3       -0.018172   0.005450  -3.334  0.00152 **
HML_3       -0.012778   0.005404  -2.365  0.02154 * 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.07171 on 56 degrees of freedom
Multiple R-squared:  0.2307,    Adjusted R-squared:  0.1895 
F-statistic: 5.597 on 3 and 56 DF,  p-value: 0.001983

Lo que me parece erróneo, el Mkt_Rf_3 debe ser significativo. Obtengo resultados de regresión muy similares cuando aplico esto a una cartera de valores más amplia.

Mi pregunta no tiene que ver con la programación sino con cómo debo construir la cartera larga/corta dado que tengo un número de acciones en cada cartera.

Lo que hago es:

1) Formar una cartera de valores basada en algunos criterios

2) Calcule el rendimiento medio mensual de cada cartera

3) Calcule el exceso de rentabilidad de la cartera tomando la media de la rentabilidad mensual de la cartera y restando el tipo libre de riesgo de los datos de Fama French

4) Tome el tech de la cartera y restar el mature rendimiento de la cartera.

5) Ejecutar mi análisis de regresión (que tiene un mal rendimiento).

Sólo quiero saber dónde me equivoco en mi lógica.

1 votos

Si estuvieras gestionando una cartera 130/30 largo-corto, estaría de acuerdo, pero siempre que las carteras "tecnológica" y "madura" sean grandes y tengan una base amplia, ir 100% largo en una y 100% corto en la otra te dejaría más o menos neutral en el mercado.

1voto

Sbennett Puntos 11

No vas a "equivocarte" en ningún sitio. Cuando dices que la regresión funciona mal es señal de que los rendimientos de tu cartera no se explican tan bien por los factores de fama francesa (lo cual es positivo para tus factores de riesgo, no sé por qué lo llamas malo).

Al ponerte en cortocircuito con los dos valores, creas una cartera que tiene menos riesgo que los valores individuales (asumiendo que la correlación de los valores es positiva, como suele ser). El menor riesgo puede deberse a un cambio en la sensibilidad a varios parámetros o factores, si se quiere. En tu caso, los rendimientos de la cartera son neutrales con respecto al mercado (mkt_rf), lo que tiene mucho sentido.

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X