股票收益率、方差和相关性
股价转换为日收益率
使用Tushare接口进行股价下载,此次我们选取三只保险类股票进行演示
- 中国平安(601318.SH)
- 中国人寿(601628.SH)
- 中国太保(601601.SH)
使用通用接口下载后复权的股票日数据,使用tidyverse,Tushare,tidyquant,DT包进行数据处理。
pacman::p_load(Tushare,tidyverse,tidyquant,DT,anytime)
api <- pro_api(token = '5adce34e8c81bf7085828754a8e09590c3630032d0f61aad6483eaaa')
bar <- pro_bar(token = '5adce34e8c81bf7085828754a8e09590c3630032d0f61aad6483eaaa')
调入api后,我们使用通用pro_bar接口读取三只股票的日数据,
pingan <- bar(ts_code='601318.SH',start_date="20140101",
end_date='20200407',adj="qfq")
zgrs <- bar(ts_code='601628.SH',start_date="20140101",
end_date='20200407',adj="qfq")
zgtb <- bar(ts_code='601601.SH',start_date="20140101",
end_date='20200407',adj="qfq")
将三只股票日数据整理合并成一个数据集:
这里使用rbind,进行所谓的行合并,类似于stata中的append,把表格变长
df <- rbind(pingan,zgrs,zgtb)
df <- df %>%
select(ts_code, trade_date,close) %>%
mutate(trade_date = as.Date(trade_date,format="%Y%m%d"),close = as.numeric(close))
df %>% datatable()
画一下三个股票的价格趋势
ggplot(df,aes(x=trade_date,y = close,color=ts_code))+
geom_line() + theme_tq() + xlab("时间") + ylab("股价") +
scale_color_tq() + ggtitle("三只保险股收盘价趋势2014-2020")
日收益率、月收益率计算
日收益率
df_day_r <- df %>% drop_na() %>%
group_by(ts_code) %>%
tq_transmute (
select = close,
mutate_fun = periodReturn,
period = 'daily',
col_rename = 'd_returns'
) %>% arrange(trade_date)
df_day_r %>% datatable()
月收益率
df_month_r <- df %>% drop_na() %>%
group_by(ts_code) %>%
tq_transmute (
select = close,
mutate_fun = periodReturn,
period = 'monthly',
col_rename = 'm_returns'
) %>% arrange(trade_date)
df_month_r %>% datatable()
计算所谓的收益率的均值
日收益率的均值
df_daily_return_mean <- df_day_r %>%
group_by(ts_code) %>%
summarise(mean_return = mean(d_returns))
df_daily_return_mean %>% datatable()
我们可以看到不同股票的在我们选择的这个时间段内,平均收益率情况。
日收益率的标准差
df_daily_return_sd <- df_day_r %>%
group_by(ts_code) %>%
summarise(sd_return = sd(d_returns))
df_daily_return_sd %>% datatable()
计算累计收益率
所谓的累计收益率也可以等同于持有期收益率,其通俗含义为期初投入1块钱,持有到期末能变成多少钱?
在我们这里可以去计算一下2014年年初投入对这三只保险股票分别投入1块钱,到2020年4月这1块钱变成了多少钱
我们利用日回报率来计算
相关R代码
df_cum_returns <- df_day_r %>%
group_by(ts_code) %>%
mutate(cr = cumprod(1 + d_returns)) %>%
mutate(cumulative_returns = cr - 1)
# 作图
ggplot(df_cum_returns,aes(x=trade_date,y=cumulative_returns,color=ts_code))+
geom_line()+ theme_tq() + scale_color_tq() +
xlab("年份")+ ylab('累计收益率') +
ggtitle("三只保险股累计收益率2014-2020年" , subtitle = "2014年初投入1元钱,现在的金额")+
geom_hline(yintercept = 1,color="red")
可以看出来601318从这个角度来看,表现要更好一些,2014年投入的1块钱,到昨天变成了2.8元
三个公司的年度收益率均值
g1<-df_month_r %>%
mutate(year = year(trade_date)) %>%
group_by(ts_code, year) %>%
summarise(mean = mean(m_returns),
sd = sd(m_returns)) %>%
ggplot(aes(x = year, y = mean, fill = ts_code)) +
geom_bar(stat = "identity", position = "dodge", width = 0.7) +
theme_tq()+ tidyquant::scale_fill_tq() +
scale_x_continuous(breaks = seq(2014,2020,1))+
scale_y_continuous(breaks = seq(-0.1,0.4,0.02),
labels = scales::percent) +
labs( x = '年份',y='收益率')+
ggtitle("三个保险公司的年度回报率")
g2<-df_month_r %>%
mutate(year = year(trade_date)) %>%
group_by(ts_code, year) %>%
summarise(mean = mean(m_returns),
sd = sd(m_returns)) %>%
ggplot(aes(x = year, y = sd, fill = as.factor(ts_code))) +
geom_bar(stat = "identity", position = "dodge", width = 0.7) +
theme_tq()+ tidyquant::scale_fill_tq() +
scale_x_continuous(breaks = seq(2014,2020,1))+
scale_y_continuous(breaks = seq(-0.1,0.4,0.02),
labels = scales::percent) +
labs( x = '年份',y='收益率的标准差')+
ggtitle("三个保险公司年度回报率的标准差")
pacman::p_load(patchwork)
g1+g2
计算多个股票的方差-协方差矩阵
计算方差协方差矩阵,我们就是用月度收益率为基础来进行计算
df_month_r %>%
pivot_wider( names_from = ts_code,values_from = m_returns) %>%
timetk::tk_xts(silent = TRUE) %>% # 这一步是强制转换为时间序列数据,同时把ts_code这一列删除掉,
#只保留三个股票的月度收益率,用以方便计算方差协方差矩阵
cov()
## 601318.SH 601628.SH 601601.SH
## 601318.SH 0.008827850 0.008104833 0.006648175
## 601628.SH 0.008104833 0.012003932 0.007539195
## 601601.SH 0.006648175 0.007539195 0.007356625
# 这一步的作用是使得数据变成宽数据,便于计算不同股票的协方差,
# 使用pivot_wider进行转换,其对立命令是pivot_longer
j <-df_month_r %>%
pivot_wider( names_from = ts_code,values_from = m_returns)
j %>% datatable()
df_month_r %>%
pivot_wider( names_from = ts_code,values_from = m_returns) %>%
timetk::tk_xts(silent = TRUE) %>%
cor()
## 601318.SH 601628.SH 601601.SH
## 601318.SH 1.0000000 0.7873264 0.8249652
## 601628.SH 0.7873264 1.0000000 0.8022762
## 601601.SH 0.8249652 0.8022762 1.0000000
pacman::p_load(corrplot)
df_month_r %>%
pivot_wider( names_from = ts_code,values_from = m_returns) %>%
timetk::tk_xts(silent = TRUE) %>%
cor() %>% corrplot()