Today we will calculate the CAPM beta of portfolio returns. This requires fitting a linear model to get visualization, and considering the significance of our results from the perspective of asset return.
Brief background introduction: Capital Asset Pricing Model (CAPM) is a model created by William Sharpe. It estimates the return of assets according to the market return and the linear relationship between assets and market return. This linear relationship is the beta coefficient of the stock.
The beta of calculating CAPM can be used as a good template for more complex models in a team’s work.
We will focus on one specific aspect of CAPM: β Value. As we pointed out above, beta coefficient refers to the result of the return of an asset to the market return. It captures the linear relationship between assets and markets
Before calculating the beta value of the portfolio, we need to find the monthly return of the portfolio.
pri <- getSymbols(symbols, src = 'yahoo', from = "2013-01-01", to = "2017-12-31", auto.assign = TRUE, warnings = FALSE) %>% monthly <- to.monthly(pri
We analyze two portfolio returns and one asset return together.
CAPM and market revenue
Our first step is to choose which asset to use as the agent of market return. We will choose spy ETF and regard the S & P 500 index as market return.
Let’s calculate the market return of spy. Note that the start date is “January 1, 2013” and the end date is “December 31, 2017”, so we will use the income of five years.
getSymbols("SPY", src = 'yahoo', from = "2013-01-01", to = "2017-12-31", auto.assign = TRUE, warnings = FALSE) %>% return <- Return.calculate(monthl, method = "log") %>%
We also want a data. Frame object for market returns and convert the XTS object.
returns_tidy <- returns_xts %>% tk\_tbl(preserve\_index = TRUE, rename_index = "date") %>%
We have a market\_ returns\_ Tidy object. We ensure that its periodicity is consistent with the portfolio cycle
monthly %>% mutate(market\_returns = returns\_tidy$returns) %>% head()
If the periodicity is inconsistent, change () throws an error.
Calculate CAPM beta
Calculation of portfolio β Value, first let’s look at this equation.
investment portfolio β Equal to the covariance of portfolio return and market return divided by the variance of market return.
We can use cov to calculate the numerator, that is, the covariance between portfolio and market return, and VaR to calculate the denominator.
Our portfolio β The value is equal to.
this β The value is quite close to 1. After all, spy is an important part of this portfolio.
We can also calculate the combined beta value by finding the beta value of each of our assets and multiplying it by the asset weight. That is, another equation for portfolio beta is the weighted sum of asset beta values.
In order to use this method in R, we first need to find the value of each of our assets β Value.
We need to return the rate of return of each asset to the market rate of return. We can use LM () to regress asset 1, then use LM () to regress asset 2, and so on. But it would be unrealistic if we had a portfolio of 50 assets. Instead, we write a code flow, use map () to return all our assets, and calculate betas with one call.
We will start from our returns_ Long starts with a neat data frame.
Nest (- Asset) has changed our data framework, so there are two columns: one is called asset, which saves the name of our asset, and the other is called data, which saves the name of each assetprofit
List. Now we haveprofit
The list is "nested" in one column.
Now we can use map () to apply a function to each nested list and store the result in a new column through the mutate () function. The entire pipeline command is mutate (model = map (, ~ lm())
long %>% mutate( map(data, ~ lm(returns ~ returns) assets
We now have three columns: Previous assets, previous data, and the model we just added. The model column is the result of our regression for each asset LM（ )。 These results are for each of our assets β Value and intercept.
Let’s tidy up our results with the tidy () function. We want to apply this function to our model columns and will use the combination of mutate () and map () again.
mutate(model = map(data, ~ lm(returns ~ returns)) %>% mutate(model = map(model, tidy))
We are close now, but there are nested data frames in the model bar. They are well formatted data frames.
However, I don’t like the end result of nested data frames, so we adjust the model columns.
mutate(model = map(data, ~ lm(returns ~returns)) %>% unnest(model)
Now, it looks neat. We will do further cleaning and remove the intercept because we need the beta value.
mutate(map( ~ lm(returns ~ returns)) %>% filter(term == "returns") %>%
A quick check should find that spy is 1 with its own beta.
bet %>% filter(asset == "SPY")
Now let’s look at how our portfolio of these assets affects the portfolio β Value.
Let’s allocate the weight of the portfolio according to the above selection.
Now we can use these weights to obtain the value of our portfolio β Value, based on the value of each asset β Value.
w\[1\] * beta$estimate\[1\] + w\[2\] * beta$estimate\[2\] + w\[3\] * beta$estimate\[3\] + w\[4\] * beta$estimate\[4\] + w\[5\] * beta$estimate\[5\]
This beta value is the same as that calculated by the covariance / variance method above. Now we know that the covariance of portfolio return and market return divided by the variance of market return is equal to the weighted estimation obtained by regressing the return of each asset to the market return.
XTS calculates the beta value of CAPM
Use the built-in CAPM. Beta() function. This function requires two parameters: we want to calculate its β The return on the value of the portfolio (or any asset), as well as the market return.
Calculate CAPM beta in tidyverse
First, we will use dplyr to capture our portfolio beta. We’ll do some visualizations later, but now we’ll extract the portfolio β Value.
To calculate the beta value, we call do (model = lm()). Then we use the tidy () function to make the model results easier to understand.
do(model = lm(returns ~return)) %>% mutate(term = c("alpha", "beta"))
Calculation of CAPM by tidyquant β value
Use the tidyquant function. The CAPM. Beta () function can be applied to a data framework.
tq_performance(Ra = returns, Rb = return, performance_fun = CAPM.beta)
Stable results and beta values close to 1 are ideal because 25% of our portfolio is allocated to the S & P 500 index.
Visualization of CAPM beta
Before visualization, we need to calculate the return of the portfolio, and then calculate the CAPM of the individual assets involved in the portfolio β。
Visualize the relationship between portfolio return, risk and market return
CAPM β Value tells us the linear relationship between portfolio return and market return. It also tells us the risk of the portfolio — the volatility of the portfolio relative to the market. Before we discuss the beta coefficient itself, let’s look at the comparison between the expected monthly return of our assets and the monthly risk of our individual assets.
ggplot(aes(x = sdev, y = ex_return)) + geom_point(size = 2) +
What is the position of our portfolio on this scatter chart? Let’s use geom_ Point () adds it to ggplot ().
ggplot(aes(x = stdev, y = expreturn)) + geom_point(size = 2) + geom_point(aes(x = sd(returns),
The return / risk of our portfolio looks good, although the expected return of the SP500 index is higher, but the risk is higher. In the past five years, it has been very difficult to beat the market. EEM and EFA have higher risk and lower expected return, while IJs has higher risk and higher expected return.
Generally speaking, scatter is to provide some return risk background for our portfolio. It is not a direct part of CAPM.
Next, let’s turn to CAPM more directly and use the scatter diagram of market return on the x-axis and portfolio return on the y-axis to intuitively show the relationship between our portfolio and the market. First, we will add market returns to our portfolio tibble by calling mutate(). Then we set our X and Y axes with ggplot().
ggplot(aes(x = market_returns, y = returns)) + geom_point() +
This scatter plot is similar to β The calculation conveys the same strong linear relationship. We can use geom_ Smooth () adds a simple regression line to it.
ggplot(aes(x = market_returns, y = returns)) + geom_point() + geom_smooth(method = "lm") +
Before concluding the analysis of CAPM beta, let’s explore how to create more interesting visual data.
The following code block starts with the model result of LM (), which returns our portfolio return to the market return. We store the results in a list column called model. Next, we call fragment () to add the predicted value to the original dataset and return a tibble.
These predictions will be placed in the. Fitted column.
do(model = lm(returns ~ returns)%>% augment(model) %>% mutate(date = date) head(portfolio_model)
Let’s use ggplot () to see how well the fitted return value matches the actual return value.
portfolio\_model\_augmented %>% ggplot(aes(x = date)) + geom_line(aes(y = returns, color = "actual returns")) + geom_line(aes(y = .fitted, color = "fitted returns")) + scale\_colour\_manual("", values = c("fitted returns" = "green", "actual returns" = "cornflowerblue")) + xlab("date") + ggtitle("Fitted versus actual returns")
These monthly returns and fitting values seem to coincide well. Let’s convert the real income and fitting income into unitary growth and make the same comparison.
ggplot(aes(x = date)) + geom_line(aes()) + geom_line(aes)) +
Our fitted growth well predicted our real growth, although most of the time, the real growth was lower than the forecast.
The Capital Asset Pricing Model: Theory and Evidence Eugene F. Fama and Kenneth R. French, The Capital Asset Pricing Model: Theory and Evidence, The Journal of Economic Perspectives, Vol. 18, No. 3 (Summer, 2004), pp. 25-46
Most popular insights