35. 每天有哪些行业的平均收益率超过市场平均收益率?
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. 每天每个行业对市场的超额收益率是多少?
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. 每天每个行业对去除本行业后的市场超额收益是多少?
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_ret和ind_capt时存在很多的重复观察,故而用了去重命令。
38. 每天分别有多少股票是最近连续3个交易日上涨、下跌的?
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类型的变量b1和b2。在b1中观测如果为TRUE则表明该只股票这一天股价为上涨,反之如果为FALSE则为下跌;b2中的观测代表的意义与b1相反。接下来,从第一行到最后一行,设定一个循环的t值,由于是判断最近连续3个交易日是否涨跌,那么就从每只股票的第4个交易日t+3开始计算,因而有l[[t+3]]和date[t+3];而后计算b1和b2最近三天的均值,分别为r3day_up和r3day_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)去除date为NA的观测,因为当循环到.N-2时,r3day_up和r3day_dn还能生成观测,但date已无法生成观测,超出了循环的日期范围,故而会出现NA的情况;接下里在by中进行分组,需要生成一个tag变量,我们可以发现,r3day_up是最近三日是否为上涨判断的均值,如果最近三日皆为上涨,则r3day_up应该为1;同理可以推断r3day_dn,如果最近三日皆为下跌,则r3day_dn应为1。故而将tag设定为三种观测值r3day_up、r3day_dn以及others,用ifelse语句进行生成。而后根据date和tag分组计算,每天属于r3day_up、r3day_dn以及others的股票数量:stkcd_amount = uniqueN(symbol)。
line 4 最后挑选出tag为r3day_up和r3day_dn的行。
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的解析,在此不作赘述。