收益率和方差

张剑

2020/04/09

Categories: 投资学 Tags: R 投资

股票收益率、方差和相关性

股价转换为日收益率

使用Tushare接口进行股价下载,此次我们选取三只保险类股票进行演示

  1. 中国平安(601318.SH)
  2. 中国人寿(601628.SH)
  3. 中国太保(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块钱变成了多少钱

我们利用日回报率来计算

1×t=1T(1+rt)

相关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()

可以看出,这几只股票的收益率呈现高度相关