Statistics: Mid-term Review

我国债券历史成交日度数据(20190121-20190628)

问题背景:

从2014年出现第一只公募债券违约,到现在2021年,高收益债市场经历了明显的扩容。2014年以后,零星出现一些弱资质企业和中小企业集合债违约,当时违约主要集中在抗风险能力比较差的企业。2017-2018年,出现一波民营产业类企业违约潮,并伴随股权质押爆仓,民间借贷也出现了风险。2018年之后,市场中出现了一批所谓的“假国企”违约,比如华阳经贸、中城建、北大方正等等,市场赋予这类企业一定信仰,但企业内部的公司治理和商业经营层面存在问题。再后来,2020年底弱资质大型国企违约,2021年又蔓延到了恒大这种超大型房地产企业,到后来多个大型房企进入违约潮,高收益债市场迅速扩容。

在高收益债市场迅速扩容,标的不断增加的契机下,高收益债也出现了较好的投资机会,如何对高收益债市场成交数据进行日度、周度或月度的监控,深挖投资机会,也显得尤其重要。

数据描述:

债券简称(name),成交价格(price),年化到期收益率%(yield),估值(val),估值和收益率的偏离%(diff),成交量(volume),交易日期(trddate),代码(code),发行人(issuer),中介成交收益(brokeryield),中介成交日期(brokerdate)。

注:代码以SH和SZ结尾的,成交量单位是“万”, 以IB结尾的,成交量单位是“亿”。

数据集分享链接:https://pan.baidu.com/s/1-NcO5s9yhs9pjdQaUr1mPA,提取码qf55。

---
title: "Mid-term Review"
author: "leon"
date: "2022-10-28"
output: html_document
---
path = "C:/Users/胡图图/Desktop/为了宝子/统计学/ibex_example/IBEX_example/"
filenames = list.files(path, pattern="*.csv", full.names=FALSE) # These functions produce a character vector of the names of files or directories in the named directory.
n = length(filenames)
tmp = read.csv(header = T, paste0(path,filenames[1]), fileEncoding="GBK")
num_feature = rep(0, n)
for(i in 1:n){
  tmp = read.csv(header = T, paste0(path,filenames[i]), fileEncoding="GBK")
  # print(colnames(tmp))
  num_feature[i] = length(colnames(tmp))
} #如果不是UTF-8的格式,可以用write.csv来重新读写

table(num_feature)
which(num_feature==11)
colnames(tmp)
colnames(read.csv(header = T, paste0(path,filenames[35]), fileEncoding="GBK"))

data0 = NULL
for(i in 1:n){
  tmp = read.csv(header = T, paste0(path, filenames[i]), fileEncoding = "GBK")
  date0 = substring(filenames[i], 5, 12) #注意到各个数据表中的trddate有的带有具体时间有的不带,又注意到各个数据表的命名规律,因此为了统一,可以用substring函数取出数据表的名字的第5~12位,并以之代替表中的日期
  data0 = rbind(data0, data.frame(name = tmp$name, price = tmp$price,
                                  yield = tmp$yield, val = tmp$val,
                                  diff = tmp$diff, volume = tmp$volume,
                                  trddate = date0, code = tmp$code))
  print(i)
  # 方便了解电脑进行到了第几步
}
class(data0); dim(data0)

利用substring函数替换trddate中不规则的日期,利用rbind函数提取、合并想要的数据并得到需要的数据框后的部分结果如下所示:

namepriceyieldvaldiffvolumetrddatecode
国开1704101.208502.8655002.81704.850000e+003305.873520190121108602.SZ
国开1804100.500002.1208002.4416-3.208000e+0183.61620190121108603.SZ
农发1801100.300002.3901002.5990-2.089000e+0122.868420190121108901.SZ
14长证债100.781403.8466003.25565.910000e+017.054720190121112232.SZ
15西部02101.000003.9486003.51684.318000e+0110.120190121112283.SZ
11陕气债101.300003.4079003.25401.539000e+0130.3920190121112034.SZ
##数据特征概览
#缺失值
sum(is.na(data0))
sum(apply(is.na(data0), 1, sum)!=0) #有多少行是缺失的?;apply函数中的"1"指对行运用,"!="是不等
data1 = data0[which(apply(is.na(data0), 1, sum)==0),] #","在右边,则把每一行取出来;“=”是赋值,"=="是相等
#异常值
attach(data1)
hist(price); length(price[which(price>120)]); min(price)
hist(val); min(val); sum(val>100); quantile(val,0.99); hist(val[which(val>100)])

hist(price)的结果如图所示:

hist(val)的结果如图所示:

由于数据过于集中,因此在利用quantile函数查看val列所对应的数据的分位数后,尝试hist(val[which(val>100)]),结果如图所示:

volume0 = as.numeric(volume)
which(is.na(volume0))
data1$volume[which(is.na(volume0))]
ind = which(is.na(volume0))
data2 = data1[,-6]
data2$volume = volume0
data2 = data2[-ind,]
detach(data1)

为了处理缺失的数据,此处简单粗暴地删掉了所有缺失数据的行。

##进一步区分市场
market = NA

for(i in 1:nrow(data2)){
  nc = nchar(data2$code[i])
  market[i] = substring(data2$code[i], nc-1, nc)
}

table(market)

data2$market = market

#单位转换(SH/SZ万,IB亿)
data3 = data2
data3$volume[data2$market=="IB"] = data2$volume[data2$market=="IB"]*10000
#比较市场间差异
layout(matrix(c(1,2,3), nrow=1, ncol=3, byrow=TRUE), heights=1)
hist(data3$volume[data2$market=="IB"], main = "Histogram_1", xlab= "IB volume")
hist(data3$volume[data2$market=="SH"], main = "Histogram_2", xlab= "SH volume")
hist(data3$volume[data2$market=="SZ"], main = "Histogram_3", xlab= "SZ volume")

效果图如下:

由于数据右偏极其明显,考虑采用对数变换:

quantile(data3$volume[data2$market=="IB"])
quantile(data3$volume[data2$market=="SH"])
quantile(data3$volume[data2$market=="SZ"])

hist(log(data3$volume[data2$market=="IB"]), main = "Logtransformed_1", xlab= "IB volume")
hist(log(data3$volume[data2$market=="SH"]), main = "Logtransformed_2", xlab= "SH volume")
hist(log(data3$volume[data2$market=="SZ"]), main = "Logtransformed_3", xlab= "SZ volume") #高度右偏的变量可以用log变换

效果图如下:

 除了用条形图,还可以用箱线图来实现数据可视化:

layout(matrix(c(1,2), nrow=1, ncol=2, byrow=TRUE), heights=1)
boxplot(data3$volume~data3$market)
boxplot(log(data3$volume)~data3$market)

效果图如下:

 可以认为SH market 和SZ market的均值相当吗?

t.test((data3$volume[data2$market=="SH"]),
        (data3$volume[data2$market=="SZ"]))
        
t.test(log(data3$volume[data2$market=="SH"]),
        log(data3$volume[data2$market=="SZ"]))

寻找新兴高收益主体:

#对于每日的成交数据,及时发现新出现的高收益债券
date4 = unique(data3$trddate)
max(date4)

data_current = data3[data3$trddate!="20190628",]
data_new = data3[data3$trddate=="20190628",]

#定义高收益
high_yield = 50
high_yield_bond = unique(data_current$name[data_current$yield > high_yield]) #由于关心的是某一个债券到底是不是高收益,所以外套一个unique函数:unique returns a vector, data frame or array like x but with duplicate elements/rows removed.
new_high_yield_bond = unique(data_new$name[data_new$yield > high_yield])

#找到新的高收益主体
setdiff(new_high_yield_bond, high_yield_bond)

new_b = "13永利债"
for(i in 1:length(high_yield_bond)){
  if(high_yield_bound[i]==new_b){
  print(i)
}
} #循环函数for嵌套条件函数if,检验13永利债是否真的为“新的”高收益主体

最后的循环函数没有输出结果,或输出结果为NULL,证明“13永利债”就是我们要找的新兴高收益主体。

就这样通过一顿“猛如虎”的操作,我们复习了《统计学——基于R(第4版)》的第1章~第6章。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值