## 8.1 Fama-French Three Factor Model

• ; extended the basic CAPM to include size and book-to-market effects as explanatory factors in explaining the cross-section of stock returns.

• SMB (Small minus Big) gives the size premium which is the additional return received by investors from investing in companies having a low market capitalization.

• HML (High minus Low), gives the value premium which is the return provided to investors for investing in companies having high book-to-market values.

• The three factor Fama-French model is written as:

$$$r_{A}-r_{F}=+\beta_{A}(r_{M}-r_{F})+s_{A}SMB+h_{A}HML+\alpha+e \#eq:ff1)$$$

Where $$s_{A}$$ and $$h_{A}$$ capture the security’s sensitivity to these two additional factors.

### 8.1.1 Data Preprocessing

# use read.table for text file
ff_data = read.csv("data/F-F_Research_Data_Factors_daily.CSV", skip = 3)
ff_data = na.omit(ff_data)  #remove missing values

head(ff_data)  #date is missing column names
         X Mkt.RF   SMB   HML    RF
1 19260701   0.10 -0.23 -0.28 0.009
2 19260702   0.45 -0.34 -0.03 0.009
3 19260706   0.17  0.29 -0.38 0.009
4 19260707   0.09 -0.59  0.00 0.009
5 19260708   0.21 -0.38  0.18 0.009
6 19260709  -0.71  0.44  0.58 0.009
colnames(ff_data)[1] = "Date"
# convert dates in R date format
ff_data$Date = as.Date(strptime(ff_data$Date, format = "%Y%m%d"))
head(ff_data)
        Date Mkt.RF   SMB   HML    RF
1 1926-07-01   0.10 -0.23 -0.28 0.009
2 1926-07-02   0.45 -0.34 -0.03 0.009
3 1926-07-06   0.17  0.29 -0.38 0.009
4 1926-07-07   0.09 -0.59  0.00 0.009
5 1926-07-08   0.21 -0.38  0.18 0.009
6 1926-07-09  -0.71  0.44  0.58 0.009
• Download the data and convert to returns
d_aapl = getSymbols("AAPL", from = "2019-01-01", to = "2021-09-30", auto.assign = F)
# select closing prices and covert to log returns

aapl = d_aapl$AAPL.Close aapl_ret = dailyReturn(aapl, type = "log") # convert to data frame aapl_ret2 = fortify.zoo(aapl_ret) #Dates column will be named Index # rename colnames(aapl_ret2) = c("Date", "AAPL") # use merge (can use left_join from dplyr as well) to combine the # stock returns and factor data data_ffex = merge(aapl_ret2, ff_data, by = "Date") ### 8.1.2 Regression Analysis • The Fama-French regression uses excess returns so first convert Apple returns to excess returns and then fit the model using the lm function # create another column with AAPL-RF data_ffex$AAPL.Rf = data_ffex$AAPL - data_ffex$RF

ff_lreg = lm(AAPL.Rf ~ Mkt.RF + SMB + HML, data = data_ffex)
• A plot function can be used to plot the four regression plots similar to simple regression.
par(mfrow = c(2, 2))
plot(ff_lreg)
• There are packages in R which provide functions to export the summary output of a regression model in a LaTeX, HTML or ASCII files.
• The following code uses function to print the OLS results in ASCII format.
• The same output can also be exported to an HTML or LaTeX file which can be later used in a word/LaTeX document.
stargazer(ff_lreg, summary = T, title = "Fama-French Regression OLS", type = "html")
 Dependent variable: AAPL.Rf Mkt.RF 0.013*** (0.0003) SMB -0.003*** (0.001) HML -0.004*** (0.0004) Constant -0.003*** (0.0005) Observations 692 R2 0.677 Adjusted R2 0.676 Residual Std. Error 0.013 (df = 688) F Statistic 481.374*** (df = 3; 688) Note: p<0.1; p<0.05; p<0.01

### 8.1.3 Visualisation

• The ggeffects package provides good functionality on visualising the marginal effects and adjusted predictions. The predictions generated by a model by varying one independent variable and keeping the others constant.
• The following example visualises the predictions based on the SMB factor
library(ggeffects)

mydf = ggpredict(ff_lreg, terms = c("SMB"))
(p_ff = plot(mydf) + geom_point(data = data_ffex, aes(x = SMB, y = AAPL.Rf),
color = "darkblue"))

### References

Fama, Eugene F, and Kenneth R French. 1992. “The Cross-Section of Expected Stock Returns.” The Journal of Finance 47 (2): 427–65.
———. 1993. “Common Risk Factors in the Returns on Stocks and Bonds.” Journal of Financial Economics 33 (1): 3–56.