Prof. Welch - Financial Decision Making, 2021

by Jeffrey Chen

Do a basic Fama-Macbeth type of regression predicting cross-sectional stock returns with independent variables: firm-marketcap, price normalized accruals, the earnings-price ratio, and 1/price. You can run this based on the annual data sets you created earlier. (If annual, you want to predict year t calendar stock returns with year t-2 variables, because a firm could end its fiscal year in May and report results in October.) The minimum requirement is Fama-Macbeth overall coefficients from one predictive set of (four) independent variables. (Each Fama-Macbeth coefficient is the average over the cross-sectional coefficients.)

Data Processing

WRDS - Capital QI - Annual Fundamental

For price normalized accruals calculations:

Total Accrual= Net profit - Net Cash from Operating Activities.

Price Normalized Accruals = Total Accrual/Closed Price

Summary

The Fama-MacBeth cross-section regression is assumed the lambda (beta) we retrieve from each t (year) is uncorrelated across time. Therefore, we can simply take the average of the regression coefficient across time.

From the table below we can see the regression coefficient for each character. We can see that market cap and price-normalized-accruals has small standard deviation across time, implies the factor is uncorrelated across time. But they also not showing statistic significant predictive ability with the returns. The ep ratio & 1/price seems to have stronger prediction power, and their standard deviation are also larger, saying that tho they have stronger prediction power but they might have some correlation across time. The positive coefficient for the ep ratio could suggest that value stocks have higher expected returns. And negative coefficient of 1/price could suggest a reversal signal of price, the cheaper the price, the more expected returns will drop.

Yet, if we look at mean p value, the p value here are relatively large, suggesting that we accept the null hypothesis, that is the data are correlated with time. I think because I’m regressing for all companies, and some companies do actually had correlation across time. Given this result, I think cross-section regression performed well in smaller/similar sample size, for instance, using industry sector to run cross-section might have better prediction power.

Code Chuck

library(tidyverse)
library(ggplot2)
library(lubridate)
library(broom)
data = read.csv("./data_hw7.csv")
data$date = ymd(data$datadate)

#clean data and get our estimators
df_factor = data %>% drop_na() %>% 
  mutate(year = year(date), acc_pr_norm = (ni - oancf)/prcc_f) %>% 
  group_by(gvkey, year) %>% summarise(avg_pr = mean(prcc_f, na.rm=T),
                                      avg_mktcap = mean(mkvalt,na.rm=T), 
                                      avg_acc_pr_norm = mean(acc_pr_norm,na.rm=T), 
                                      epratio = mean(epsfi, na.rm=T)/mean(prcc_f,na.rm=T))
#add stock return with 2 year interval
df_factor = df_factor %>% group_by(gvkey) %>% 
  mutate(invpr=1/avg_pr,
          ret= avg_pr/lag(avg_pr)-1) %>% 
  drop_na() %>% filter_all(all_vars(!is.infinite(.)))
# run cross-section regression 
# step1 run regression for each year with 4 factors. Using t to predict t+2
cs_reg_models = df_factor %>% filter(n() >= 3) %>% 
  group_by(year) %>%                            
  do(reg_yearly = lm(lead(ret,2) ~ avg_mktcap + avg_acc_pr_norm + epratio + invpr, data=.)) %>% 
  summarise(tidy(reg_yearly))
# step2 take the average of the lambda across time for each factor

coefs_avg = cs_reg_models %>%
    group_by(term) %>%
    summarize(Mean.Estimators = mean(estimate), 
              Std.Estimators = sd(estimate), 
              Mean.Std.Err = mean(std.error),
              Mean.P.value = mean(p.value))

Summary Table

coefs_avg
## # A tibble: 5 x 5
##   term            Mean.Estimators Std.Estimators Mean.Std.Err Mean.P.value
## * <chr>                     <dbl>          <dbl>        <dbl>        <dbl>
## 1 (Intercept)          4.91            10.9          3.53           0.0865
## 2 avg_acc_pr_norm     -0.000189         0.000908     0.00270        0.911 
## 3 avg_mktcap           0.00000100       0.000248     0.000254       0.691 
## 4 epratio              0.0624           0.296        0.105          0.918 
## 5 invpr               -0.0180           0.0665       0.252          0.884