问题描述
量化获取财务数据报错:获取GTN数据为空,详细信息:
{'error_no': 0, 'error_info': ''}, 返回内容:{'error_no': '0'}
解决方案
在 ptrade 量化平台中,调用 get_fundamentals 接口获取财务数据时,如果遇到“获取GTN数据为空”的报错(详细信息:{'error_no': 0, 'error_info': ''}, 返回内容:{'error_no': '0'}),通常是由以下几个原因引起的:
1. 接口调用频率限制(流控)
原因:
get_fundamentals 接口为 HTTP 在线获取,存在严格的流量限制。根据 ptrade API 文档,每秒不得调用超过 100 次,单次最大调用量是 500 条数据(一条数据定义为一个股票对应一个表的一个字段)。如果您的策略在短时间内发起了大量请求,就会触发流控,导致返回空数据或报错。
解决方法:
在涉及多股多字段的查询时,必须考虑限流情况。依据实际调用场景,在代码中加入 time.sleep() 做时间间隔。
示例代码:
import time
def before_trading_start(context, data):
# 假设取4000股*10年一季报数据为4万条,之后再取中报又是4万条
# 因为规则要求每秒不得调用超过100次(单次最大调用量是500条数据)
# 调用过程就需要sleep1秒,防止流控触发
funda_data = get_fundamentals(g.security, 'balance_statement', fields='total_assets', start_year='2011', end_year='2020', report_types='1')
time.sleep(1) # 增加延时
funda_data2 = get_fundamentals(g.security, 'balance_statement', fields='total_assets', start_year='2010', end_year='2020', report_types='2')
2. 网络拥堵或服务端异常
原因:
由于该接口是在线获取数据,可能会因为网络拥堵或服务端临时异常导致应答失败,从而返回空数据。
解决方法:
在策略中增加保护机制(重试机制)。如果返回数据结果为空,可以尝试多次调用。
示例代码:
import time
def get_financial_data_with_retry(security, table, fields, max_retries=3):
for i in range(max_retries):
try:
data = get_fundamentals(security, table, fields)
if data is not None and not data.empty:
return data
except Exception as e:
log.warning(f"获取财务数据失败,正在重试 ({i+1}/{max_retries}): {e}")
time.sleep(1) # 重试前等待
log.error("获取财务数据失败,已达到最大重试次数。")
return None
3. 查询参数不合理
原因:
- 查询的日期(date)为非交易日:在回测和交易中,若
date为非交易日,将返回字段为 NAN 的数据;在研究中,若date为非交易日,将返回往前最近一个交易日的数据。 - 参数冲突:
date字段与start_year/end_year不能同时输入。 - 数据尚未发布:如果查询的日期早于财报发布日期,且未正确设置
date_type,可能获取不到数据。
解决方法:
- 检查传入的
date是否为交易日,建议使用get_trading_day(-1)获取上一个交易日。 - 确保参数组合正确,不要同时使用
date和start_year/end_year。 - 根据需求合理设置
date_type和merge_type。
总结
遇到“获取GTN数据为空”的报错,首先检查是否触发了频率限制,在代码中加入适当的 sleep。其次,增加重试机制以应对网络波动。最后,仔细核对查询参数是否符合 API 规范。