Estoy escribiendo mi tesis de maestría sobre las estrategias de impulso, incluyendo el impulso del precio (UMD/MOM) y dos estrategias de impulso fundamental (SUE y CAR3). Ahora mismo estoy intentando crear los tres factores de momentum para comparar su rendimiento desde 1975-2012. El factor UMD/MOM es un factor ya construido por Fama-French. La documentación se puede ver en la página web de French: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/Data_Library/det_mom_factor.html
Sigo el método de Fama-French a la hora de construir el factor MOM y luego intento seguir exactamente el mismo procedimiento a la hora de crear los factores SUE y CAR3, al igual que Robert Novy-Marx en su artículo "Fundamentally, Momentum is Fundamental Momentum" de 2015: http://rnm.simon.rochester.edu/research/FMFM.pdf . Mis datos se recogen directamente de WRDS a R siguiendo este código: https://drive.google.com/file/d/0BxvBvE2V-dFTVnZuLUFhZWNuazA/view?fbclid=IwAR0-uPDl1-kzRyugIVePTtIFxMiM5jQbbWqE9VxIdMftrs4adJ_zDGuh4Go
Novy-Marx (2015) crea una figura del rendimiento de los factores en la p. 9 que es la figura que pretendo replicar. Mis resultados de MOM y CAR3 son muy similares a los de Fama-French y Robert. La figura de abajo es mis resultados, donde el factor UMD es el que he construido y el factor MOM es el que he descargado de Fama-French. Esto mostró claramente que he sido capaz de replicar el factor UMD casi 1:1 y CAR3 también es muy similar a Novy-Marx (2015).
Sin embargo, cuando incluyo el SUE al gráfico resulta esto:
Pero como ves la SUE es irrealmente alta. Dado que el procedimiento de construcción del rendimiento de los factores es exactamente el mismo que para UMD y CAR3, implica que el problema debe estar en relación con mi cálculo de SUE en sí. Por lo tanto, necesito ayuda para examinar dónde se produce exactamente el problema.
Para calcular el SUE sigo a Novy-Marx (2015). Define la SUE como "la variación interanual más reciente en las ganancias por acción, escalada por la desviación estándar de estas innovaciones en las ganancias durante los últimos ocho anuncios, sujeto a un requisito de al menos seis anuncios observados anuncios observados a lo largo de la ventana de dos años". Intentaré escribir paso a paso lo que hago exactamente:
Paso 1: Descargo los datos trimestrales de Compustat, incluyendo las variables DATADATE, GVKEY y EPSPXQ (Beneficios por acción (básicos) / excluyendo elementos extraordinarios).
res <- dbSendQuery(wrds,"select gvkey, datadate, epspxq from comp.fundq
where INDFMT='INDL' and DATAFMT='STD' and CONSOL='C' and POPSRC='D'")
comp.fundq <- dbFetch(res, n = -1)
Paso 2: Ordeno los datos por datadate y gvkey para asegurarme de que los datos están ordenados correctamente antes de retrasar EPSPXQ en 4 trimestres.
comp.data <-
comp.data %>%
arrange(datadate, gvkey) %>%
group_by(gvkey) %>%
mutate(lag.eps = dplyr::lag(epspxq, n = 4, default = NA))
Paso 3: Calculo las innovaciones de los ingresos mediante
comp.data$ei <- comp.data$epspxq-comp.data$lag.eps
Paso 4: Calculo la desviación estándar móvil de las innovaciones de los beneficios calculadas en el paso 3 a lo largo de los últimos 8 anuncios (anchura = 8) con un criterio en el que se requieren al menos 6 observaciones de no NA (Parcial = 6)
FUN <- function(x) if (length(na.omit(x)) >= 6) sd(x, na.rm = TRUE) else NA
roll1 <- function(z) rollapplyr(z, width = 8, FUN = FUN, fill = NA, partial = 6)
comp.data <-
comp.data %>%
arrange(datadate, gvkey) %>%
transform(comp.data, roll1 = ave(ei, gvkey, FUN = roll1))
Paso 5: Calculo la SUE mediante
comp.data$sue <- comp.data$ei/comp.data$roll1
Paso 6: Descargo los datos CCM de WRDS como paso para fusionar los datos Compustat con los datos CRSP:
res <- dbSendQuery(wrds,"select GVKEY, LPERMNO, LINKDT, LINKENDDT, LINKTYPE, LINKPRIM
from crsp.ccmxpf_lnkhist")
ccm <- dbFetch(res, n = -1)
Paso 7: Fusiono mi conjunto de datos Compustat comp.data (incluyendo mi nueva variable SUE) con CCM:
ccm.comp <-
ccm %>%
filter(linktype %in% c("LU", "LC", "LS")) %>%
filter(linkprim %in% c("P", "C", "J")) %>%
merge(comp.data, by="gvkey") %>%
mutate(datadate = as.Date(datadate),
permno = as.factor(lpermno),
linkdt = as.Date(linkdt),
linkenddt = as.Date(linkenddt),
linktype = factor(linktype, levels=c("LC", "LU", "LS")),
linkprim = factor(linkprim, levels=c("P", "C", "J"))) %>%
filter(datadate >= linkdt & (datadate <= linkenddt | is.na(linkenddt))) %>%
arrange(datadate, permno, linktype, linkprim) %>%
distinct(datadate, permno, .keep_all = TRUE)
Paso 8: Limpio mis datos después de la fusión:
ccm.comp.cln <-
ccm.comp %>%
arrange(datadate, permno) %>%
select(datadate, permno, sue) %>%
mutate_if(is.numeric, funs(ifelse(is.infinite(.), NA, .))) %>%
mutate_if(is.numeric, funs(round(., 5)))
ccm.comp.cln$datadate <- strptime(as.character(ccm.comp.cln$datadate), "%Y-%m-%d")
ccm.comp.cln$datadate <- format(ccm.comp.cln$datadate,"%Y%m")
Paso 9: Introduzco los datos del CRSP y los depuro de la misma manera que Fama-French: "... todas las empresas del CRSP constituidas en los EE.UU. y que cotizan en el NYSE, AMEX o NASDAQ que tienen un código de acción del CRSP de 10 u 11 al principio del mes t, buenos datos de acciones y precios al principio de t, y buenos datos de rendimiento para t". Esto incluye también el tratamiento de los rendimientos de la exclusión de la lista.
Paso 10: Fusiono mis datos de CCM-Compustat con mis datos de CRSP:
na_locf_until = function(x, n) {
l <- cumsum(! is.na(x))
c(NA, x[! is.na(x)])[replace(l, ave(l, l, FUN=seq_along) > (n+1), 0) + 1]
}
crsp.comp <- merge(x = crsp.data, y = ccm.comp.cln, by.x = c("permno", "date"), by.y = c("permno", "datadate"), all.x = TRUE)
¿Puede alguien ayudarme a identificar dónde podría producirse el problema?