🚀 AI 一键生成 ptrade 策略代码
立即体验
👉 AI 生成代码 👈

ptrade 策略中 get_fundamentals 获取数据为空怎么办?(附限流与网络异常处理方案)

ptrade | 发布时间: 2026/5/28
以下内容由 EasyQuant 生成。

问题描述

策略交易中使用get_fundamentals获取数据时,数据获取为空,报错:获取GTN数据为空! "

/

解决方案

问题原因分析

在 ptrade 量化平台中使用 get_fundamentals 获取财务数据时,如果遇到数据为空或报错“获取GTN数据为空!”,通常是由以下几个原因导致的:

  1. 网络拥堵或请求超时get_fundamentals 接口底层为 HTTP 在线获取,在交易时段网络拥堵时,极易出现应答失败或返回空数据的情况。
  2. 触发了 API 流量限制(流控):官方文档明确指出,该接口有严格的流量限制:每秒不得调用超过100次,单次最大调用量是500条数据(一条数据 = 一个股票 + 一个表 + 一个字段)。如果循环调用过快或单次请求数据量过大,会被服务器拒绝。
  3. 参数组合冲突date 字段与 start_year/end_year 不能同时输入。如果同时传入,会导致查询逻辑混乱,返回空值。
  4. 数据尚未发布(未来函数规避):如果在盘中时间获取当天的财务数据,由于数据尚未更新,可能会返回 NaN。建议在获取最新数据时,将 date 参数设置为上一个交易日。

解决方案与优化建议

针对上述原因,可以通过在策略代码中增加保护机制限流控制来彻底解决此问题。

1. 增加异常重试机制

由于网络原因导致的偶发性获取失败,可以通过编写一个带有重试机制的封装函数来解决。如果返回为空,则等待短暂时间后重试。

2. 加入休眠 (Sleep) 规避限流

在进行多股、多字段或多时间段的批量查询时,务必在两次调用之间加入 time.sleep(),防止触发每秒 100 次的流控限制。

3. 检查参数规范

确保查询模式单一:要么使用 date 按日期查询,要么使用 start_yearend_year 按年份查询。

优化后的代码示例

以下是一个封装好的、带有重试机制和防流控的财务数据获取函数示例:

import time

def get_fundamentals_safe(security, table, fields=None, date=None, max_retries=3):
    """
    安全获取财务数据,包含重试机制和防流控休眠
    """
    for attempt in range(max_retries):
        try:
            # 调用官方接口
            data = get_fundamentals(security, table, fields=fields, date=date)
            
            # 检查数据是否为空
            if data is not None and not data.empty:
                return data
            else:
                log.warning(f"第 {attempt + 1} 次获取 {security} 的 {table} 数据为空,准备重试...")
        except Exception as e:
            log.error(f"第 {attempt + 1} 次获取财务数据发生异常: {e}")
        
        # 触发流控或网络异常时,休眠后重试 (递增休眠时间)
        time.sleep(1 + attempt)
        
    log.error(f"已达到最大重试次数 {max_retries},获取 {security} 财务数据失败!")
    return None

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)

def before_trading_start(context, data):
    # 建议获取前一交易日的数据,避免当天数据未更新
    pre_date = get_trading_day(-1).strftime('%Y%m%d')
    
    # 使用安全封装函数获取资产负债表数据
    funda_data = get_fundamentals_safe(g.security, 'balance_statement', fields='total_assets', date=pre_date)
    
    if funda_data is not None:
        log.info("成功获取财务数据:\n%s" % funda_data)
    else:
        log.error("未能获取到财务数据,请检查网络或参数。")

def handle_data(context, data):
    pass

总结

在 ptrade 中调用 HTTP 类的在线数据接口(如 get_fundamentals)时,**“防御性编程”**是必不可少的。通过加入 try-except 异常捕获、time.sleep() 延时以及多次重试逻辑,可以有效避免因“获取GTN数据为空”导致的策略中断。