Closed roc138 closed 6 months ago
请尝试修改qteasy的下面几个配置,调整下载数据时的重试次数和延时设置,这几个参数是专门为了应对tushare的读取频率限制设置的:
QT_CONFIG.hist_dnld_retry_cnt
- 下载数据时失败重试的次数,默认为7次
QT_CONFIG.hist_dnld_retry_wait
- 第一次下载失败时的等待时长,单位为秒,默认为1秒
QT_CONFIG.hist_dnld_backoff
- 等待后仍然失败时等待时间的倍增乘数,默认为2倍
qteasy
在调用所有的tushare
函数时,会自动retry
,每两次retry
之间会逐渐延长间隔。比如,第一次下载不成功时,会暂停一秒重试,如果重试仍然有问题,会等待2秒重试,下一次等待4秒、再等待8秒。。。依此类推,一直到重试次数用光,这时才会raise。
正常来讲,重试7次后的延时会倍增到32秒,加上前面延时的长度,已经超过1分钟了,正常是不会触发频率错误的,但如果您的网速过快,或者同时启用的线程太多,可能会有上面的问题。
可以尝试将重试次数改成10次或更多(这样会显著延长下载时间),或者增加等待初始时长:
qt.configure(hist_dnld_retry_cnt=10, hist_dnld_retry_wait=2.)
如果您做了上面的修改仍然会报错,那么有可能是我最近在1.1.7以后版本的retry
函数中增加的“逃逸”信息引起的,因为我考虑到有的情况下如果tushare
报错说用户没有权限,那么就没必要一直重试了,因此设置了一些逃逸条件。如果是这个情况,请告诉我,我来仔细检查。
使用qt.configure(hist_dnld_retry_cnt=10, hist_dnld_retry_wait=2.)后还是报错。
我又增加了几个参数,也还是会报错。 qt.configure(hist_dnld_retry_cnt=10, hist_dnld_retry_wait=5.,hist_dnld_delay=2.,hist_dnld_delay_evy=2,hist_dnld_backoff=3.) qt.refill_data_source(tables='events', start_date='20230101', end_date='20240403', reversed_par_seq=True)
[#################-----------------------]7551/16923-44.6%
进程已结束,退出代码为 0
经检查,问题的原因在于我使用了静态decorator来实现tushare api的重试。重试的参数是在程序读取的时候就确定了,后面即使修改config参数,实际重试的次数也不会改变。所以,尽管已经将重试次数改为10次,但实际上程序运行时仍然只重试7次。
抱歉造成上面的问题,现在已经有了解决方案。
解决方案是使用动态decorator,每次调用tushare api的时候系统会读取config参数并重新生成decorated_func,经测试,修改config参数后,重试的参数已经能按照config改变了。
另外,为了方便,对于tushare实施了频率限制的api,现在他们的retry次数会被特殊处理。qteasy在使用这些api获取数据时,会在config设置的基础上多3次重试。用户不再需要手动修改。会自动额外重试的API包括:
'name_change'
'stk_managers'
'daily_basic'
'index_daily'
'options_daily'
'fund_share'
'fund_manager'
'hibor'
'libor'
如果完整的测试都能通过,上面的改变将在1.1.10版本中发布,敬请期待!
修正bug之后的qteasy
v1.1.10
版本已经发布到pypi
!请升级最新版qteasy
。
$ pip install qteasy -U
更新后的版本改变了retry
装饰器的使用方式,使得QT_CONFIG
变化后能立即影响retry
的参数。因此,在从tushare
下载数据时如果积分不够导致频率受限,可以通过修改以下参数增加重试次数和等待时间,规避因频率受限导致的下载失败。
QT_CONFIG.hist_dnld_retry_cnt
- 下载数据时失败重试的次数,默认为7次
QT_CONFIG.hist_dnld_retry_wait
- 第一次下载失败时的等待时长,单位为秒,默认为1秒
QT_CONFIG.hist_dnld_backoff
- 等待后仍然失败时等待时间的倍增乘数,默认为2倍
麻烦再测试一下,如果问题得到解决,请关闭此Issue,如果还有其他问题,请跟我联系!
程序运行过程中尝试次1次失败后,再进行第2次尝试,成功了。
C:\ProgramData\anaconda3\envs\qteasy-env-p311\Lib\site-packages\qteasy\database.py:5085: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.
dnld_data = pd.concat([dnld_data, df])
[#########################---------------]10800/16923-63.8%
第1个问题是个告警,应该不影响什么吧? C:\ProgramData\anaconda3\envs\qteasy-env-p311\Lib\site-packages\qteasy\database.py:5085: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation. dnld_data = pd.concat([dnld_data, df])
第2个问题,换了2个5000分以上tushare token,都还是报错。估计是tushare 每分钟读取频率限制的问题,请问大佬哪里可以调整tusahre数据的读取频率?
运行的脚本: qt.refill_data_source(tables='events', start_date='20230101', end_date='20240403',reversed_par_seq=True) 把refill_data_source函数中的parallel=True,merge_type='update'参数去掉了也还是不行。
报错日志: [##############--------------------------]6000/16923-35.5%37107wrtn/about 19 minleftC:\ProgramData\anaconda3\envs\qteasy-env-p311\Lib\site-packages\qteasy**database.py:5134: UserWarning:
抱歉,您每分钟最多访问该接口600次,权限的具体详情访问:https://tushare.pro/document/1?doc_id=108。:
download process interrupted at [fund_share]:<F180003.OF>-<016408.OF>
37107 rows downloaded, will proceed with next table!
warnings.warn(msg)
[#######################-----------------]10000/16923-59.1% 1264483wrtn/about 15 minleftC:\ProgramData\anaconda3\envs\qteasy-env-p311\Lib\site-packages\qteasy\database.py:5134: UserWarning:
抱歉,您每分钟最多访问该接口500次,权限的具体详情访问:https://tushare.pro/document/1?doc_id=108。:**
download process interrupted at [fund_manager]:<F180003.OF>-<012278.OF>
1264483 rows downloaded, will proceed with next table!
warnings.warn(msg)
有没有这种类似的参数可以设置的?
self.params.rows_limit = 5000 # 该接口限制每次调用,最大获取数据量