问题描述
调用get_fundamentals获取600000.SS代码2024年1月的profit_ability表的roe字段数据报错:
获取GTN数据为空,详细信息:{'error_no': 0, 'error_info': ''}, 返回内容:{'error_no': '0'}
命令如下:
get_fundamentals('688001.SS','profit_ability','roe','20240117')
解决方案
在 ptrade 平台调用 get_fundamentals 接口获取财务数据时,遇到返回为空或报错 获取GTN数据为空,通常是由以下几个原因引起的:
1. 网络请求失败或超时
根据 ptrade API 文档说明,get_fundamentals 接口是通过 HTTP 在线获取数据的。由于网络波动或服务器拥堵,可能会导致应答失败,从而返回空数据或报错。
2. 接口流量限制(流控)
该接口有严格的流量限制:每秒不得调用超过100次,单次最大调用量是500条数据。如果在短时间内频繁调用,或者一次性请求了大量股票和字段,会触发流控导致获取失败。
3. 财报发布时间的客观原因
你查询的日期是 20240117。在1月中旬,绝大多数上市公司还未发布2023年的年报,此时获取的应该是2023年三季报的数据。如果底层数据源在特定日期的切片数据存在缺失,也可能导致返回为空。
解决方案与代码优化
为了解决这个问题,必须在策略中加入重试机制(Retry)和异常保护(Try-Except),并在重试之间加入适当的延时(time.sleep)。
以下是优化后的代码示例:
import time
import pandas as pd
def get_financial_data_with_retry(security, table, fields, date, max_retries=3):
"""
带重试机制的财务数据获取函数
"""
for attempt in range(max_retries):
try:
# 调用接口获取数据
df = get_fundamentals(security, table, fields, date=date)
# 检查返回值是否有效
if df is not None and not df.empty:
return df
else:
log.warning(f"第 {attempt + 1} 次尝试:获取 {security} 的 {table} 数据为空。")
except Exception as e:
log.error(f"第 {attempt + 1} 次尝试:获取数据发生异常,错误信息:{e}")
# 如果失败,等待 1 秒后重试,避免触发流控
time.sleep(1)
log.error(f"已达到最大重试次数 {max_retries},未能获取到 {security} 的财务数据。")
return pd.DataFrame() # 返回空 DataFrame 以防后续代码报错
def initialize(context):
g.security = '688001.SS'
set_universe(g.security)
def before_trading_start(context, data):
# 使用封装好的重试函数获取数据
query_date = '20240117'
funda_data = get_financial_data_with_retry(
security=g.security,
table='profit_ability',
fields='roe',
date=query_date
)
if not funda_data.empty:
log.info(f"成功获取数据:\n{funda_data}")
else:
log.info("未能获取到有效的财务数据,请检查日期或稍后再试。")
def handle_data(context, data):
pass
注意事项
profit_ability表不支持merge_type参数:在调用盈利能力、成长能力、营运能力、偿债能力和每股指标表时,不要传入merge_type参数。- 避免在
handle_data中高频调用:get_fundamentals是耗时操作,强烈建议将其放在before_trading_start或run_daily定时任务中执行,并将结果保存到全局变量g中供盘中逻辑使用。 - 检查代码后缀:确保股票代码后缀正确(上交所为
.SS,深交所为.SZ)。