2025年5月14日星期三

如何用Tushare获取长时段、全市场日行情?

 个人做量化经常遇到的问题是数据。从最基本的全市场行情数据来说,如果没有开通诸如miniQMT的量化接口、购买某些官方数据库,个人很难直接获取高质量的全市场行情数据。当然,有些人也可以从某些平台上买到数据(诸如海鲜市场),但从第三方买到的数据,自己很难确保这些数据是否可靠,如果数据跟某些行情软件上的不一样,自己也不知道该如何调整。

本着以亲民、低门槛原则,本推文将介绍个人如何用Python从Tushare上获取长时段、全市场的日线行情。方法简单高效,可随时每日更新行情数据,以便让个人Quant能及时获取全市场行情数据,开展相应研究。

熟悉Tushare的朋友可能知道,Tushare主要有两个接口可以用来获取股票历史行情数据: ts.pro_bar() 和 pro.daily() ,其相应的官方介绍链接如下:

ts.pro_bar() 官方文档介绍

pro.daily() 官方文档介绍


简要来讲,ts.pro_bar()可以获取单只股票的日线行情数据,比如从2021年到2025年当日的长时段行情,未复权、前复权、后复权的数据都可以。ts.pro_bar() 一次只能获取一只股票的数据,不能输入多只股票代码一次性获取多只股票行情。如果是获取小批量的股票数据,比如说几十只股票数据,这个接口是最直白的,直接输入相应的股票代码,然后循环获取即可。

ts.pro_bar() 接口使用例子
ts.pro_bar() 接口使用例子

但是如果要获取几千只股票行情(全市场股票有5000多只),由于受Tushare对访问流量的控制,短时间内没法获取如此大量的数据。当然,如果不嫌麻烦、有时间慢慢等待,可以在访问一定的数据之后,等待一段时间(time.sleep( ),向大厂学习,熟练使用sleep技能),然后再继续获取,这样能避免Tushare的流量控制。


而pro.daily()接口可以获取多只股票、某个时段内的行情数据。如果要同时提取多个股票的历史行情,只需要将这些股票的代码用逗号连接起来,然后传给接口即可,具体例子如下:

# 同时获取多只股票在某个时段的行情

df = pro.daily(ts_code='000001.SZ,600000.SH', start_date='20180701', end_date='20180718')

这样听起来是不是觉得pro.daily()接口很完美,如果要获取全市场股票历史行情,那直接把全市场的股票代码全部连起来,设置下需要访问的时段(start_date, end_date),把这些参数传给pro.daily()接口不就完了,获取全市场行情如同呼吸一样简单😁。

然而事与愿违,pro.daily()也设置了访问限制,单次只能获取6000条数据,如果一次性访问全市场行情,按全市场有5000只股票计算,那一次大概只能访问一天的数据......并且pro.daily()也受Tushare的流量控制,短时间内调用的次数有限(通常每1分钟的访问次数计算)。当然,我们同样可以发挥 time.sleep()的强大功能,在调用pro.daily()接口一定次数后,让程序sleep一段时间,然后继续访问提取数据。如果有耐心、不追求获取数据效率,这种土方法是行得通的。

pro.daily()还有一个功能,它可以获取历史某日的全市场行情,只需要输入参数trade_date、其他参数不输入即可,示例代码如下:

# 获取历史某一天的全部行情

df = pro.daily(trade_date='20180810')

pro.daily(trade_date='20180810') 的输出


如果要获取全市场、某个时段的行情,那我们是不是可以用pro.daily()逐天地获取全市场行情,然后将每日的全市场行情数据保存在本地?就算Tusahre有流量控制,由于我们已经将部分天的数据保存在了本地,那直接获取本地数据即可,无需再调用pro.daily()接口来重复获取行情,徒增流量管控负担。比如,我们可以逐天获取2024年1月1号到2025年5月13号的每日全市场行情,将每次的行情数据保存在本地。到了2025年5月14号,我们直接用pro.daily()来获取5月14号的数据,然后跟2024年1月1号到2025年5月13号的本地数据拼接起来即可。


现在有最后一个问题:pro.daily() 获取的数据是没有复权的。不过获取的数据是有 pre_close 字段,那我们就自己写代码来对原始数据进行复权咯。到这里,我们所有的问题都已经解决,只差把上面的思路写成代码实现即可。部分代码截图如下:


获取数据部分代码截图


通过上面的流程,我们可以获取前复权、后复权的长时段、全市场行情。以收盘价为例,我们轻轻松松便可得到某个时段的数据。

我们方法获取的全市场、前复权收盘价

我们对比一下我们方法获取的和用ts.pro_bar()获取的前复权数据。以股票平安银行(000001.SZ)为例,两种方法得到的数据截图如下。可以看到两种方法得到的数据是一致的,证明我们的这个方案是成功的!

我们方法获取的前复权数据

ts.pro_bar()接口获取的前复权数据


没有评论:

发表评论

博客目录