套件
# 資料整理工具
library(dplyr)
# 繪圖套件
library(plotly)
# 時間序列資料的相關套件
library(xts)
# 財金金融套件
# 安裝 PerformanceAnalytics 之前的準備動作
# sudo apt-get install libblas-dev liblapack-dev
library(PerformanceAnalytics)
library(quantmod)
library(TTR)setwd("~/TEJ_08170442")動手做:任選兩隻台股(2011~2020),探索其各年的風險係數。
金融-金控:
先各別整理兩台股之收益率及風險溢酬,最後再合併同時研究兩台股之差異
為何選擇金融金控產業?
但是!因為新型冠狀病毒(COVID-19)的關係,重創股價,非常值得探討
為何選擇這兩台股?(2880 華南金、2891 中信金)
資料顯示,台灣六大金融股2020報酬率如下:
前三家為民營股金控銀行,後三家為官股金控銀行,各挑選一家民營股金控、官股金控銀行作為研究,故挑選報酬率最低的2880 華南金以及2891 中信金
大盤是什麼?
大盤是指台灣股市的整體表現,也可以叫做「加權指數」
例如:
alpha(α)、beta(β)是什麼?
α是總風險扣除系統性風險,額外創造的 超額報酬
例如:
β是衡量系統性風險及大盤連動性,也就是指數的波動幅度
例如:
通常以1作為臨界點
alpha(α)、beta(β)之間的關係?
低Beta(β)高Alpha(α)的股票往往反映企業有優質且穩定的基本因素,讓投資者即使碰上市況不景亦可做到攻守兼備
α和β是歷史模型估算,過去並不代表將來,所以α和β高低並沒有絕對的好壞,只是一個參考
α和β不能單獨拆開看,必須一起評估,一起看才有意義
# 下載資料
# 大盤指數:^TWII
# 華南金:2880.TW
loadSymbols(Symbols=c("^TWII", "2880.TW"),
from="2011-01-01", to="2020-12-31",
auto.assign=TRUE) # 這一定要設定## 'getSymbols' currently uses auto.assign=TRUE by default, but will
## use auto.assign=FALSE in 0.5-0. You will still be able to use
## 'loadSymbols' to automatically load data. getOption("getSymbols.env")
## and getOption("getSymbols.auto.assign") will still be checked for
## alternate defaults.
##
## This message is shown once per session and may be disabled by setting
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
## Warning: ^TWII contains missing values. Some functions will not work if objects
## contain missing values in the middle of the series. Consider using na.omit(),
## na.approx(), na.fill(), etc to remove or replace them.
## Warning: 2880.TW contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## [1] "^TWII" "2880.TW"
# 注意:^TWII 下載後存入 TWII 中
# 轉換成正常的變數名稱
#TWII = get("TWII")
TW2880 = get("2880.TW")# 處理大盤資料
str(TWII)## An 'xts' object on 2011-01-03/2020-12-30 containing:
## Data: num [1:2455, 1:6] 9040 9045 9014 8866 8905 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:6] "TWII.Open" "TWII.High" "TWII.Low" "TWII.Close" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 2
## $ src : chr "yahoo"
## $ updated: POSIXct[1:1], format: "2021-11-14 18:11:42"
# 去掉遺失值
TWII = na.omit(TWII)
colnames(TWII) = c("Open", "High", "Low", "Close", "Volume", "Adjusted")
str(TWII)## An 'xts' object on 2011-01-03/2020-12-30 containing:
## Data: num [1:2444, 1:6] 9040 9045 9014 8866 8905 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:6] "Open" "High" "Low" "Close" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 3
## $ src : chr "yahoo"
## $ updated : POSIXct[1:1], format: "2021-11-14 18:11:42"
## $ na.action: 'omit' int [1:11] 248 390 1111 1167 1254 1334 1403 1413 1414 1509 ...
## ..- attr(*, "index")= num [1:11] 1.33e+09 1.34e+09 1.44e+09 1.44e+09 1.45e+09 ...
head(TWII)## Open High Low Close Volume Adjusted
## 2011-01-03 9039.63 9041.32 8994.50 9025.30 5067400 9025.267
## 2011-01-04 9045.11 9046.18 8988.58 8997.19 5270400 8997.157
## 2011-01-05 9014.32 9027.16 8812.36 8846.31 5796600 8846.277
## 2011-01-06 8866.23 8883.21 8813.63 8883.21 4362200 8883.177
## 2011-01-07 8905.25 8907.11 8738.93 8782.72 4500800 8782.688
## 2011-01-10 8798.05 8817.88 8762.50 8817.88 2885200 8817.848
# 轉成資料框
TWII.df = data.frame(Date=index(TWII),coredata(TWII))
head(TWII.df)## Date Open High Low Close Volume Adjusted
## 1 2011-01-03 9039.63 9041.32 8994.50 9025.30 5067400 9025.267
## 2 2011-01-04 9045.11 9046.18 8988.58 8997.19 5270400 8997.157
## 3 2011-01-05 9014.32 9027.16 8812.36 8846.31 5796600 8846.277
## 4 2011-01-06 8866.23 8883.21 8813.63 8883.21 4362200 8883.177
## 5 2011-01-07 8905.25 8907.11 8738.93 8782.72 4500800 8782.688
## 6 2011-01-10 8798.05 8817.88 8762.50 8817.88 2885200 8817.848
# 處理華南金資料
# 去掉遺失值
TW2880 = na.omit(TW2880)
colnames(TW2880) = c("Open", "High", "Low", "Close", "Volume", "Adjusted")
str(TW2880)## An 'xts' object on 2011-01-03/2020-12-30 containing:
## Data: num [1:2450, 1:6] 14.2 14.3 13.9 13.4 13.5 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:6] "Open" "High" "Low" "Close" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 3
## $ src : chr "yahoo"
## $ updated : POSIXct[1:1], format: "2021-11-14 18:11:43"
## $ na.action: 'omit' int [1:5] 1254 1334 1403 1509 1578
## ..- attr(*, "index")= num [1:5] 1.45e+09 1.46e+09 1.47e+09 1.49e+09 1.50e+09
head(TW2880)## Open High Low Close Volume Adjusted
## 2011-01-03 14.19921 14.34381 14.05462 14.25705 30333029 10.394250
## 2011-01-04 14.25705 14.25705 13.91002 13.93894 20770102 10.162331
## 2011-01-05 13.93894 14.02570 13.30273 13.44732 34703862 9.803907
## 2011-01-06 13.36056 13.56300 13.30273 13.47624 16207353 9.824991
## 2011-01-07 13.47624 13.47624 12.98462 13.10029 24862572 9.550904
## 2011-01-10 13.10029 13.21597 13.01354 13.12921 21482437 9.571988
# 轉成資料框
TW2880.df = data.frame(Date=index(TW2880),coredata(TW2880))
head(TW2880.df)## Date Open High Low Close Volume Adjusted
## 1 2011-01-03 14.19921 14.34381 14.05462 14.25705 30333029 10.394250
## 2 2011-01-04 14.25705 14.25705 13.91002 13.93894 20770102 10.162331
## 3 2011-01-05 13.93894 14.02570 13.30273 13.44732 34703862 9.803907
## 4 2011-01-06 13.36056 13.56300 13.30273 13.47624 16207353 9.824991
## 5 2011-01-07 13.47624 13.47624 12.98462 13.10029 24862572 9.550904
## 6 2011-01-10 13.10029 13.21597 13.01354 13.12921 21482437 9.571988
# 算出收益率
# Rm
Rm2880 = quantmod::periodReturn(TWII$Close, period="daily",
type='arithmetic')
colnames(Rm2880) = "Rm"
head(Rm2880)## Rm
## 2011-01-03 0.000000000
## 2011-01-04 -0.003114509
## 2011-01-05 -0.016769775
## 2011-01-06 0.004171275
## 2011-01-07 -0.011312379
## 2011-01-10 0.004003333
Rm2880 = Rm2880[-1]
# Rq
Rq2880 = quantmod::periodReturn(TW2880$Close, period="daily",
type='arithmetic')
colnames(Rq2880) = "Rq"
head(Rq2880)## Rq
## 2011-01-03 0.000000000
## 2011-01-04 -0.022312327
## 2011-01-05 -0.035269745
## 2011-01-06 0.002150540
## 2011-01-07 -0.027897025
## 2011-01-10 0.002207508
Rq2880 = Rq2880[-1]# 合併資料,只取共同日期
# all=FALSE ==> 只取共同日期
Ret2880<-merge(Rm2880, Rq2880,all=FALSE)
head(Ret2880)## Rm Rq
## 2011-01-04 -0.003114509 -0.022312327
## 2011-01-05 -0.016769775 -0.035269745
## 2011-01-06 0.004171275 0.002150540
## 2011-01-07 -0.011312379 -0.027897025
## 2011-01-10 0.004003333 0.002207508
## 2011-01-11 0.012869360 0.011013228
利用台銀一年期存款利率。
# 讀取資料
twRf = read.csv("./ch20_twbank10.csv")
str(twRf)## 'data.frame': 120 obs. of 2 variables:
## $ ym : int 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 ...
## $ ret: num 1.21 1.21 1.21 1.3 1.3 1.3 1.38 1.38 1.38 1.38 ...
head(twRf)## ym ret
## 1 10001 1.21
## 2 10002 1.21
## 3 10003 1.21
## 4 10004 1.30
## 5 10005 1.30
## 6 10006 1.30
# 資料整理
# 利率
twRf$ret = twRf$ret*0.01
# 日期
year = as.character(as.numeric(substr(as.character(twRf$ym),1,3))+1911)
head(year)## [1] "2011" "2011" "2011" "2011" "2011" "2011"
month = substr(as.character(twRf$ym),4,5)
head(month)## [1] "01" "02" "03" "04" "05" "06"
#
twRf$ym2 = paste(year, month, sep="-")
head(twRf)## ym ret ym2
## 1 10001 0.0121 2011-01
## 2 10002 0.0121 2011-02
## 3 10003 0.0121 2011-03
## 4 10004 0.0130 2011-04
## 5 10005 0.0130 2011-05
## 6 10006 0.0130 2011-06
將ret與twRf合併
Ret2880$Rf.month = rep(0, dim(Ret2880)[1])
for (year in seq(2011,2020)){
for (mn in c("01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12")){
ym = paste(year, mn, sep="-")
#print(ym)
#print(twRf[twRf$ym2==ym, "ret"])
Ret2880$Rf.month[ym] = twRf[twRf$ym2==ym, "ret"]
}
}
#
head(Ret2880)## Rm Rq Rf.month
## 2011-01-04 -0.003114509 -0.022312327 0.0121
## 2011-01-05 -0.016769775 -0.035269745 0.0121
## 2011-01-06 0.004171275 0.002150540 0.0121
## 2011-01-07 -0.011312379 -0.027897025 0.0121
## 2011-01-10 0.004003333 0.002207508 0.0121
## 2011-01-11 0.012869360 0.011013228 0.0121
tail(Ret2880)## Rm Rq Rf.month
## 2020-12-23 0.0032184808 -0.002816847 0.0079
## 2020-12-24 0.0040209567 0.002824804 0.0079
## 2020-12-25 0.0035811376 0.008450771 0.0079
## 2020-12-28 0.0105816724 0.002793299 0.0079
## 2020-12-29 -0.0007609235 0.000000000 0.0079
## 2020-12-30 0.0149011642 0.022284088 0.0079
轉換成日資料
Ret2880$Rf.day = (Ret2880$Rf.month+1)^(1/20)-1
head(Ret2880)## Rm Rq Rf.month Rf.day
## 2011-01-04 -0.003114509 -0.022312327 0.0121 0.0006015499
## 2011-01-05 -0.016769775 -0.035269745 0.0121 0.0006015499
## 2011-01-06 0.004171275 0.002150540 0.0121 0.0006015499
## 2011-01-07 -0.011312379 -0.027897025 0.0121 0.0006015499
## 2011-01-10 0.004003333 0.002207508 0.0121 0.0006015499
## 2011-01-11 0.012869360 0.011013228 0.0121 0.0006015499
STEP1:把資料整理成資料框較方便繪圖或建模
head(Ret2880)## Rm Rq Rf.month Rf.day
## 2011-01-04 -0.003114509 -0.022312327 0.0121 0.0006015499
## 2011-01-05 -0.016769775 -0.035269745 0.0121 0.0006015499
## 2011-01-06 0.004171275 0.002150540 0.0121 0.0006015499
## 2011-01-07 -0.011312379 -0.027897025 0.0121 0.0006015499
## 2011-01-10 0.004003333 0.002207508 0.0121 0.0006015499
## 2011-01-11 0.012869360 0.011013228 0.0121 0.0006015499
#
Ret2880.df = data.frame(Date=index(Ret2880), coredata(Ret2880))
head(Ret2880.df)## Date Rm Rq Rf.month Rf.day
## 1 2011-01-04 -0.003114509 -0.022312327 0.0121 0.0006015499
## 2 2011-01-05 -0.016769775 -0.035269745 0.0121 0.0006015499
## 3 2011-01-06 0.004171275 0.002150540 0.0121 0.0006015499
## 4 2011-01-07 -0.011312379 -0.027897025 0.0121 0.0006015499
## 5 2011-01-10 0.004003333 0.002207508 0.0121 0.0006015499
## 6 2011-01-11 0.012869360 0.011013228 0.0121 0.0006015499
STEP2:計算各風險溢酬
Ret2880.df$Rmf = Ret2880.df$Rm - Ret2880.df$Rf.day
Ret2880.df$Rqf = Ret2880.df$Rq - Ret2880.df$Rf.day
head(Ret2880.df)## Date Rm Rq Rf.month Rf.day Rmf
## 1 2011-01-04 -0.003114509 -0.022312327 0.0121 0.0006015499 -0.003716059
## 2 2011-01-05 -0.016769775 -0.035269745 0.0121 0.0006015499 -0.017371325
## 3 2011-01-06 0.004171275 0.002150540 0.0121 0.0006015499 0.003569725
## 4 2011-01-07 -0.011312379 -0.027897025 0.0121 0.0006015499 -0.011913928
## 5 2011-01-10 0.004003333 0.002207508 0.0121 0.0006015499 0.003401784
## 6 2011-01-11 0.012869360 0.011013228 0.0121 0.0006015499 0.012267810
## Rqf
## 1 -0.022913876
## 2 -0.035871295
## 3 0.001548990
## 4 -0.028498575
## 5 0.001605958
## 6 0.010411678
STEP3:畫出系統性風險溢酬與投資組合的風險溢酬的散佈圖
plot(Ret2880.df$Rmf, Ret2880.df$Rqf,
xlab="系統性風險溢酬", ylab="投資風險溢酬",
main="華南金(2880)十年資料")plotList2880 = list()
par(mai=c(0.1, 0.1, 0.1, 0.1), mfrow=c(5,2))
for (year in as.character(seq(2011,2020))){
plotData2880 = Ret2880.df[format(Ret2880.df$Date, "%Y")==year, ]
fig = plot(plotData2880$Rmf, plotData2880$Rqf,
xlab="系統性風險溢酬", ylab="投資風險溢酬",
xlim=c(-0.065, 0.065), ylim=c(-0.11, 0.071),
main=year)
#plotList = list(plotList, fig)
}par(mfrow=c(1,1))plotList2880 = list()
for (year in as.character(seq(2011,2020))){
plotData2880 = Ret2880.df[format(Ret2880.df$Date, "%Y")==year, ]
fig2880 = plotly_build(plot_ly(x=~Rmf, y=~Rqf, data=plotData2880,
type="scatter",
mode="markers",
name=year))
plotList2880 = c(plotList2880, list(fig2880))
}
#
plotly::subplot(plotList2880,
nrows=5,
shareX=TRUE, shareY=TRUE,
titleX=FALSE, titleY=FALSE)算出某一年度的β
year="2020"
anaData2880 = dplyr::filter(Ret2880.df,
format(Date, "%Y")==year)
out2880 = lm(Rqf ~ Rmf, data=anaData2880)
summary(out2880)##
## Call:
## lm(formula = Rqf ~ Rmf, data = anaData2880)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.027741 -0.004166 -0.000321 0.004416 0.041411
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.0012614 0.0004919 -2.564 0.0109 *
## Rmf 0.8270838 0.0366705 22.555 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.007678 on 242 degrees of freedom
## Multiple R-squared: 0.6776, Adjusted R-squared: 0.6763
## F-statistic: 508.7 on 1 and 242 DF, p-value: < 2.2e-16
抓出 α,β,及其統計顯著性
# 只能抓到係數
out2880$coef## (Intercept) Rmf
## -0.001261361 0.827083796
# 可以抓到細數及其顯著性
summary(out2880)$coef## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.001261361 0.0004918834 -2.56435 1.094162e-02
## Rmf 0.827083796 0.0366704515 22.55450 2.009436e-61
# 係數
summary(out2880)$coef[,1]## (Intercept) Rmf
## -0.001261361 0.827083796
# 顯著性
summary(out2880)$coef[,4]## (Intercept) Rmf
## 1.094162e-02 2.009436e-61
# 抓出年代
Ret2880.df$year = format(Ret2880.df$Date, "%Y")
# 自訂函數
lm.self2880 = function(data){
out2880 = lm(Rqf ~ Rmf, data=data)
out2880
}
# 利用 by 分割資料。再將每組資料利用lm.self分析
outT2880 = by(Ret2880.df, Ret2880.df$year, FUN=lm.self2880)抓出 β與α,與統計顯著性
coef2880 = data.frame()
for (i in seq(1, length(outT2880))){
coef2880 = rbind(coef2880,
c(summary(outT2880[[i]])$coef[,1],
summary(outT2880[[i]])$coef[,4]))
}
colnames(coef2880) = c("alpha", "beta", "p(alpha)", "p(beta)")
coef2880## alpha beta p(alpha) p(beta)
## 1 -1.944925e-04 1.0761456 0.76430612 8.436893e-63
## 2 -8.589717e-05 0.8128140 0.83907601 4.436596e-49
## 3 -1.355362e-04 0.8405466 0.73473816 5.902554e-38
## 4 -1.843291e-04 0.7519432 0.69053230 7.886516e-24
## 5 -2.065363e-04 0.7383259 0.62466118 5.170465e-45
## 6 7.123648e-05 0.7829830 0.87379850 1.982005e-35
## 7 -2.220420e-04 0.5046872 0.44773342 1.082820e-17
## 8 2.442315e-04 0.4654821 0.43037979 6.691361e-36
## 9 4.558800e-04 0.5735232 0.23198241 2.379821e-20
## 10 -1.261361e-03 0.8270838 0.01094162 2.009436e-61
可以看出 β 幾乎都是非常顯著不為0,且風險低於大盤。α 幾乎都不顯著異於0,但2011~2015年間,卻是幾乎年年下降;不過近幾年有漸漸上升跡象
繪圖呈現
year2880 = unique(Ret2880.df$year)
plot_ly(x=year2880, y=coef2880$beta,
type="scatter", mode="lines+markers",
name="beta") %>%
add_trace(y=coef2880$alpha, yaxis = "y2",
name="alpha") %>%
layout(xaxis = list(title = list(text = "華南金(2880)")),
yaxis=list(title = list(text = "beta"),
side = "left"),
yaxis2=list(title = list(text = "alpha"),
overlaying = "y",
side = "right"))# 下載資料
# 大盤指數:^TWII
# 中信金:2891.TW
loadSymbols(Symbols=c("^TWII", "2891.TW"),
from="2011-01-01", to="2020-12-31",
auto.assign=TRUE) # 這一定要設定## Warning: ^TWII contains missing values. Some functions will not work if objects
## contain missing values in the middle of the series. Consider using na.omit(),
## na.approx(), na.fill(), etc to remove or replace them.
## Warning: 2891.TW contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## [1] "^TWII" "2891.TW"
# 注意:^TWII 下載後存入 TWII 中
# 轉換成正常的變數名稱
#TWII = get("TWII")
TW2891 = get("2891.TW")# 處理大盤資料
str(TWII)## An 'xts' object on 2011-01-03/2020-12-30 containing:
## Data: num [1:2455, 1:6] 9040 9045 9014 8866 8905 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:6] "TWII.Open" "TWII.High" "TWII.Low" "TWII.Close" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 2
## $ src : chr "yahoo"
## $ updated: POSIXct[1:1], format: "2021-11-14 18:11:46"
# 去掉遺失值
TWII = na.omit(TWII)
colnames(TWII) = c("Open", "High", "Low", "Close", "Volume", "Adjusted")
str(TWII)## An 'xts' object on 2011-01-03/2020-12-30 containing:
## Data: num [1:2444, 1:6] 9040 9045 9014 8866 8905 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:6] "Open" "High" "Low" "Close" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 3
## $ src : chr "yahoo"
## $ updated : POSIXct[1:1], format: "2021-11-14 18:11:46"
## $ na.action: 'omit' int [1:11] 248 390 1111 1167 1254 1334 1403 1413 1414 1509 ...
## ..- attr(*, "index")= num [1:11] 1.33e+09 1.34e+09 1.44e+09 1.44e+09 1.45e+09 ...
head(TWII)## Open High Low Close Volume Adjusted
## 2011-01-03 9039.63 9041.32 8994.50 9025.30 5067400 9025.267
## 2011-01-04 9045.11 9046.18 8988.58 8997.19 5270400 8997.157
## 2011-01-05 9014.32 9027.16 8812.36 8846.31 5796600 8846.277
## 2011-01-06 8866.23 8883.21 8813.63 8883.21 4362200 8883.177
## 2011-01-07 8905.25 8907.11 8738.93 8782.72 4500800 8782.688
## 2011-01-10 8798.05 8817.88 8762.50 8817.88 2885200 8817.848
# 轉成資料框
TWII.df = data.frame(Date=index(TWII),coredata(TWII))
head(TWII.df)## Date Open High Low Close Volume Adjusted
## 1 2011-01-03 9039.63 9041.32 8994.50 9025.30 5067400 9025.267
## 2 2011-01-04 9045.11 9046.18 8988.58 8997.19 5270400 8997.157
## 3 2011-01-05 9014.32 9027.16 8812.36 8846.31 5796600 8846.277
## 4 2011-01-06 8866.23 8883.21 8813.63 8883.21 4362200 8883.177
## 5 2011-01-07 8905.25 8907.11 8738.93 8782.72 4500800 8782.688
## 6 2011-01-10 8798.05 8817.88 8762.50 8817.88 2885200 8817.848
# 處理中信金資料
# 去掉遺失值
TW2891 = na.omit(TW2891)
colnames(TW2891) = c("Open", "High", "Low", "Close", "Volume", "Adjusted")
str(TW2891)## An 'xts' object on 2011-01-03/2020-12-30 containing:
## Data: num [1:2450, 1:6] 14 14.1 13.7 13.4 13.9 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:6] "Open" "High" "Low" "Close" ...
## Indexed by objects of class: [Date] TZ: UTC
## xts Attributes:
## List of 3
## $ src : chr "yahoo"
## $ updated : POSIXct[1:1], format: "2021-11-14 18:11:47"
## $ na.action: 'omit' int [1:5] 1254 1334 1403 1509 1578
## ..- attr(*, "index")= num [1:5] 1.45e+09 1.46e+09 1.47e+09 1.49e+09 1.50e+09
head(TW2891)## Open High Low Close Volume Adjusted
## 2011-01-03 13.96524 14.15920 13.90059 14.12688 85765904 9.268356
## 2011-01-04 14.09455 14.09455 13.67430 13.67430 75769600 8.971431
## 2011-01-05 13.73895 13.90059 13.25405 13.31870 104937215 8.738131
## 2011-01-06 13.35103 13.99757 13.28637 13.93291 122391692 9.141101
## 2011-01-07 13.90059 13.90059 13.44801 13.57732 101877848 8.907803
## 2011-01-10 13.70663 13.77128 13.51266 13.67430 63541412 8.971431
# 轉成資料框
TW2891.df = data.frame(Date=index(TW2891),coredata(TW2891))
head(TW2891.df)## Date Open High Low Close Volume Adjusted
## 1 2011-01-03 13.96524 14.15920 13.90059 14.12688 85765904 9.268356
## 2 2011-01-04 14.09455 14.09455 13.67430 13.67430 75769600 8.971431
## 3 2011-01-05 13.73895 13.90059 13.25405 13.31870 104937215 8.738131
## 4 2011-01-06 13.35103 13.99757 13.28637 13.93291 122391692 9.141101
## 5 2011-01-07 13.90059 13.90059 13.44801 13.57732 101877848 8.907803
## 6 2011-01-10 13.70663 13.77128 13.51266 13.67430 63541412 8.971431
# 算出收益率
# Rm
Rm2891 = quantmod::periodReturn(TWII$Close, period="daily",
type='arithmetic')
colnames(Rm2891) = "Rm"
head(Rm2891)## Rm
## 2011-01-03 0.000000000
## 2011-01-04 -0.003114509
## 2011-01-05 -0.016769775
## 2011-01-06 0.004171275
## 2011-01-07 -0.011312379
## 2011-01-10 0.004003333
Rm2891 = Rm2891[-1]
# Rq
Rq2891 = quantmod::periodReturn(TW2891$Close, period="daily",
type='arithmetic')
colnames(Rq2891) = "Rq"
head(Rq2891)## Rq
## 2011-01-03 0.000000000
## 2011-01-04 -0.032036595
## 2011-01-05 -0.026004770
## 2011-01-06 0.046116506
## 2011-01-07 -0.025522012
## 2011-01-10 0.007142869
Rq2891 = Rq2891[-1]# 合併資料,只取共同日期
# all=FALSE ==> 只取共同日期
Ret2891<-merge(Rm2891, Rq2891,all=FALSE)
head(Ret2891)## Rm Rq
## 2011-01-04 -0.003114509 -0.032036595
## 2011-01-05 -0.016769775 -0.026004770
## 2011-01-06 0.004171275 0.046116506
## 2011-01-07 -0.011312379 -0.025522012
## 2011-01-10 0.004003333 0.007142869
## 2011-01-11 0.012869360 0.014184420
利用台銀一年期存款利率。
# 讀取資料
twRf = read.csv("./ch20_twbank10.csv")
str(twRf)## 'data.frame': 120 obs. of 2 variables:
## $ ym : int 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 ...
## $ ret: num 1.21 1.21 1.21 1.3 1.3 1.3 1.38 1.38 1.38 1.38 ...
head(twRf)## ym ret
## 1 10001 1.21
## 2 10002 1.21
## 3 10003 1.21
## 4 10004 1.30
## 5 10005 1.30
## 6 10006 1.30
# 資料整理
# 利率
twRf$ret = twRf$ret*0.01
# 日期
year = as.character(as.numeric(substr(as.character(twRf$ym),1,3))+1911)
head(year)## [1] "2011" "2011" "2011" "2011" "2011" "2011"
month = substr(as.character(twRf$ym),4,5)
head(month)## [1] "01" "02" "03" "04" "05" "06"
#
twRf$ym2 = paste(year, month, sep="-")
head(twRf)## ym ret ym2
## 1 10001 0.0121 2011-01
## 2 10002 0.0121 2011-02
## 3 10003 0.0121 2011-03
## 4 10004 0.0130 2011-04
## 5 10005 0.0130 2011-05
## 6 10006 0.0130 2011-06
將ret(2891)與twRf合併
Ret2891$Rf.month = rep(0, dim(Ret2891)[1])
for (year in seq(2011,2020)){
for (mn in c("01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12")){
ym = paste(year, mn, sep="-")
#print(ym)
#print(twRf[twRf$ym2==ym, "ret"])
Ret2891$Rf.month[ym] = twRf[twRf$ym2==ym, "ret"]
}
}
#
head(Ret2891)## Rm Rq Rf.month
## 2011-01-04 -0.003114509 -0.032036595 0.0121
## 2011-01-05 -0.016769775 -0.026004770 0.0121
## 2011-01-06 0.004171275 0.046116506 0.0121
## 2011-01-07 -0.011312379 -0.025522012 0.0121
## 2011-01-10 0.004003333 0.007142869 0.0121
## 2011-01-11 0.012869360 0.014184420 0.0121
tail(Ret2891)## Rm Rq Rf.month
## 2020-12-23 0.0032184808 -0.005181244 0.0079
## 2020-12-24 0.0040209567 0.002604114 0.0079
## 2020-12-25 0.0035811376 0.002597351 0.0079
## 2020-12-28 0.0105816724 -0.005181244 0.0079
## 2020-12-29 -0.0007609235 0.002604114 0.0079
## 2020-12-30 0.0149011642 0.025974026 0.0079
轉換成日資料
Ret2891$Rf.day = (Ret2891$Rf.month+1)^(1/20)-1
head(Ret2891)## Rm Rq Rf.month Rf.day
## 2011-01-04 -0.003114509 -0.032036595 0.0121 0.0006015499
## 2011-01-05 -0.016769775 -0.026004770 0.0121 0.0006015499
## 2011-01-06 0.004171275 0.046116506 0.0121 0.0006015499
## 2011-01-07 -0.011312379 -0.025522012 0.0121 0.0006015499
## 2011-01-10 0.004003333 0.007142869 0.0121 0.0006015499
## 2011-01-11 0.012869360 0.014184420 0.0121 0.0006015499
STEP1:把資料整理成資料框較方便繪圖或建模
head(Ret2891)## Rm Rq Rf.month Rf.day
## 2011-01-04 -0.003114509 -0.032036595 0.0121 0.0006015499
## 2011-01-05 -0.016769775 -0.026004770 0.0121 0.0006015499
## 2011-01-06 0.004171275 0.046116506 0.0121 0.0006015499
## 2011-01-07 -0.011312379 -0.025522012 0.0121 0.0006015499
## 2011-01-10 0.004003333 0.007142869 0.0121 0.0006015499
## 2011-01-11 0.012869360 0.014184420 0.0121 0.0006015499
#
Ret2891.df = data.frame(Date=index(Ret2891), coredata(Ret2891))
head(Ret2891.df)## Date Rm Rq Rf.month Rf.day
## 1 2011-01-04 -0.003114509 -0.032036595 0.0121 0.0006015499
## 2 2011-01-05 -0.016769775 -0.026004770 0.0121 0.0006015499
## 3 2011-01-06 0.004171275 0.046116506 0.0121 0.0006015499
## 4 2011-01-07 -0.011312379 -0.025522012 0.0121 0.0006015499
## 5 2011-01-10 0.004003333 0.007142869 0.0121 0.0006015499
## 6 2011-01-11 0.012869360 0.014184420 0.0121 0.0006015499
STEP2:計算各風險溢酬
Ret2891.df$Rmf = Ret2891.df$Rm - Ret2891.df$Rf.day
Ret2891.df$Rqf = Ret2891.df$Rq - Ret2891.df$Rf.day
head(Ret2891.df)## Date Rm Rq Rf.month Rf.day Rmf
## 1 2011-01-04 -0.003114509 -0.032036595 0.0121 0.0006015499 -0.003716059
## 2 2011-01-05 -0.016769775 -0.026004770 0.0121 0.0006015499 -0.017371325
## 3 2011-01-06 0.004171275 0.046116506 0.0121 0.0006015499 0.003569725
## 4 2011-01-07 -0.011312379 -0.025522012 0.0121 0.0006015499 -0.011913928
## 5 2011-01-10 0.004003333 0.007142869 0.0121 0.0006015499 0.003401784
## 6 2011-01-11 0.012869360 0.014184420 0.0121 0.0006015499 0.012267810
## Rqf
## 1 -0.032638145
## 2 -0.026606320
## 3 0.045514956
## 4 -0.026123562
## 5 0.006541319
## 6 0.013582870
STEP3:畫出系統性風險溢酬與投資組合的風險溢酬的散佈圖
plot(Ret2891.df$Rmf, Ret2891.df$Rqf,
xlab="系統性風險溢酬", ylab="投資風險溢酬",
main="中信金(2891)十年資料")plotList2891 = list()
par(mai=c(0.1, 0.1, 0.1, 0.1), mfrow=c(5,2))
for (year in as.character(seq(2011,2020))){
plotData2891 = Ret2891.df[format(Ret2891.df$Date, "%Y")==year, ]
fig = plot(plotData2891$Rmf, plotData2891$Rqf,
xlab="系統性風險溢酬", ylab="投資風險溢酬",
xlim=c(-0.065, 0.065), ylim=c(-0.11, 0.071),
main=year)
#plotList = list(plotList, fig)
}par(mfrow=c(1,1))plotList2891 = list()
for (year in as.character(seq(2011,2020))){
plotData2891 = Ret2891.df[format(Ret2891.df$Date, "%Y")==year, ]
fig2891 = plotly_build(plot_ly(x=~Rmf, y=~Rqf, data=plotData2891,
type="scatter",
mode="markers",
name=year))
plotList2891 = c(plotList2891, list(fig2891))
}
#
plotly::subplot(plotList2891,
nrows=5,
shareX=TRUE, shareY=TRUE,
titleX=FALSE, titleY=FALSE)算出某一年度的β
year="2020"
anaData2891 = dplyr::filter(Ret2891.df,
format(Date, "%Y")==year)
out2891 = lm(Rqf ~ Rmf, data=anaData2891)
summary(out2891)##
## Call:
## lm(formula = Rqf ~ Rmf, data = anaData2891)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.046779 -0.005687 0.000023 0.005381 0.039129
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.0012451 0.0006288 -1.98 0.0488 *
## Rmf 0.8482329 0.0468810 18.09 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.009816 on 242 degrees of freedom
## Multiple R-squared: 0.575, Adjusted R-squared: 0.5732
## F-statistic: 327.4 on 1 and 242 DF, p-value: < 2.2e-16
抓出 α,β,及其統計顯著性
# 只能抓到係數
out2891$coef## (Intercept) Rmf
## -0.001245135 0.848232878
# 可以抓到細數及其顯著性
summary(out2891)$coef## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.001245135 0.0006288432 -1.980041 4.883178e-02
## Rmf 0.848232878 0.0468809550 18.093336 7.370221e-47
# 係數
summary(out2891)$coef[,1]## (Intercept) Rmf
## -0.001245135 0.848232878
# 顯著性
summary(out2891)$coef[,4]## (Intercept) Rmf
## 4.883178e-02 7.370221e-47
# 抓出年代
Ret2891.df$year = format(Ret2891.df$Date, "%Y")
# 自訂函數
lm.self2891 = function(data){
out2891 = lm(Rqf ~ Rmf, data=data)
out2891
}
# 利用 by 分割資料。再將每組資料利用lm.self分析
outT2891 = by(Ret2891.df, Ret2891.df$year, FUN=lm.self2891)抓出 β與α,與統計顯著性
coef2891 = data.frame()
for (i in seq(1, length(outT2891))){
coef2891 = rbind(coef2891,
c(summary(outT2891[[i]])$coef[,1],
summary(outT2891[[i]])$coef[,4]))
}
colnames(coef2891) = c("alpha", "beta", "p(alpha)", "p(beta)")
coef2891## alpha beta p(alpha) p(beta)
## 1 1.371122e-03 1.3133537 0.19315083 3.794233e-44
## 2 -1.389862e-04 1.1361638 0.85197808 5.326331e-36
## 3 5.779263e-04 0.8588918 0.29877051 2.766348e-24
## 4 -1.884023e-05 1.1889129 0.97111027 3.410333e-39
## 5 2.411052e-06 0.9675196 0.99752081 5.248152e-28
## 6 1.134113e-04 1.0285992 0.84810800 3.496546e-35
## 7 7.025935e-05 0.7476083 0.86831269 2.659560e-18
## 8 1.984156e-04 0.8367173 0.74459819 1.466219e-31
## 9 -2.797941e-04 0.5810339 0.54529609 2.586320e-15
## 10 -1.245135e-03 0.8482329 0.04883178 7.370221e-47
可以看出 β 幾乎都是非常顯著不為0,且風險低於大盤。α 幾乎都不顯著異於0,但2011~2015年間,卻是幾乎年年下降;不過近幾年有漸漸上升跡象
繪圖呈現
year2891 = unique(Ret2891.df$year)
plot_ly(x=year2891, y=coef2891$beta,
type="scatter", mode="lines+markers",
name="beta") %>%
add_trace(y=coef2891$alpha, yaxis = "y2",
name="alpha") %>%
layout(xaxis = list(title = list(text = "中信金(2891)")),
yaxis=list(title = list(text = "beta"),
side = "left"),
yaxis2=list(title = list(text = "alpha"),
overlaying = "y",
side = "right"))兩台股系統性風險溢酬與投資風險溢酬之散佈圖
十年資料
par(mfrow=c(1,2))
fig1 <- plot(Ret2880.df$Rmf, Ret2880.df$Rqf,
xlab="系統性風險溢酬", ylab="投資風險溢酬",
main="華南金(2880)十年資料")
fig2 <- plot(Ret2891.df$Rmf, Ret2891.df$Rqf,
xlab="系統性風險溢酬", ylab="投資風險溢酬",
main="中信金(2891)十年資料")散佈圖之說明:
由此兩圖可知華南金(2880)較集中在第三象限,屬於低風險低報酬;中信金(2891)集中在第一、二、三象限,且有零星散佈點位於第一象限,屬於相對高風險高報酬的金融股
兩台股各年度之散佈圖
註:上兩行為華南金(2880)各年度散佈圖,下兩行為中信金(2891)各年度散佈圖
plotList2880 = list()
for (year in as.character(seq(2011,2020))){
plotData2880 = Ret2880.df[format(Ret2880.df$Date, "%Y")==year, ]
fig2880 = plotly_build(plot_ly(x=~Rmf, y=~Rqf, data=plotData2880,
type="scatter",
mode="markers",
name=year))
plotList2880 = c(plotList2880, list(fig2880))
}
plotList2891 = list()
for (year in as.character(seq(2011,2020))){
plotData2891 = Ret2891.df[format(Ret2891.df$Date, "%Y")==year, ]
fig2891 = plotly_build(plot_ly(x=~Rmf, y=~Rqf, data=plotData2891,
type="scatter",
mode="markers",
name=year, showlegend = FALSE))
plotList2891 = c(plotList2891, list(fig2891))
}
list = c(plotList2880, plotList2891)
#
plotly::subplot(list,
nrows=4,
shareX=TRUE, shareY=TRUE,
titleX=FALSE, titleY=FALSE)因各年度皆分布於第一、三象限,較看不出差異,所以不再多探討兩者之間差異
year2880 = unique(Ret2880.df$year)
fig3 <- plot_ly(x=year2880, y=coef2880$beta,
yaxis = "y",type="scatter",
mode="lines+markers", name="beta") %>%
add_trace(y=coef2880$alpha, yaxis = "y2",
name="alpha") %>%
layout(xaxis = list(title = list(text = "華南金(2880)")),
yaxis=list(title = list(text = "beta"), side="left", range = c(0.4,1.5)),
yaxis2=list(overlaying = "y",
side = "right", range = c(-0.002,0.002),
showticklabels = FALSE))
year2891 = unique(Ret2891.df$year)
fig4 <- plot_ly(x=year2891, y=coef2891$beta,
yaxis = "y", type="scatter",
mode="lines+markers", name="beta") %>%
add_trace(y=coef2891$alpha, yaxis = "y2",
name="alpha") %>%
layout(xaxis = list(title = list(text = "中信金(2891)")),
yaxis=list(side="left", range = c(0.4,1.5), showticklabels = FALSE),
yaxis2=list(title = list(text = "alpha"), overlaying = "y3",
side = "right", range = c(-0.002,0.002)))
plotly::subplot(fig3, fig4, titleX=TRUE, titleY=TRUE)第二章節有提到:
α是總風險扣除系統性風險,額外創造的 超額報酬
β是衡量系統性風險及大盤連動性,也就是指數的波動幅度
由兩圖之折線圖可知:
論及「官股金控」以及「民營股金控」,看名字就知道,「官股金控」就是官方持有股份的比例比較高,「民營股金控」就是民間經營,所以以風險來說,當然是「官股金控」(也就是舉例中的華南金控)風險比較少,因為國家持有大部分的股份,比較不可能倒!
華南金(2880):
但其餘年(2012~2019)都是呈現高alpha(α)低beta(β),相對穩定
中信金(2891):
以折線圖來研究,可以發現重疊年份比較多,分別是2013、2014、2017及2020年,波動幅度很大
官股金控有中央銀行當靠山,又受到立法院的監督,因此投資人比較放心,所以願意付出更高的股價。 民營的比較「物美價廉」,官股則是「安全穩定」。
以現在大盤在萬點的高點,建議投資人還是選擇「官股金控」為主,萬一股市有意外時也會比較抗跌。
以2008~2009年金融海嘯期間為例,上面2家民營金控的股價都跌到個位數,只剩下官股金控的一半,如下表所示:
當股災降臨之際,「安全穩定」是官股金控的最大優勢,「信心不足」則是民營金控的最大致命傷。
追求穩定的人首選公股銀行、想要獲利高的人選民營金控