4.07K 浏览
0

对几千个参数进行回测,会用到几十个 某合约某周期某时间段的数据。

电信网络100M下载带宽,每个合约、每个参数在一个新子进程中跑,回测过程中出现大量以下类似的数据获取超时异常报错:

raise Exception("获取 %s 的行情超时,请检查客户端及网络是否正常,且合约代码填写正确" % (symbol))
Exception: 获取 SHFE.fu1909 的行情超时,请检查客户端及网络是否正常,且合约代码填写正确

raise Exception("获取 %s (%d) 的K线超时,请检查客户端及网络是否正常" % (symbol, duration_seconds))
Exception: 获取 ['SHFE.fu1909'] (86400) 的K线超时,请检查客户端及网络是否正常

raise Exception("获取 %s (%d) 的K线超时,请检查客户端及网络是否正常" % (symbol, duration_seconds))
Exception: 获取 ['SHFE.fu1909'] (86400) 的K线超时,请检查客户端及网络是否正常

(self.host, self.timeout))
urllib3.exceptions.ConnectTimeoutError: (<urllib3.connection.VerifiedHTTPSConnection object at 0x7f91444c72e8>, 'Connection to openmd.shinnytech.com timed out. (connect timeout=30)')
 During handling of the above exception, another exception occurred:
      raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='openmd.shinnytech.com', port=443): Max retries exceeded with url: /t/md/symbols/latest.json (Caused by ConnectTimeoutError(<urllib3.connection.VerifiedHTTPSConnection object at 0x7f91444c72e8>, 'Connection to openmd.shinnytech.com timed out. (connect timeout=30)'))
 During handling of the above exception, another exception occurred:
 requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='openmd.shinnytech.com', port=443): Max retries exceeded with url: /t/md/symbols/latest.json (Caused by ConnectTimeoutError(<urllib3.connection.VerifiedHTTPSConnection object at 0x7f91444c72e8>, 'Connection to openmd.shinnytech.com timed out. (connect timeout=30)'))
     sock.connect(sa)
socket.timeout: timed out

解决办法建议:

是否能在本地目录下建立一个临时的数据缓存,例如调用api = TqApi(account=acc,backtest=TqBacktest(start_dt=yyy, end_dt=xxx,) 或 调用get_quote、get_kline_serial时指定一个目录缓存这个某个合约、某个周期粒度、某个时间范围的历史数据,这样再次调用的时候可以选择是否优先从本地读取,这样如果反复对同样的历史数据回测,只需要反复从本地磁盘读取。历史数据不太可能发生变化,即使有发生变化的可能,可以生成一个数据集的类md5内容摘要校对下判断是否重新下载。

这样的好处:

例如回测10000次参数,每次回测要调用50个数据集合(某个合约、某个周期粒度、某个时间范围,往往是N段主力合约)回测,因为每次回测都是走的独立子进程方法,子进程中重新初始化api回测某一个参数和某一小段数据,现在你们的做法是要向服务器调用10000*50=50万次数据请求,这样对服务器造成很大压力。如果有了缓存,只需要第一次向服务器请求50次数据,后续的回测都直接从本地磁盘读取。即使分散在10台服务器上跑这些回测,也只需要一共请求50*10=500次,远远小于50万次。

west 发表新评论 2020年2月3日

报错:
raise Exception(“获取 %s (%d) 的K线超时,请检查客户端及网络是否正常” % (symbol, duration_seconds))
Exception: 获取 [‘SHFE.fu1909’] (86400) 的K线超时,请检查客户端及网络是否正常
。。。。。。

anaconda3-64/lib/python3.6/site-packages/OpenSSL/SSL.py”, line 1631, in _raise_ssl_error
raise SysCallError(errno, errorcode.get(errno))
OpenSSL.SSL.SysCallError: (104, ‘ECONNRESET’)
。。。。。。

anaconda3-64/lib/python3.6/site-packages/tqsdk/api.py”, line 496, in get_kline_serial
raise Exception(“获取 %s (%d) 的K线超时,请检查客户端及网络是否正常” % (symbol, duration_seconds))
Exception: 获取 [‘SHFE.fu1909’] (86400) 的K线超时,请检查客户端及网络是否正常
。。。。。。

anaconda3-64/lib/python3.6/site-packages/tqsdk/api.py”, line 496, in get_kline_serial
raise Exception(“获取 %s (%d) 的K线超时,请检查客户端及网络是否正常” % (symbol, duration_seconds))
Exception: 获取 [‘SHFE.fu2005’] (86400) 的K线超时,请检查客户端及网络是否正常

以上拉取数据超时报错是在电信500M下载带宽下跑的,应该还是服务器反应不过来了

你这两次贴的报错信息都不同,这两次运行的代码之类的是否有改动过?

0

用異步代碼就可以了

王森 已回答的问题 2020年2月2日