R练习50题 - 第三期

2020-10-10 16:59:55 浏览数 (1)

在前面

很久没有更新公众号了,这里大猫的R语言课堂给大家说声抱歉。由于两位作者这半年以来实在是太忙了,捱到了国庆假期,终于抽出时间来更新公众号,在此也祝各位水友双节快乐!!!

题预览

继续做题,题目难度已经逐渐加深,先看看预览:

· 每天涨幅前10的股票的总成交额和跌幅前10的股票的总成交额比例是多少?

· 每天开盘涨停的股票与收盘涨停的股票各有多少?(涨停按照收益率超过1.5%的标准计算)

· 每天统计最近3天出现过开盘涨停与收盘涨停的股票各有多少只?

目前,所有的题目答案和解析已基本上传到我们的github主页,大家如果想看看所有的题目解析,可以猛戳:

github.com/Ravin515/r-data-practice

此外,感谢frankzhangsyd、香酥奶油饼(微信)、zhjx19 和 yu-soong 提供的issue,也热烈欢迎大家提供issue!!

题 8

每天涨幅前10的股票的总成交额和跌幅前10的股票的总成交额比例是多少?

代码及解析:

首先,我们需要按照日期进行分组,然后对于每一个交易日,我们需要三个统计值:

top10:涨幅前十的股票的总成交额

bottom10:跌幅前十的股票的总成交额

ratio:top10/bottom10

原数据集中,成交量对应变量amount。

第一步,我们为数据集新增一个变量ret,表示股票的日收益,对应的语句为':='(ret = (close - pre_close)/pre_close)

其次,我们先按照时间date,再按照收益率ret从低到高排序,这是为了方便后续计算,对应语句为order(date, ret)。其中,order是data.table中的快速排序函数。

接着,我们按照日期分组,然后计算每一天涨幅前十和跌幅前十的股票的成交额。amount[1:10]的意思是取amount的前十个观测,amount[(.N-10):.N]则表示amount的倒数10个观测。由于上一步中我们已经按照收益率ret进行了排序,所以amount[1:10]就对应了ret最小的10个股票它们对应的成交额。

sum为求和函数。

题 9

每天开盘涨停的股票与收盘涨停的股票各有多少?(涨停按照收益率超过1.5%的标准计算)

该题提供了大猫和村长的两种答案,我们将分别进行讲解。

代码及解析:

大猫的答案

还是老样子,首先按照date进行分组,然后找出每个交易日中收盘涨停与开盘涨停的股票,最后统计个数。只是题目中把涨停定义为1.5%,似乎和平日里说的10%不一致。不过不影响做题,题目怎么说我们怎么做就行。

line 1-2: 首先我们在原数据集中新增两个变量ret_open与ret_close,分别表示开盘涨幅与收盘涨幅。

line 3-5: 接着我们按照日期date进行分组(keyby语句),然后在每组之内建立两个新的变量n_openlimit与n_closelimit用来统计开收盘涨停的股票数。这里比较有技巧的是sum(ret_open > 0.015)语句。首先我们看ret_open > 0.015,他的意思是把ret_open这个向量的每一个分量与1.5%进行比较,如果成立返回True,否则False。这种比较的最终的结果仍旧是一个向量。sum(ret_open > 0.015)则是把这个向量的所有分量相加,要知道True在数值计算中被转化成1,False则转化为0,因此sum(ret_open > 0.015)最终做的事情是统计ret_open这个向量中有多少个分量是大于0.015的。

以上技巧是非常实用的,你也可以自己验证一下,sum(c(True, False, False))的结果是不是等于1?

村长的答案

村长的答案整体写得更加一步到位,且与大猫最后呈现的数据结构最不同的地方在于,其将本来分属的两个变量变成了一个tag变量,以此作为开盘涨停和收盘涨停的标记。

line 1基本上就将70%以上的工作完成,根据先i,再by,最后j的原则,在 i 中将那些开盘涨停和收盘涨停的股票全部提取了出来,之后在 by 中将这些股票是开盘涨停和收盘涨停进行标记,生成一个变量tag,最后再根据date日期、symbol股票代码和tag这个分类变量进行分组,得出数据集。

line 2以tag和date两个变量分组进行统计,将分组下的symbol数进行统计,uniqueN(symbol)即得到了不重复的股票代码数。

题 10

每天统计最近3天出现过开盘涨停与收盘涨停的股票各有多少只?

代码及解析:

此题大猫的答案由于存在一定的问题,在这里只解读村长的答案。

此题存在一定的陷阱,即是三天内涨停的股票重复计数。例如,t-1日涨停的某只股票,很有可能在t-2日已经涨停,如果单纯加总每日涨停的股票数量,就会对此股票进行重复计数。因此必须计算三日内涨停的不重复股票数量。

line 1 选出开盘涨停和收盘涨停的股票,并分别标记为closelimit和openlimit,生成一个tag变量。

line 2 利用list(symbol),外加keyby = .(tag, date),将每天的开盘涨停和收盘涨停的股票代码变为一个单独的list,为symbol_list。

line 3 以tag进行分组,并对4:.N进行循环,将(i-3):(i-1)的每一行symbol_list,分别去list化,输出为一个无嵌套格式的list:lapply(symbol_list[(i-3):(i-1)], unlist);接着再用%>% unlist将这个list,变成一个vector;而后对这个vector求%>% unique,去除重复的股票代码;最后求出这个向量的长度%>% length(),即三日内开盘涨停和收盘涨停的股票数量。

期预告

在下期,会继续更新剩余的答案~

大猫的R语言课堂

我是大猫,一个高中读文科但却在代码、数学的路上狂奔不止的Finance Ph. D Candidate。

我是村长,一个玩了11年指弹吉他,却被代码深深吸引的博士候选人。

大猫的微信号是:

iRoss2007

村长的微信号及B站主页是:

ravin515

http://space.bilibili.com/40771572

大猫的R语言课堂关注R语言、数据挖掘以及经济金融学。

我们与大家分享我们的知识和节操,我相信独乐乐不如众乐乐。

我还有许多好玩的计划。

更多的精彩内容正在路上。

长按二维码关注

0 人点赞