R/Component_FamaFrench.R

Defines functions Calculate_Fama_COE Calculate_Fama_Table Return_toMonthly

Documented in Calculate_Fama_COE Calculate_Fama_Table Return_toMonthly

#' Get Monthly Log return
#'
#' Transforms data from \code{ImportAndClean_DailyPrice()} into xts objects
#' and returns monthly log returns for each stock.
#'
#' @param stock.list a list object that contains stocks with \emph{daily} stock prices
#'
#' @return list with monthly data.frame returns of stock
#' @export
Return_toMonthly <- function(stock.list) {

  time.difference <- Sys.time()

  if(class(stock.list) != 'list') stop('stock.list object is not of object type list')

  stock.list <- stock.list[sapply(stock.list, function(x) { nrow(x) > 150 })] # we require at least 5 month of being public, otherwise will get error

  # execution time can be long, so print message
  cat('please wait, calculating monthly stock returns for', length(stock.list), 'number of firms\n')

  # nr 22 in the stock.list is generating error, couldn't resolve error, we go with tryCatch()
  stock.list <- lapply(stock.list, function(stock) {

    # mutate to xts object
    stock <- stock %>% select(datadate, Close) %>%
                       xts_mutate()

    stock <- quantmod::monthlyReturn(stock, type = 'log', leading = FALSE)

    # mutate to df object
    stock <- df_mutate(stock)
  })

  # print time it took to execute function
  cat('it took ', Sys.time() - time.difference, ' to execute this function\n')
  return(stock.list)
}
#' Calculate Fama French Cost of Equity
#'
#' returns a list object with the monthly Fama coefficients, estimates and cost of capital.
#'
#' @param stock.list monthly returns of stocks
#'
#' @return a list object
#' @export
Calculate_Fama_Table <- function(stock.list) {
# ISSUE: WITH CURRENT SETUP ANY STOCK THAT HAS NOT BEEN REGISTERED SINCE PRE-2015
# WILL HAVE ONLY NA VALUES IN ITS DATA.FRAME, AND WILL THUS GENRATE AN ERROR IN THE
# LINEAR REGRESSION CALCULATION

    time.start <- Sys.time()

    # import Rf rates to join
    RiskF.Return <- SE.10Y.Monthly                                                        %>% # load form /data
                    mutate(Date = as.Date(paste(Date, 1), format = '%Y %B %d'))           %>%
                    mutate(YearMonth = as.integer(format(zoo::as.yearmon(Date), '%Y%m')))


    # neccessary FAMA data
    FamaFrench.coefficients <- FamaFrench.coefficients # load from /data
    FamaFrench.table        <- FamaFrench              # load from /data


    # calculate stock Re
    Stock.Fama.COE <- lapply(stock.list, function(stock) {


      if(nrow(stock) > 30) { # we need at least 3 years back, as Fama table starts in 2014
                                 # put if statement first, firms that do not have values for 2014
                                 # do not need to be evaluated

        # manipulate monthly stock market data so it fits the Fama French!
        stock$YearMonth  <- as.integer(
                                        format(zoo::as.yearmon(stock$Date), '%Y%m')
                                                                                  )

        # left join before Fama French Re calculation
        FamaTable <- left_join(stock, FamaFrench.table, by = c('YearMonth' = 'Date'))                %>% # join with Fama data
                     left_join(., select(RiskF.Return, -Date), by = c('YearMonth' = 'YearMonth'))    %>% # join with RiskF data
                     arrange(desc(Date))                                                             %>% # descending order
                     filter(complete.cases(.))                                                       %>%
                     select(-YearMonth)

          FamaTable$Fama.Estimate <- zoo::rollapply(select(FamaTable, -Date), width = 12, FUN = function(stock) {

          lm.stock  <- summary(
            lm(monthly.returns ~ RM.RF + SMB + HML, data = as.data.frame(stock))
          )

          # seperate out coef for FamaFrench calculation
          lm.stock.coefficients <- lm.stock$coefficients

          FAMA.RM.RF <- lm.stock.coefficients['RM.RF', 'Estimate']
          FAMA.SMB   <- lm.stock.coefficients['SMB', 'Estimate']
          FAMA.HML   <- lm.stock.coefficients['HML', 'Estimate']

          Fama.Estimate <- FAMA.RM.RF * (FamaFrench.coefficients$RM.RF*100) + FAMA.SMB * (FamaFrench.coefficients$SMB*100) + FAMA.HML * (FamaFrench.coefficients$HML*100)

          return(Fama.Estimate)

        }, by.column = FALSE, fill = NA, align = 'left')

        # add cost of equity
        FamaTable$Fama.COE <- FamaTable$Fama.Estimate + ((1+FamaTable$SE.10Y)^(1/12)-1) # remember, monthly

        return(FamaTable)

        } else {

        return(NULL) # return NA for firms that have nrow > 30

        }
      # return from lapply
    })
  print(Sys.time() - time.start)
  return(Stock.Fama.COE)
}
#' Calculate Yearly Cost of Capital
#'
#' Uses the list object generated from the \code{Calculate_Fama_Table} and calculates the yearly cost of equity.
#' For year 2015, the cost of equity is assumed to be equal to the 2014. Other values for 2015 are added.
#'
#' @param FAMA.table.list list obejct returns from \code{Calculate_Fama_Table()}
#'
#' @return a list object
#' @export
#'
#' @examples
#' Monthly.stockReturns <- Return_toMonthly(ImportAndClean_DailyPrice())
#' Fama.Table           <- Calculate_Fama_Table(Monthly.stockReturns)
#' Fama.COE             <- Calculate_Fama_COE(Fama.Table)
Calculate_Fama_COE <- function(FAMA.table.list) {

    # support function to return last date in year 2015 and 2016, needed later
    LastDateofYear <- function(year) {

      DateSeq      <- seq.Date(as.Date('2015-01-01'), as.Date('2016-12-31'), by = 1)
      DateSeq <- DateSeq[lubridate::wday(DateSeq) > 1 & lubridate::wday(DateSeq) < 7] # monday to friday
      DateSeq <- DateSeq[!(DateSeq %in% SvenskaHelgdagar$Date)] # load from /data

      Date.df     <-  data.frame(Date = DateSeq, Year = lubridate::year(DateSeq))
      browser()
      last.date.in.year.df   <- Date.df %>% filter(Year == year)                          %>%
                                             slice(n())                                   %>%
                                             .$Date

      return(last.date.in.year.df)
    }

    # necessary data needed
    # import Rf rates to join
    RiskF.Return <- data(SE.10Y.Monthly)                                                  %>%
                    mutate(Date = as.Date(paste(Date, 1), format = '%Y %B %d'))           %>%
                    mutate(YearMonth = as.integer(format(zoo::as.yearmon(Date), '%Y%m')))

    # make fama coe to yearly values
    # for year 2015 and 2016 take 2014 years values
    FAMA.table.list.cleaned <- FAMA.table.list[sapply(FAMA.table.list, function(x) { !is.null(x) })]

    Fama.table.return       <- lapply(FAMA.table.list.cleaned, function(Fama.table) {

      Fama.xts <- xts_mutate(Fama.table)

      return.xts <- xts()

      # Make monthly to annual geometric return
      return.xts$Stock.Return           <- apply.yearly(Fama.xts[, 'monthly.returns'], function(x) {

          x <- df_mutate(x)
          for(i in 1:nrow(x)) {

            if(i == 1) {
              x[1, 'Yearly.return'] <- x[1, 'monthly.returns']
            } else {
              x[i, 'Yearly.return'] <- (1+x[i, 'monthly.returns']) * (1+x[i-1, 'Yearly.return']) -1
            }

          }
        # end of for loop
        return(x[nrow(x), 'Yearly.return'])
        })
      return.xts$RiskF.Return           <- apply.yearly(Fama.xts[, 'SE.10Y'] , mean, na.rm = TRUE)$SE.10Y
      return.xts$Monthly.Cost.of.Equity <- apply.yearly(Fama.xts[, 'Fama.COE']    , mean, na.rm = TRUE)$Fama.COE # monthly COE
      return.xts$Yearly.Cost.of.Equity  <- ((1+return.xts$Monthly.Cost.of.Equity)^12-1)

      if(2014 %in% lubridate::year(index(return.xts))) { # add values for year 2015 (no 2016 as we are in 2016)

      return.2015                       <- data.frame(Stock.Return = NA,
                                                      RiskF.Return = RiskF.Return[RiskF.Return$YearMonth == '201512', 'SE.10Y', drop = TRUE],
                                                      Monthly.Cost.of.Equity = return.xts[nrow(return.xts), 'Monthly.Cost.of.Equity'],
                                                      Yearly.Cost.of.Equity  = return.xts[nrow(return.xts), 'Yearly.Cost.of.Equity' ])

      return.xts                        <- c(return.xts, xts(order.by = as.Date('2015-12-30'), x = return.2015))
      }
      return(return.xts)
    })
    return(Fama.table.return)
}
uncoollocket/strider documentation built on Jan. 16, 2018, 12:05 a.m.