小散量化炒股记|基于多任务爬虫技术, 实现A股实时行情Level1采样

0d1ca9fedb441a25adff90c9f5456cbd.png

前言

daf0224a1b01e1429a36ff8b59d6cd7e.png

股票行情数据对量化交易者来说非常重要,无论是短线交易者还是中长线交易着。

对于短线交易者来说,获取实时行情数据的方案涉及到盘中分析和买卖点监测的时效性。

对于中长线交易中来说,盘后更新全市场数据也要求下载尽可能快。如果用第三方Python数据库,比如tushare等,会受到服务器端的限制,全市场个股行情数据获取需要几十分钟。

本主题提及的A股实时行情数据获取方案,只需要三秒内就能获取全市场个股行情数据。

对于短线交易者来说每间隔3秒调取一次即可。对于中长线交易者来说,每天收盘后调取一次后存储到自己的数据库即可。

接下来就和大家详细介绍下这个方案!

3aba292bc0a27ef48336fe099ffee8bf.png

实时行情数据特征

e9399641ccb42b107af38cecbcbc9233.png

本主题提及的A股实时行情数据获取,是类似于Level1级别的更新,每间隔3秒以爬虫的方式从财经网站上实时采样获取到的。

如下图所示,数据类型有“最新价”、 “最高”(当前)、 “最低”(当前)、 “涨跌幅”(当前)、 “成交量(当天累加)”、 “成交额(当天累加)”、 “换手率”、 “市盈率”,然后我们增加一列“当前时间”,表示获取实时数据的时间。因为这些数据在财经网站上是实时更新的,所以有必要增加这一列。

fa5257a1c79ebf927c97c048f359e808.png

我们获取数据的交易时段是9:29至11.31,12:59至15:01,每间隔3秒获取一次数据,并且以csv文件格式存储。

bc1c29f27ce93c428e2e5574e89bec04.png

6a1cbf2ee2fa7a2b988ce58fbda8b48e.png

多线程爬虫技术

369b949c2da3062704f8a1adc1ea8114.png

接下来我们重点介绍下多线程爬虫技术的实现。

我们看到网页上显示总共有232页,通常大家是用for...in循环的方式爬取的。

但是面对几千只股票的行情数据时,下载过程势必会出现耗时过长的情况,从而导致超过3秒间隔的采样精度。

c085e5bef8d1633f2e7ea68f008fd743.png

我在书中《Python股票量化交易从入门到实践》介绍了多进程和多线程的提速方案。

当涉及复杂的计算、繁多的I/O 操作时,可以考虑使用多任务并行方式充分利用CPU多核性能来提高程序的执行效率。

在Python中由于GIL机制的的存在,多进行和多线程在计算密集型和I/O密集型的任务场景中执行效率会有所不同,多线程更适合 I/O 密集型应用,多进程对于 CPU 密集型的应用表现更好。

书中的例程,分别对比介绍了for循环方式、多线程方式和多进程方式。遍历获取股票池中前500只股票的1年的数据,测试的结果是:

  • for循环:55秒

  • 8个线程:7.5秒

  • 8个进程:7.8秒

可见,当我们获取A股几千只股票,过去几年甚至十几年数据的时候,如果以调用API接口方式,用for循环去获取股票数据,耗时非常严重。

那么,对于爬虫来说,它适合多线程还是多进程呢?

爬虫是基于网络请求模块urllib实现的。urllib3扮演了 HTTP 客户端的角色,即向网络服务器发送一个 HTTP 请求,然后等待网络服务器的响应,这类任务属于 I/O 密集型的任务。不同于计算密集型任务那样会在整个时间片内始终消耗 CPU 的资源,I/O 密集型的任务大部分时间都在等待 I/O 操作的完成。

接下来我们就以爬虫方式获取财经网站股票每日实时行情数据为场景,扩展介绍下多线程的提速方案。

关于爬虫的实现过程可参考知识星球以下主题:

47df59e1f64ccbbad9c28eece4a3c333.png

那么我们可以将该任务分配给多个线程来完成,而不只是让一个线程去逐一读取。

在 Python3 中内置了线程池模块 ThreadPoolExecutor,通过 ThreadPoolExecutor模块来实现多线程的处理。

对于爬虫任务来说,每一页仅仅是URL地址不同。因此按模块的使用要求,将爬虫任务crawer_daily()函数拆分为执行函数map_fun( )和可迭代参数 itr_arg 两部分。

关键代码如下所示:

with ThreadPoolExecutor(max_workers=8) as executor:
    # map_fun 传入的要执行的map函数
    # itr_argn 可迭代的参数
    # result  返回的结果是一个生成器
    results = executor.map(crawer_daily, itr_arg)

每一页只有20只股票的数据,因此我们需要把数据合并成一份DataFrame,最后保存为本地的csv文件。

关键代码如下所示:

for ret in results:
    df_daily_stock = df_daily_stock.append(ret, ignore_index=True)
df_daily_stock.to_csv(Path(store_path+u"{}.csv".format(df_daily_stock["当前时间"].values[0])), columns=df_daily_stock.columns, index=True, encoding='GBK')

打开csv文件如下所示:

aed820ca1e63682bc704991083ca8329.png

需要注意到的是增加了“当前时间”列,在盘中获取实时数据的话,对应的时间会体现数据更新的时间戳。

还有一个重要点是文件名,这里取的名字是“2021-08-27 15/00/00.csv”,如果是实时数据的话要体现出时/分/秒的信息。

关于测试的结果,我用了8个线程,执行的时间在0.5秒左右。也就是说,更新一次实时数据只需要0.5秒左右,是远小于3秒的采样周期的。

另外,如果我们只在收盘时增量更新日线数据,那么每天只需要花1秒时间就能更新完当日A股市场全部股票数据。

35db66678c2a2a2e825f6b287471d738.png

由于测试环境千差万别,此处测试结果仅供大家参考。大家也可以亲手对比下多线程和多进程的效率。

334fcaf4b90b6ab177ba2d76dba14681.png

如何获取实时数据

38f82bcb2195a23b14048d3a290b2962.png

我们会把源码上传到知识星球《玩转股票量化交易》,大家可以在本地获取数据,不过数据量有点大,一天的数据在3G左右,估计存一年的数据要留800G的硬盘空间。

我一般只会移动地留一个月左右的实时数据,再早期的会转换为分钟线存储,降低空间的占用。

同时,我们也在搭建的云服务器上保存了一周内的实时行情数据,如果大家平时只是需要数据做分析的话,可以在收盘后通过FTP方式获取。

打通量化系统数据源环节—股票数据远程下载服务来袭

如果大家需要在当天跟踪股价的变动,从而执行买卖操作的话,可以在自己的电脑上执行这个脚本,并添加自己的判断逻辑,当出现操作信号时候就通过邮箱、钉钉等即时工具发给你。

说明

1. 我们会把完整的源码上传到知识星球《玩转股票量化交易》中,帮助小伙伴们更好地掌握这个方法。

2. 想要加入知识星球《玩转股票量化交易》的小伙伴记得先微信call我获取福利!

10bd76ada986e0c4f9ca407cc30e62bd.jpeg

元宵大师的量化交易书籍开售!!
京东、当当、天猫有售!!

f3cf919f16ccf4b062887781897d3e17.jpeg

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值