前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R练习50题 - 第八期

R练习50题 - 第八期

作者头像
用户7652506
发布2021-07-23 16:40:15
3630
发布2021-07-23 16:40:15
举报

习题 35

35. 每天有哪些行业的平均收益率超过市场平均收益率?

代码语言:javascript
复制
data[, .(stkcd_ret = close/pre_close - 1, symbol, ind_weight = capt/sum(capt), capt), keyby = .(industry,date)
    ][, .(ind_ret = sum(ind_weight*stkcd_ret), stkcd_ret, symbol, capt), keyby = .(industry, date)
    ][, .(ind_ret, mkt_weight = capt/sum(capt), stkcd_ret, industry), keyby = date
    ][, .(ind_ret, mkt_ret = sum(mkt_weight*stkcd_ret), industry), keyby = date
    ][ind_ret > mkt_ret, unique(.SD)
    ][1:5]

此题主要计算每天的行业收益率ind_ret和市场收益率mkt_ret

line 1 计算每只股票每天的收益率stkcd_ret和每个行业中各股票的流通市值权重ind_weight

line 2 计算每个行业每天的收益率ind_ret

line 3 计算每天市场中各股票的流通市值权重mkt_weight

line 4 计算市场每天的收益率mkt_ret

line 5 挑选出每天那些行业收益率ind_ret大于市场收益率mkt_ret的行业,并去重。

习题 36

36. 每天每个行业对市场的超额收益率是多少?

代码语言:javascript
复制
data[, .(stkcd_ret = close/pre_close - 1, symbol, ind_weight = capt/sum(capt), capt), keyby = .(industry,date)
    ][, .(ind_ret = sum(ind_weight*stkcd_ret), stkcd_ret, symbol, capt), keyby = .(industry, date)
    ][, .(ind_ret, mkt_weight = capt/sum(capt), stkcd_ret, industry), keyby = date
    ][, .(ind_ret, mkt_ret = sum(mkt_weight*stkcd_ret), industry), keyby = date
    ][, unique(.SD)
    ][, .(alpha = coef(lm(ind_ret ~ mkt_ret))[1], beta = coef(lm(ind_ret ~ mkt_ret))[2], ind_ret, mkt_ret, date), keyby = industry
    ][, .(abnr_ret = ind_ret - alpha - beta*mkt_ret, date), by = industry
    ][1:5]

与Ex-30类似,此题最大的不同在于需要以行业industry和日期date,分组计算每个行业的收益率ind_ret和市场收益率mkt_ret。具体可参考R练习50题 - 第七期!

题 37

37. 每天每个行业对去除本行业后的市场超额收益是多少?

代码语言:javascript
复制
data[, .(stkcd_ret = close/pre_close - 1, symbol, ind_weight = capt/sum(capt), capt), keyby = .(industry,date)
    ][, .(ind_ret = sum(ind_weight*stkcd_ret), stkcd_ret, symbol, capt), keyby = .(industry, date)
    ][, .(ind_capt = sum(capt), ind_ret), keyby = .(industry, date)
    ][, unique(.SD)
    ][, .(ind_mkt_weight = ind_capt/(sum(ind_capt) - ind_capt), ind_ret, industry), keyby = date
    ][, .(mkt_ret = sum(ind_mkt_weight * ind_ret) - ind_mkt_weight * ind_ret, ind_ret, industry), by = date
    ][, .(alpha = coef(lm(ind_ret ~ mkt_ret))[1], beta = coef(lm(ind_ret ~ mkt_ret))[2], ind_ret, mkt_ret, industry, date)
    ][, .(abnr_ret = ind_ret - alpha - beta*mkt_ret, date), by = industry
    ][1:5]

与Ex-31类似,唯一不同点在于需要在计算完每个行业每天的收益率ind_ret之后,运用公式:

计算去除本行业的市场收益率。具体可参考R练习50题 - 第七期!,这里不作赘述。

需要注意的是 line 4 中用了一个unique(.SD)的处理,因为原始数据是以每一只股票每一天作为最小观测的,但这里需要的是每一个行业每天的收益率和总体市值,在提取ind_retind_capt时存在很多的重复观察,故而用了去重命令。

题 38

38. 每天分别有多少股票是最近连续3个交易日上涨、下跌的?

代码语言:javascript
复制
data[, .(stkcd_ret = close/pre_close - 1), keyby = .(symbol, date)
    ][, {
        l <- list()
        b1 <- stkcd_ret > 0
        b2 <- stkcd_ret < 0
        for (t in 1:.N) {
            l[[t+3]] <- list(r3day_up = mean(b1[t:(t+2)]), r3day_dn = mean(b2[t:(t+2)]), date = date[t+3])
        }
        rbindlist(l)
    }    
    , keyby = .(symbol)
    ][!is.na(date), .(stkcd_amount = uniqueN(symbol)), keyby = .(date, tag = ifelse(r3day_up == 1, "r3day_up", ifelse(r3day_dn == 1, "r3day_dn", "others")))
    ][tag == "r3day_dn"|tag == "r3day_up"
    ][1:5]

此题的关键点和难点在于,如何识别出连续三个交易日上涨和下跌。由于牵涉到行处理,所以最好的方法是在data.table语句中进行循环。本题运用了logical类向量在四则运算时TRUE为1,FALSE为0的特征,进行识别。

line 1 首先计算出每一只股票每一天的收益率stkcd_ret

line 2 是本题的关键.首先由于要对每一只股票进行对应处理,先用keyby = .(symbol)进行分组。接下来定义一个listl,接下来把每只股票每天的收益率stkcd_ret做一个判断,这一天的收益率大于0为上涨,收益率小于0为下跌,以此生成两列logical类型的变量b1b2。在b1中观测如果为TRUE则表明该只股票这一天股价为上涨,反之如果为FALSE则为下跌;b2中的观测代表的意义与b1相反。接下来,从第一行到最后一行,设定一个循环的t值,由于是判断最近连续3个交易日是否涨跌,那么就从每只股票的第4个交易日t+3开始计算,因而有l[[t+3]]date[t+3];而后计算b1b2最近三天的均值,分别为r3day_upr3day_dn(为什么求均值会在后面 )。由于每一次循环生成了三个变量的一次观测,所以将这一次观测生成一个list,而后对应到每一个l的每一天的观测中去,于是就有了 l[[t+3]] <- list(r3day_up = mean(b1[t:(t+2)]), r3day_dn = mean(b2[t:(t+2)]), date = date[t+3])。最后,需要对生成的.N-3行观测进行合并,在这里用到了rbindlist(l)

line 3 则计算出了每一天当中最近三天上涨和下跌的股票数。首先以!is.na(date)去除dateNA的观测,因为当循环到.N-2时,r3day_upr3day_dn还能生成观测,但date已无法生成观测,超出了循环的日期范围,故而会出现NA的情况;接下里在by中进行分组,需要生成一个tag变量,我们可以发现,r3day_up是最近三日是否为上涨判断的均值,如果最近三日皆为上涨,则r3day_up应该为1;同理可以推断r3day_dn,如果最近三日皆为下跌,则r3day_dn应为1。故而将tag设定为三种观测值r3day_upr3day_dn以及others,用ifelse语句进行生成。而后根据datetag分组计算,每天属于r3day_upr3day_dn以及others的股票数量:stkcd_amount = uniqueN(symbol)

line 4 最后挑选出tagr3day_upr3day_dn的行。

题 39

代码语言:javascript
复制
data[, .(stkcd_ret = close/pre_close - 1, mkt_weight = capt/sum(capt), symbol), keyby = .(date)
    ][, .(mkt_ret = sum(stkcd_ret * mkt_weight), symbol, stkcd_ret), keyby = .(date)
    ][, .(rday_ret = ifelse(stkcd_ret > mkt_ret, 1, 0)), keyby = .(symbol, date)
    ][, {
        l <- list()
        for (t in 1:.N) {
            l[[t+3]] <- list(r3day_ret = mean(rday_ret[t:(t+2)]), date = date[t+3])
        }
        rbindlist(l)
    }, keyby = symbol
    ][r3day_ret == 1 & !is.na(date), .(stkcd_amount = uniqueN(symbol)), keyby = date
    ][1:5]

line 1 和 line 2 分别计算出每日市场收益率mkt_ret和每日每只股票的收益率stkcd_ret

line 3 则判断每日该股票是否超过该日市场收益率,超过为1,没超过为0,写入变量rday_ret中。

line 4 ~ line 5可完全参考Ex-38中的line 3 ~ line 4的解析,在此不作赘述。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大猫的R语言课堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 习题 35
  • 习题 36
  • 习题 37
  • 习题 38
  • 习题 39
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档