SigmaField

Practice Portfolios

Estimate a stock's beta and its uncertainty

Medium+25 pointsAbout 30 minutesPortfolios

The brief

A portfolio manager holds a mid-cap stock and hedges its market risk with index futures. The hedge ratio is the stock's beta. The risk committee wants to know whether the stock really moves more than the market, or whether a beta of 1 would do.

The data vendor sends two years of weekly closes for the stock and the index. The stock was suspended for one week, so one of its closes is missing.

Your task

  1. Write weekly_returns(prices): the simple returns PtPt−1−1\frac{P_t}{P_{t-1}} - 1 of a list of closes, as a NumPy array one shorter than the list. A missing close (None) makes both returns that touch it NaN. Raise ValueError for a close that is zero or negative, or for fewer than two closes.
  2. Write capm_beta(stock, market, rf): regress the stock's excess returns Rt−rfR_t - r_f on the market's, RM,t−rfR_{M,t} - r_f, by least squares, using only the weeks where both returns are known. rf is one number or one rate per week. Return a dict with alpha, beta, their standard errors se_alpha and se_beta, and n, the number of weeks used.
  3. Write beta_test(stock, market, rf, b=1.0, level=0.95): the t test of β=b\beta = b and a confidence interval for β\beta. Return a dict with t, the two-sided p_value, and the ends of the interval, low and high.

capm_beta and beta_test raise ValueError when the two series differ in length, or when fewer than three weeks have both returns. They also raise it when the market's excess return is the same every week. beta_test raises it when level is not strictly between 0 and 1.

The data

STOCK and INDEX hold 105 weekly closes, oldest first, with None for the stock's missing close. RF_WEEKLY is the risk-free rate per week: 4% a year divided by 52. The prices are synthetic.

Hint: Where to start

Case study 5.10.5 estimates a beta this way from monthly excess returns. Fit the line with a column of ones beside the market's excess returns, as in lesson 5.10.2.

Hint: Standard errors and the test

Lesson 5.10.3 gives se⁡(β^j)=s[(X⊤X)−1]jj\operatorname{se}(\hat{\beta}_j) = s\sqrt{[(X^\top X)^{-1}]_{jj}}, with s2=RSS⁡n−2s^2 = \frac{\operatorname{RSS}}{n - 2} for a line. The t statistic for β=b\beta = b is β^−bse⁡(β^)\frac{\hat{\beta} - b}{\operatorname{se}(\hat{\beta})}, with n−2n - 2 degrees of freedom.

Hint: The missing week

A return across the gap covers two weeks, so its variance is about twice the others'. Lesson 5.10.3 explains why changing variance makes the standard errors wrong. Drop both returns that touch the missing close.