原文鏈接:http://tecdat.cn/?p=22588
原文出處:拓端數據部落公眾號
今天我們將計算投資組合收益的CAPM貝塔。這需要擬合一個線性模型,得到可視化,從資產收益的角度考慮我們的結果的意義。
簡單的背景介紹,資本資產定價模型(CAPM)是由威廉·夏普(William Sharpe)創建的一個模型,它根據市場收益和資產與市場收益的線性關系來估算資產的收益。這種線性關系就是股票的貝塔系數。
計算CAPM的betas可以作為一個團隊工作中更復雜的模型的一個很好的模板。
我們將專注於CAPM的一個特定方面:β值。正如我們上面所指出的,貝塔系數是指一項資產的收益率回歸到市場收益率的結果。它抓住了資產與市場之間的線性關系
在計算該投資組合的貝塔值之前,我們需要找到投資組合的月度收益率。
-
-
pri <-
-
getSymbols(symbols, src = 'yahoo',
-
from = "2013-01-01",
-
to = "2017-12-31",
-
auto.assign = TRUE, warnings = FALSE) %>%
-
monthly <- to.monthly(pri
我們將兩個投資組合收益和一個資產收益一起分析。
CAPM和市場收益
我們的第一步是做出選擇,用哪種資產作為市場收益的代理,我們將選擇SPY ETF,將標准普爾500指數視為市場收益。
讓我們計算一下SPY的市場收益。注意開始日期是 "2013-01-01",結束日期是 "2017-12-31",所以我們將使用五年的收益。
-
getSymbols("SPY",
-
src = 'yahoo',
-
from = "2013-01-01",
-
to = "2017-12-31",
-
auto.assign = TRUE,
-
warnings = FALSE) %>%
-
-
return <-
-
Return.calculate(monthl, method = "log") %>%
我們還想要一個市場收益率的data.frame對象,並轉換xts對象。
-
returns_tidy <-
-
returns_xts %>%
-
tk_tbl(preserve_index = TRUE, rename_index = "date") %>%
我們有一個market_returns_tidy對象。我們確保它的周期性與投資組合周期一致
-
monthly %>%
-
mutate(market_returns = returns_tidy$returns) %>%
-
head()
如果周期性不一致,mutate()就會拋出一個錯誤。
計算CAPM貝塔
計算投資組合的β值,首先讓我們看看這個方程式。
投資組合β等於投資組合收益和市場收益的協方差,除以市場收益的方差。
我們可以用cov計算分子,即投資組合和市場收益的協方差,用var計算分母。
我們的投資組合β值等於。
cov(monthly,returns)/var(returns)
這個β值相當接近於1,畢竟SPY是這個投資組合的一個重要部分。
我們也可以通過找到我們每個資產的貝塔值,然后乘以資產權重來計算組合貝塔值。也就是說,投資組合貝塔值的另一個方程式是資產貝塔值的加權和。
為了在R中使用這種方法,我們首先要找到我們每個資產的β值。
我們需要將每項資產的收益率回歸到市場收益率上。我們可以用lm()對資產1進行回歸,然后再用lm()對資產2進行回歸,等等。但如果我們有一個50個資產的投資組合,這將是不現實的。相反,我們寫一個代碼流程,使用map()來回歸我們所有的資產,並通過一次調用計算betas。
我們將從我們的returns_long整齊的數據框架開始。
assets
nest(-asset)改變了我們的數據框架,所以有兩列:一列叫做asset,保存我們的資產名稱,一列叫做data,保存每個資產的
收益列表。現在我們已經將
收益列表 "嵌套 "在一列中。
現在我們可以使用map()對每個嵌套的列表應用一個函數,並通過mutate()函數將結果存儲在一個新的列中。整個管道命令是mutate(model = map(, ~ lm())
-
long %>%
-
-
mutate( map(data, ~ lm(returns ~ returns)
-
assets
我們現在有三列:之前的資產,之前的數據,以及我們剛剛添加的模型。模型一欄是我們對每項資產進行回歸的結果lm( )。這些結果是我們每個資產的β值和截距。
讓我們用tidy()函數整理一下我們的結果。我們想將該函數應用於我們的模型列,並將再次使用mutate()和map()組合。
-
mutate(model = map(data, ~ lm(returns ~ returns)) %>%
-
mutate(model = map(model, tidy))
我們現在已經很接近了,但是模型欄里有嵌套的數據框。它們是格式化很好的數據框架。
beta_assets$model
不過,我不喜歡最終出現嵌套的數據框架,所以我們調整模型列。
-
mutate(model = map(data, ~ lm(returns ~returns)) %>%
-
unnest(model)
現在,這看起來比較整潔。我們將做進一步的清理,去掉截距,因為我們需要貝塔值。
-
-
mutate(map( ~ lm(returns ~ returns)) %>%
-
filter(term == "returns") %>%
快速檢查應該發現SPY與自身的貝塔為1。
bet %>% filter(asset == "SPY")
現在讓我們看看我們對這些資產的組合如何影響投資組合的β值。
讓我們按照上面的選擇來分配投資組合的權重。
現在我們可以使用這些權重來獲得我們的投資組合的β值,基於每個資產的β值。
-
-
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]
-
這個貝塔值與我們上面用協方差/方差法計算的是一樣的,現在我們知道投資組合收益和市場收益的協方差除以市場收益的方差等於我們把每項資產的收益回歸到市場收益上得到的加權估計。
xts計算CAPM的Beta值
使用內置CAPM.beta()函數。該函數需要兩個參數:我們希望計算其β值的投資組合(或任何資產)的收益,以及市場收益。
CAPM.beta(_monthly, returns_xts)
在Tidyverse中計算CAPM Beta
首先,我們將使用dplyr來抓取我們的投資組合貝塔。我們稍后會進行一些可視化,但現在將提取投資組合的β值。
為了計算貝塔值,我們調用do(model = lm())。然后我們使用tidy()函數,使模型結果更容易看懂。
-
do(model = lm(returns ~return)) %>%
-
mutate(term = c("alpha", "beta"))
Tidyquant計算CAPM的β值
使用tidyquant函數。能夠將CAPM.beta()函數應用於一個數據框架。
-
-
tq_performance(Ra = returns,
-
Rb = return,
-
performance_fun = CAPM.beta)
穩定的結果和接近1的貝塔值是比較理想的,因為我們的投資組合有25%分配給標准普爾500指數。
CAPM beta的可視化
在可視化之前,我們需要計算投資組合的收益,然后計算投資組合涉及到的單個資產的CAPMβ。
可視化投資組合收益、風險和市場收益之間的關系
CAPM的β值告訴我們投資組合收益與市場收益之間的線性關系。它還告訴我們投資組合的風險性--投資組合相對於市場的波動程度。在我們討論貝塔系數本身之前,讓我們先看看我們的資產的預期月度收益與我們個別資產的月度風險的對比。
-
-
ggplot(aes(x = sdev, y = ex_return)) +
-
geom_point(size = 2) +
我們的投資組合在這個散點圖上的位置如何?讓我們用geom_point()把它添加到ggplot()中。
-
-
ggplot(aes(x = stdev, y = expreturn)) +
-
geom_point(size = 2) +
-
geom_point(aes(x = sd(returns),
我們的投資組合收益/風險看起來都不錯,盡管SP500指數的預期收益率更高,只是風險更大一些。在過去的五年里,要戰勝市場是很困難的。EEM和EFA有較高的風險和較低的預期收益,而IJS有較高的風險和較高的預期收益。
一般來說,散點是為我們的投資組合提供一些收益-風險的背景。它不是CAPM的直接組成部分。
接下來,讓我們更直接地轉向CAPM,用X軸上的市場收益和Y軸上的投資組合收益的散點圖來直觀地顯示我們的投資組合與市場之間的關系。首先,我們將通過調用mutate()將市場收益添加到我們的投資組合tibble中。然后,我們用ggplot()設置我們的x軸和y軸。
-
-
ggplot(aes(x = market_returns, y = returns)) +
-
geom_point() +
這個散點圖與β計算傳達了相同的強線性關系。我們可以用geom_smooth()給它添加一個簡單的回歸線。
-
ggplot(aes(x = market_returns, y = returns)) +
-
geom_point() +
-
geom_smooth(method = "lm") +
線性回歸
在結束CAPM beta的分析之前,讓我們來探討一下如何創建更有趣的可視化數據。
下面的代碼塊從lm()的模型結果開始,它將我們的投資組合收益率回歸到市場收益率上。我們將結果存儲在一個名為model的列表列中。接下來,我們調用augment(),將預測值添加到原始數據集,並返回一個tibble。
這些預測值將被放在.fitted列中。
-
-
do(model = lm(returns ~ returns)%>%
-
augment(model) %>%
-
mutate(date = date)
-
head(portfolio_model)
讓我們用ggplot()來看看擬合的收益值與實際收益值的匹配程度。
-
-
ggplot(aes(x = date)) +
-
geom_line(aes(y = returns, color = "actual returns")) +
-
geom_line(aes(y = .fitted, color = "fitted returns")) +
-
scale_colour_manual("",
這些月度收益和擬合值似乎重合得不錯。讓我們把實際收益和擬合收益都轉換為一元的增長,並進行同樣的比較。
-
-
ggplot(aes(x = date)) +
-
geom_line(aes()) +
-
geom_line(aes)) +
我們的擬合增長很好地預測了我們的實際增長,盡管在大部分時間里,實際增長低於預測值。
參考文獻
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
最受歡迎的見解
1.在python中使用lstm和pytorch進行時間序列預測
2.python中利用長短期記憶模型lstm進行時間序列預測分析