1. Read in the monthly CRSP date (crsp_monthly) and the monthly market excess returns (factors_ff_monthly) from the tidy_finance.sqlite database. Very briefly state the definition of the variables permno, ret_excess and mktcap. Provide suitable summary statistics of the cross-section of monthly excess returns and market capitalization in the CRSP sample.

Task 1.

Very briefly state the definition of the variables permno, ret_excess and mktcap*. Definition of PERMNO, as per {PERMNO}: “PERMNO is a unique permanent security identification number assigned by CRSP to each security”. Thus PERMNO is a unique company identifier.

Definition of excess returns, as per {exret}: Excess return for a stock is the difference between the stock return and the return on the risk-free security over the same period. For such risk-free securities, it is common to use a government bond such as a 10-year US Treasury bond.\

Definition of mktcap, as per {mktcap}: The variable ‘mktcap’ is defined as the market capitalization, which refers to the total dollar market value of a company’s outstanding shares of stock. Market capitalization is commonly referred to as “market cap,” and is calculated by multiplying the total number of a company’s outstanding shares by the current market price of one share.

Provide suitable summary statistics of the cross-section of monthly excess returns and market capitalization in the CRSP sample*

## [1] "There is probably a smarter way to do this, but this method includes creating two seperate summary statistics. One can do the summary statistics across a variable. "
name ret_excess mktcap
mean 0.0083 1814.65
sd 0.1523 8770.21
min -0.6906 0.71
max 2.6775 242415.02

Summary statistics for ret_excess and mktcap shows that the mean return per month is 0.79% although the median is -0.0004%. An important distinction between the variables is that ret_excess is in relative numbers, while mktcap of course is absolute, since the return is a relative change and market cap is a true number.

Task 2.

Generate a new column ret_excess_lag. Briefly state why crsp_monthly %>% group_by(permno) %>% mutate(ret_excess_lag = lag(ret_excess)) does not provide the correct result if crsp_monthly contains implicitly missing values.

Briefly stating why the provided code gives incorrect results.

If crsp_monthly contains implicitly missing values, this will cause a ret_excess_lag to not necessarily represent the value of the previous month, but the previous value in the dataset. An implicitly missing value then makes a ret_excess_lag value represent the second lagged value.

Even without implicitly missing values, the given code returns a variable with missing values for the first cell of every permno. The following code can be used to avoid missing values.

## # A tibble: 6 x 9
##   permno month           ret     rf ret_excess mkt_excess mktcap mktcap_lag
##    <dbl> <date>        <dbl>  <dbl>      <dbl>      <dbl>  <dbl>      <dbl>
## 1  10000 1986-02-01 -0.257   0.0053    -0.262      0.0713   12.0       16.1
## 2  10000 1986-03-01  0.365   0.006      0.359      0.0488   16.3       12.0
## 3  10000 1986-04-01 -0.0986  0.0052    -0.104     -0.0131   15.2       16.3
## 4  10000 1986-05-01 -0.223   0.0049    -0.228      0.0462   11.8       15.2
## 5  10000 1986-06-01 -0.00503 0.0052    -0.0102     0.0103   11.7       11.8
## 6  10000 1986-07-01 -0.0808  0.0052    -0.0860    -0.0645   10.8       11.7
## # ... with 1 more variable: ret_excess_lag <dbl>

Report suitable summary statistics or visualizations that show if returns rt and rt−1 exhibit autocorrelation that is significantly different from zero. What do your results imply? Is there short-term momentum?

  ret ret_lag
ret 1 -0.01738

ret_lag -0.01738 1

As the mean of returns is non-constant, it does not fluctuate around a constant value, returns suffer from autocorrelation. Furthermore, there is a negative correlation between \(r_t\) and \(r_{t-1}\).

The PACF plot clearly shows that there is a significant relationship between \(r_t\) and \(r_{t-1}\).

Task 3.

Generate a new column mktcap_lag_12 which contains the firms’ market capitalization 12-month prior to the measurement date.

Lagging a variable can be a frustrating task, since the days of a month will differ. The below function will always return a date in the nth month after Date. This allows for 1) not exceeding the end of month and 2) handles NA’s really well.

First we create a variable by lagging the month column without touching the others. Next, we merge our sorting variable with the return data. We use the 12-month lagged marketcap as a sorting variable to ensure that the sorts rely only on information available when we create the portfolios.

Compute the momentum of stock i as the relative change in market capitalization, represented in percentage terms (1.00 is a 1% return) during the period covering months t−12 until t−1. Specifically, if \(mc_{i,t}\) denotes the market capitalization of stock i in month t, compute momentum as

\[Mom_{i,t} = 100\frac{(mc_{i,t-1} −mc_{i,t-12})}{mc_{i,t-12}}\]

Briefly discuss the difference between computing momentum as the relative change in prices or as the relative change in market capitalization.* Since market cap is basically the stock price times volume, there is rarely a large distinction between the two. But the change in market cap will always reflect a change in the public value of a company whereas a change in stock price might be due to stock split or buybacks, which would have significant implications for the stock price but not the actual market capitalization (unless prices are given in adjusted form, e.g. as per yahoo! finance).

Create summary statistics for \(Mom_{i,t}\) as follows: Each month, compute the mean, standard deviation, minimum, fifth percentile, 25th percentile, median, 75th percentile, 95th percentile, and maximum values of the cross-sectional distribution of \(Mom_{i,t}\).

Then, report the time-series means for each cross-sectional value. What is the mean value of \(Mom_{i,t}\) in the average month? What is the cross-sectional standard deviation?

Mean SD Min Q5 Q25 Median Q75 Q95 Max
18.99 95.41 -89.13 -48.21 -16.28 5.576 32.99 117.9 3169

Does momentum exhibit a positive correlation with \(log(mc_{i,t}\)?*

  momentum log_mktcap
momentum 1 0.06729
log_mktcap 0.06729 1

Yes, there is a positive correlation coefficient of 0.067 between the momentum value and log of market capitalization.

Task 4.

Next, examine the relation between momentum and future stock returns. For that purpose, perform univariate portfolio sorts in the following way: Compute monthly portfolio breakpoints. Each month, use \(Mom_{i,t}\) as a sorting variable. The portfolio breakpoints are the deciles of \(Mom_{i,t}\) calculated using all stocks i in the sample during month t.

We need to create a function that is able to sort stocks into a number of portfolios. We use quantile() to compute breakpoints for n_portfolios. Then, we assign portfolios to stocks using the findInterval() function. The output of the following function is a new column that contains the number of the portfolio to which a stock belongs.

First, we create a function that is able to sort stocks into a number of portfolios based on their momentum score. The output one gets when running the function with a dataframe is a new column that contains the number of the portfolio in which the stock belongs.

## # A tibble: 6 x 6
## # Groups:   month [4]
##   permno month          ret mktcap_lag momentum portfolio
##    <dbl> <date>       <dbl>      <dbl>    <dbl> <fct>    
## 1  10000 1987-02-01  0           1.58   -86.8   1        
## 2  10000 1987-03-01 -0.385       1.58   -90.3   1        
## 3  10000 1987-04-01 -0.0625      0.973  -93.6   1        
## 4  10000 1987-05-01 -0.0667      0.912  -92.3   1        
## 5  10001 1987-02-01 -0.0741      6.69     8.66  6        
## 6  10001 1987-03-01  0.0368      6.19    -0.387 5

This shows a snip of the new portfolios sorts that have been created. Portfolio 1 has the lowest momentum and 10 has the highest.

To help understand the characteristics of the stocks comprising each of the \(Mom_{i,t}\) sorted portfolios, present the equal-weighted average values of \(Mom_{i,t}\) and \(mc_{i,t}\) for each of the 10 portfolios.

## # A tibble: 10 x 3
##    portfolio mom_mean mc_mean
##    <fct>        <dbl>   <dbl>
##  1 1           -53.8     288.
##  2 2           -30.4     899.
##  3 3           -17.6    1578.
##  4 4            -7.69   2092.
##  5 5             1.19   2479.
##  6 6            10.2    2745.
##  7 7            20.7    2813.
##  8 8            34.7    2727.
##  9 9            59.0    2226.
## 10 10          184.     1213.

This summary shows that the lowest portfolio sorts on momentum has the lowest market capitalization as well. Momentum is small for the largest companies. Momentum portfolios ranging from 6 to 8 has the highest market cap. The fact that the highest momentum companies are not the largest makes sense, since the largest companies might not be able to grow their business as much as smaller.

Compute value-weighted monthly excess returns for the decile portfolios. Report the average excess return, the CAPM alpha and the market beta for the 10 momentum sorted portfolios.

## # A tibble: 10 x 4
##    portfolio     alpha  beta excess_ret
##    <fct>         <dbl> <dbl>      <dbl>
##  1 1         -0.00676  1.67     0.00267
##  2 2         -0.00374  1.35     0.00392
##  3 3         -0.00109  1.17     0.00552
##  4 4         -0.000223 1.06     0.00574
##  5 5          0.000849 0.977    0.00637
##  6 6         -0.000661 0.957    0.00475
##  7 7          0.000668 0.942    0.00599
##  8 8          0.00151  0.939    0.00682
##  9 9          0.00149  1.02     0.00727
## 10 10         0.00312  1.22     0.0100

The plot indicates that the higher the momentum of a portfolio, the higher is the realized alpha. Alpha becomes negative in the bottom four portfolio sorts. The beta of the momentum portfolio is highest in the lowest decile, which might come from the fact that this is also the portfolios with the lowest market capitalization.

Finally, analyse the momentum strategy: a portfolio that goes long past winners (the highest decile) and short past losers (the lowest decile).

## `summarise()` has grouped output by 'month'. You can override using the
## `.groups` argument.
## # A tibble: 2 x 5
##   term        estimate std.error statistic  p.value
##   <chr>          <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)  0.00988   0.00308      3.21 1.40e- 3
## 2 mkt_excess  -0.448     0.0685      -6.54 1.20e-10

What do you conclude about the performance of the momentum strategy? Is the strategy market neutral (i.e., does it exhibit a market beta which is zero)? Does the strategy deliver abnormal excess returns (i.e., a positive alpha)?

The test statistics shows that is it possible to generate 0.1% alpha by having a short position in the lowest decile momentum stocks and a long position in highest decile momentum stocks. The alpha can be implied by the graph above, which shows that alpha is highest within the highest momentum stocks. The strategy is not market neutral as the beta is -0.45.

Task 5.

One of the main conclusions in the momentum literature is that the timing of the measurement of momentum plays a substantial role in the nature of the relation between momentum and future stock returns. To assess this in more detail and to examine whether momentum has the ability to predict returns further in the future than the next month, repeat the univariate portfolio sorts but this time using the k-month-ahead excess return as the outcome variable for values of k ∈{1, 3, 6, 12}.

For which time-horizon does the momentum deliver the highest risk-adjusted performance?

The momentum strategy delivers the highest risk-adjusted excess return with a 1-month ahead horizon. The 0-month ahead is included as a verification of the method, as this is the same number as earlier reported.

## `summarise()` has grouped output by 'month'. You can override using the `.groups` argument.
## `summarise()` has grouped output by 'month'. You can override using the `.groups` argument.
## `summarise()` has grouped output by 'month'. You can override using the `.groups` argument.
## `summarise()` has grouped output by 'month'. You can override using the `.groups` argument.
## `summarise()` has grouped output by 'month'. You can override using the `.groups` argument.
k ahead alpha
0 0.00988
1 0.1074
3 0.1048
6 0.106
12 0.01142

6. Most academic studies ignore real world costs and other forms of slippage when examining factors, which is likely a larger issue for momentum due to its higher turnover. The concern is that momentum is so costly to trade that its return premium is diminished in the real world.

First, based on your findings in 1. and 3., briefly explain why you think a momentum strategy could be costlier to trade than, say, a strategy based on size sorts.

When a given portfolio selection is based on i.e., past year market cap momentum, then the composition of the portfolio would change frequently as this is based purely on the performance of the stock value. Basically, since the analysis is made purely on activity from the past 12 months the momentum-portfolio composition will change often, since the market value of public companies tend to change frequently. Compared to a beta selection strategy where the analysis is made from i.e., 20 or 30 year historic stock price data, then the estimate would change much less frequently. This dramatically increases the need for trading activity and thus transaction costs of the momentum strategy. For the momentum strategy to be efficient, there will have to be frequent turnover, otherwise the strategy might not be able to catch it if a stock loses momentum after it’s traded.

Then, propose an alternative strategy that may be able to effectively capture the momentum premium but which at the same time delivers lower trading costs. Describe the strategy and implement it within the CRSP sample.

A portfolio that would capture a momentum effect but at the same time deliver lower trading costs, compared to the portfolio in 4, can be a portfolio with a strict no-short selling condition. Instead of buying the upper 10th quantile of momentum and selling the 1st quantile, we strictly go long in the upper 10th quantile. The idea is that this will result in a lower turnover, as assets enter and exit the portfolio less frequently.

  Total trades
momentum_original 293383
momentum_new 146497

#Report the resulting Sharpe-ratio and average turnover and compare to the baseline momentum strategy from exercise 4.

## `summarise()` has grouped output by 'month'. You can override using the
## `.groups` argument.
  Sharpe Ratio
Original portfolio 0.08715118
No short-portfolio 0.1488169