云淡风轻

  • 量化与交易
  • 关于站长
博学笃志 切问近思
  1. 首页
  2. 量化与交易
  3. 固定收益
  4. 正文

Python爬虫抓取债券借贷数据

2019年4月18日 2437点热度 2人点赞 0条评论

2020年更新:本文的方法已经失效,现需采购交易中心数据方可获得个券借贷数据

 

债券借贷是YH间市场借券卖空最主要的交易途径,买断式回购虽然也能开展借券卖空,但是在出借债券的方式上,YH还是明显更加偏好债券借贷,一方面债券借贷借出时债券不出表,另一方面借贷费用收入是中间业务收入,相比于买断式回购在这两点上具有显著优势。所以债券借贷存量数据对于市场卖空力度是一个很好的指标,尤其是一些新券。目前市场上新券借贷费率显著高于老券,机构借入老券还有可能用于回购融资,而承担高费率借入新券则大概率是用于卖空。

去年,债券市场大牛市,资金也很宽松,债券借贷卖空和融资的需求都减弱不少,然而今年债市波动加剧,国开和GZ最新券卖空力量显著加强,债券借贷的存量也显著上升,以180027为例,在3-4月间其债券借贷存量上升100多亿。在这样的背景下,我们必须对债券借贷数据重新重视起来。此前,债券借贷数据每日均公布在外汇交易中心的网站上,然而目前此数据的链接已经不显示在chinamoney网站上了,虽然并非无法访问,但访问方式很麻烦,也无法一次性导出。我参考18年初固收小黄的公众号文章优化了python爬虫的代码,可以一次性导出指定债券的借贷历史数据到excel,并自动更新数据并保存至原excel文件,可以方便的每日定时运行该程序进行自动更新。

第一部分代码定义几个函数

import datetime
import time
#外部包,xlwt,xlrd,xlutils是excel读写包,WindPy是Wind包,BeautifulSoup用于网页解析,urllib用于获取网页
import xlwt
import xlrd
from xlutils.copy import copy
from bs4 import BeautifulSoup
import urllib
import datetime
from WindPy import w

def getTradingDayList(date):
    w.start()
    trade_day_list=[]
    if date==0:
        #如果原本没有数据,从T-20日开始
        startdate = w.tdaysoffset(-20, time.strftime("%Y-%m-%d"), "TradingCalendar=NIB")
    else:
        #获取现有最新数据的下一交易日
        startdate = w.tdaysoffset(1, date, "TradingCalendar=NIB")
    if startdate.Times[0]>=datetime.date.today():
        print('Data is up-to-date')
    else:
        tm1=w.tdaysoffset(0, time.strftime("%Y-%m-%d"), "TradingCalendar=NIB")
        #如果今日是交易日,则获取数据截至上一交易日
        if tm1.Times[0]==datetime.date.today():
            tm1=w.tdaysoffset(-1, time.strftime("%Y-%m-%d"), "TradingCalendar=NIB")
        trade_day_list = w.tdays(startdate.Times[0],tm1.Times[0], "TradingCalendar=NIB").Times
    w.stop()
    return trade_day_list

def getlastday(filename):
    try:
        #打开文件
        data = xlrd.open_workbook(filename)
        table = data.sheets()[0]
        rows=table.nrows
        #获取最后一行第一列的日期
        date = xlrd.xldate_as_tuple(table.cell(rows-1,0).value,0)
        value = datetime.datetime(*date)
        return value
    except FileNotFoundError:
        #找不到文件
        return 0
    
def zqjd_one_day(year, month, day,bond_list):
    #把日期填入链接,得到实际的url
    turl="http://www.chinabond.com.cn/jsp/include/EJB/jdtj_dzzq.jsp?sel4=1&tbSelYear6=" + str(year) + "&tbSelMonth6=" + str(month) + "&calSelectedDate6=" + str(day)+ "&ZQFXRJD1=00&FUXFSJD1=00&JXFSJD2=00&JDQX2=00&ZQFXRJD3=00&ZQFXRJD4=00&I_ZQDM_JD="
    #交易中心网站已屏蔽爬虫,必须指定header伪装为浏览器否则爬虫无法访问网站
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}  
    req = urllib.request.Request(url=turl, headers=headers)  
    #获取网页信息
    page = request.urlopen(req)
    #解析,使用gb18030防止中文乱码
    soup = BeautifulSoup(page, "html.parser", from_encoding="gb18030")
    jqye_list = []
    print('Trading Day '+str(year) + str(month).zfill(2) + str(day).zfill(2) + ':' )
    for bond_name in bond_list:
        #找到表格中债券代码匹配的行
        bond_position = soup.find('td', text=bond_name)
        if bond_position is None:
            #没找到,借贷量为0
            bond_jqye = 0
        else:
            #交易中心数据格式为100,000.00,所以去掉.00和逗号
            bond_jqye = int(bond_position.next_sibling.next_sibling.string.strip().replace(',', '').replace('.00', ''))
        print(bond_name + ':' + str(bond_jqye))
        jqye_list.append(bond_jqye)
    return jqye_list

def zqjd(bond_list,trade_day_list,filename):
    #指定excel日期存储格式
    datastyle = xlwt.XFStyle()
    datastyle.num_format_str = 'yyyy/mm/dd'
    total_jqye_list=[]
    try:
        #打开现有文件
        data = xlrd.open_workbook(filename, formatting_info=True)
        table = data.sheets()[0]
        startrow = table.nrows-1
        # 将文件对象拷贝,变成可写的workbook对象
        output_workbook = copy(data)
        # 获得第一个sheet的对象
        sheet1 = output_workbook.get_sheet(0)
    except FileNotFoundError:
        #找不到文件,则创建Excel文件,excel同单元格可覆盖写入
        output_workbook = xlwt.Workbook()
        sheet1 = output_workbook.add_sheet(u'BondLendingData', cell_overwrite_ok=True)
        startrow=0
    #遍历所有交易日
    for trade_day in trade_day_list:
        #获取每个交易日的借贷信息
        jqye_list = zqjd_one_day(trade_day.year, trade_day.month, trade_day.day, bond_list)
        #暂停5秒,防止过于频繁访问网站被封禁
        time.sleep(5)
        total_jqye_list.append(jqye_list)
        #Excel的A1单元格写入Date
        if startrow==0:
            sheet1.write(0, 0, 'Date')
        for i in range(len(bond_list)):
            #从第一行的第二个单元格开始从左至右写入债券代码
            sheet1.write(0, i + 1, bond_list[i])
        for i in range(len(total_jqye_list)):
            #每个交易日另起一行,左起写入交易日,格式为指定的日期格式
            sheet1.write(startrow + i + 1, 0, trade_day_list[i],datastyle)
            for j in range(len(total_jqye_list[i])):
                #写入在该交易日每个债券对应的借贷量
                sheet1.write(startrow + i + 1, j + 1, total_jqye_list[i][j])
        #逐行保存到Excel文件
        output_workbook.save(filename)
    return

第二部分为主体部分,相对简单

import datetime

filename='zqjd_output.xls'
#取现有最新数据的日期
date=getlastday(filename)
trade_day_list=getTradingDayList(date)
#print(trade_day_list)
if trade_day_list:
    bond_list = ['190205', '180210' ,'180027']
    zqjd(bond_list,trade_day_list,filename)
print('Done!')

python输出如下所示

Trading Day 20190415:
190205:3889000
180210:4238000
180027:1810000
Trading Day 20190416:
190205:4279000
180210:4178000
180027:1854000
Trading Day 20190417:
190205:4473000
180210:4024000
180027:1877000
Done!

excel输出如下所示

Date190205180210180027
2019/04/15388900042380001810000
2019/04/16427900041780001854000
2019/04/17447300040240001877000

此程序输入参数主要有两个,一个是债券列表,例子中为190205,180210,180027,其二为文件名,本例中zqjd_output.xls,实际上另外还有一个输入是交易日区间,上述代码中交易日是自动获取的,第一次运行从T-20开始获取数据,此后自动更新补全至最新交易日。输出就是一个xls文件,借贷量数字单位为万,可以很方便的进行后续处理和展示。不过需要注意的是,如果更改了债券列表,则需要删除原文件或指定新的文件名,否则更新数据将出现错乱的情况。

标签: 暂无
最后更新:2021年8月16日

世平矿

博学笃志,切问近思

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

世平矿

博学笃志,切问近思

分类
  • C++
  • 交易执行
  • 其他
  • 区块链
  • 固定收益
  • 技术指标
  • 数据库
  • 机器学习
  • 网站
  • 资产配置
  • 量化与交易
归档
  • 2025 年 2 月
  • 2024 年 12 月
  • 2022 年 1 月
  • 2021 年 6 月
  • 2021 年 1 月
  • 2020 年 12 月
  • 2019 年 4 月
  • 2018 年 12 月
  • 2018 年 11 月
  • 2018 年 10 月
  • 2018 年 9 月
  • 2018 年 8 月
  • 2018 年 6 月
  • 2018 年 5 月
  • 2018 年 4 月
  • 2018 年 2 月
  • 2018 年 1 月
  • 2017 年 12 月
  • 2017 年 11 月
  • 2017 年 10 月
  • 2017 年 9 月
  • 2017 年 7 月
  • 2017 年 6 月
  • 2017 年 5 月

COPYRIGHT © 2025 lishiping.site. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang