17.24. Assigment 5#

Instructions: This problem set should be done in group

Answer each question in the designated space below

After you are done. save and upload in blackboard.

Please check that you are submitting the correct file. One way to avoid mistakes is to save it with a different name.

17.25. Write your name and simon email#

Please write names below

  • [Name]:

  • [email]:

17.26. Discussion Forum Assignment#

Do the Factor investing assignment

https://edstem.org/us/courses/30665/discussion/1987589

17.27. Exercises#

Exercise 1

Start by importing pandas, numpy, maplotlib, and loading the data set.

The dataset has address

url='https://github.com/amoreira2/Lectures/blob/main/assets/data/Assignment5.xlsx?raw=true'

I strongly recommend you download first and look at the data set.

This file contains multiple sheets, you should use read_excel to get the data that contains the 49 value-weighted industry portfolios.

See here:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html .

Do the followings:

  1. Import this dataframe as df_ind

    • Use “sheet_name” to select the desired excel sheet.

    • Use “skip_rows” to skip the initial rows before the data.

    • Figure out what is the code for missing value and change the option na_values appropriately

    • If you look at the excel file you will see that there are other data sets stacked horizontally. Use the usecols option to select the range of columns you want imported

    • You can take a look at Lab3 material for some examples of importing excel data and using these options.

  2. Change the name of the column with the date information to date

  3. Use to_datetime so python understand the column date as a datetime object (you will have to use the option format)

  4. Set date as index

  5. Call df_ind.info() so you check all the tasks were accomplished.

  6. In the next cell, call df_ind.head()

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
from pandas.tseries.offsets import MonthEnd

# your code below
df_inde.info()
df_ind.head()

Exercise 2. Advanced date manipulation

  1. convert the date from the start of the month to end of the month.

  2. call df_ind.head() and verify it works

Hint:

# your code below

df_ind.head()

Exercise 3. Importing risk-free rate

  1. In this same file there is another sheet with market returns and the risk-free rate. Import them as df_rmrf by following all the steps you did in the above two questions

  2. Call df_rmrf.info() so you check all the tasks were accomplished.

  3. In the next cell, call df_rmrf.head()

# your code below
df_rmrf.info()
df_rmrf.head()

Exercise 4. Constructing excess returns A

  1. for the industry Agric, construct the excess return by subtracting the risk-free rate RF from it.

  2. compute the mean of this excess return.

  3. print it along with the mean of the raw returns and the risk free rate to compare

# your code below

Exercise 5. Constructing excess returns B

  1. construct excess returns for all portfolio by subtracting the risk-free rate from all of columns at the same time

  2. name the new data frame df_inde ( for excess returns)

Hint:

  • You can do that using the method .subtract() with the option axis to tell along which dimension

  • Go ahead , google “pandas subtract” to see how this works

# your code below 

df_inde.head()

Exercise 6. Drop missing observations

You may notice that excess returns of some industries are not available at the beginning of the sample.

If we want all the industries to have same period of data in df_inde, we need to drop some observations.

Do the followings:

  1. Use method dropna to drop rows in df_inde if ANY industry is missing.

  2. After that, print(df_inde.shape) to see the changes in the length.

Hint

  • when you call dropna function, use axis and how option to drop missing values if ANY industry is missing

# your code below

Exercise 7. Moments

We will now estimate the risk-premium in each of these portfolio and the covariance between these portfolios.

Do the followings:

  1. using the method mean on the excess return data frame to obtain a vector of average excess returns which we will use as our ESTIMATE for these portfolio risk-premiums. call this vector ERe

  2. use cov method to estiamte the covariance of excess returns, call this CovRe, which we will use as our ESTIMATE for the TRUE covariance matrix between these portfolios

  3. Print ERe and CovRe

# your code below
ERe.head()
CovRe.head()

Exercise 8. Storing the weights

Lets create a storage for our weights.

Use the pd.DataFrame function to create an empty dataframe with name Weights which has as index the name of the different industries in df_ind and column names as ‘W1’ and ‘W2’.

# your code below

Weights.head()

Exercise 9. Weighting scheme 1

We will now find the weights by applying the formula

\[ W=E[R^e]@Var(R^e)^{-1} \]

For that you need to inverse the covariance matrix CovRe you just estimated.

You do that using the function np.linalg.inv.

Attribute the weight vector to the column ‘W1’

# your code below

Weights.head()

Exercise 10. Weighting scheme 2

We will now find the weights by applying the formula

\[ W= \frac{\mathbf{1} @Var(R^e)^{-1}}{\mathbf{1} @Var(R^e)^{-1} @ \mathbf{1}'} \]

where \(\mathbf{1}\) is a vector of 1 that has the length same as the number of assets.

Attribute this vector to the column ‘W2’

# your code below

Weights.head()

Exercise 11. What mathematical problems weights W1 and W2 are solutions to?

(This will not be graded. )

# Answer here: 

Exercise 12. Strategy returns

Use weight W1 and W2 to construct the time series of the strategy returns

The output should be one dataframe called df_wR which rows are the dates of df_inde and in the columns we have the names W1 and W2 and the values are the strategy return implied by the respective weights.

# your code below

df_wR.head()

Exercise 13. Sharpe Ratios

A key measue of risk-reward is the so called Sharpe ratio.

the Sharpe ratio is a ratio of the average excess return of a strategy relative to it’s standard deviation.

Do the followings:

  1. compute the Sharpe ratio for both strategies above and report them in annualized units

  2. comment on what you find. is the difference between these Sharpe ratios as expected? explain.

# your code below
# your comments below 

Exercise 14. Normalization

While strategy 2 was solved by imposing a constraint on weights so that they add up to 1, strategy 1 does not impose any constraint on the weights as it imposes a constraint on the expected return target

Imposing a constraint is a choice because we are working with excess returns, so the weights do not need to add up to 1 because these assets cost zero–i.e. each asset is a strategy that is self funded, which invests in the asset with money borrowed at the risk-free rate.

This is all fine and good, but it means that leverage that comes out of the weights \(W1=E[E^e]@Var(R^e)^{-1} \) is not determinate. Any set of weights proportional to W1 will achieve the same Sharpe Ratio.

In the exercise below we will trace the entire frontier by changing this proportionality constant.

Do the followings:

  1. transform the weights W1 by multiplying it by a constant (your job is to figure out what this constant must be) so that the new strategy associated with these new weights (call it W3) have the same in sample volatility as the strategy associated with W2.

  2. record this new strategy in df_wR.

  3. plot the cumulative returns (as seen for example in Chapter 7) of strategies W2 and W3. Note that stock returns from the data are in percentages, so you may need to rescale the portfolio returns to the unit of 1 when you compute the cumulative returns.

  4. given what you know about their Sharpe Ratios, are the results surprising? explain

Hint: $\( K =\sigma(R^e_{p2}) = c\cdot \sigma( R^e_{p1}) = \sigma(c\cdot R^e_{p1}) = \sigma( R^e_{p3}) \)$

\[ c = \sigma(R^e_{p2}) / \sigma( R^e_{p1}) \]
\[ R^e_{p3} = c\cdot R^e_{p1} = (\sigma(R^e_{p2}) / \sigma( R^e_{p1})) \cdot R^e_{p1} \]
# your code below
# your explanation below

Exercise 15. The Efficient Frontier 1

We will now construct the investment frontier using portfolio strategy W1.

The key idea is that any portolio that is in the frontier must have returns of the form

\[\begin{split} \begin{align} r^{frontier} &= w \cdot r^f+(1-w)(W1 @ R) \\ &= r^f+(1-w)(W1 @ (R-rf)) \\ &= r^f+w (W1 @ R^{e}) \end{align} \end{split}\]

In terms of weights, the frontier is of the form \([1,w*W1]\) that is, a weight 1 on the risk-free rate plus a weight \(w*W1\) on the long-short portfolios \(R^e\), where \(w\) is any scalar greater than 0 and \(W1\) is the weight that solves the problem you described in question 10.

This means that we can write any portfolio in the efficient frontier as:

\[E[R^{frontier}]=r^f+w W1 E[R^e]\]
\[STD[R^{frontier}]=STD[r^f+wW1 R^{e}]=wSTD[W1 R^{e}]\]

Thus to trace-out the frontier you will need the mean and the volatility of the portfolio constructed with weights W1

Do the followings to plot the frontier:

  1. plot the mean-standard deviation efficient frontier by varying the weight \(w\) in the expression above from zero to some positive value \(\bar{w}\)

  2. pick \(\bar{w}\) consistent with an annual volatility equal to 20%, so that it traces out the frontier up to the point that you have a volatility of 20%.

  3. the plot should have \(wSTD[W1 R^{e}]\) in the x-axis and \(r^f+w W1 E[R^e]\) in the y-axis.

  4. both mean and standard deviation should be annualized.

Hint: find the upper bound of \(w\) and then use np.linspace to create a array of \(w\).

# your code below

Exercise 16. Risk free rates?

Which risk-free rate should you use in the question above? The historical average? The current one? What do you think?

# Answer here: 

Exercise 17. The Efficient frontier 2

For contrast, plot the means and standard deviations of the individual industry portfolio in the same plot above. So these will be additional 49 points in the same plot.

You can simply copy the code from the question (EF1) above and add the points here.

Hint: you might find plt.scatter useful.

# your code below

Exercise 18. The Efficient frontier 3

Plot portfolio W2 in the mean-standard-deviation plot as well. To do that we will follow the same strategy we did for the portfolio above

\[E[R2]=r^f+E[W2 @R^{e}]\]
\[STD[R2]=STD[W2 @ R^{e}]\]

Again simply copy the code of EF2 and add the additional code.

# your code below

Exercise 19. The Efficient frontier 4

Explain the followings:

  1. why we first take out the risk-free rate to compute average excess returns and the covariance matrix?

  2. if instead, we do not take the risk-free rate out, and later add it back

    2.1 would the weights for strategy 2 be meaningfully impacted?

    2.2 would the weights for strategy 1 be meaningfully impacted?

# Answer here: