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

ptrade模拟交易模块调用get_history函数报错或获取不到数据怎么办?

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

问题描述

get_history函数在模拟交易模块中无法使用?

为什么在模拟交易模块中使用get_history函数报错或无法获取数据?

解决方案

在 ptrade 平台中,get_history 函数在回测、交易(包含模拟交易和实盘交易)、研究模块中均是可用的。如果您在模拟交易模块中使用该函数时遇到报错或无法获取数据(返回空值)的情况,通常是由以下几个常见原因导致的:

1. 多线程并发调用冲突(最常见导致数据为空的原因)

原因分析:根据 ptrade 官方 API 文档说明,get_history 接口与 get_price 接口不支持多线程同时调用。如果您在 run_dailyrun_interval 等定时/周期函数中,与 handle_data 等框架模块在同一时刻调用了 get_historyget_price 接口,会偶现获取数据为空的现象。
解决方法:错开调用时间。例如,不要将 run_daily 的执行时间设置在刚好触发 handle_data 的整分钟时刻,或者在代码逻辑中加入状态锁,避免并发请求行情数据。

2. 单只股票与多只股票的入参格式错误导致解析报错

原因分析get_history 的返回值结构会根据 security_list 参数的类型发生变化:

  • 单只股票:必须传入字符串类型(如 security_list='600570.SS')。此时返回的 DataFrame 列索引是行情字段(如 'open', 'close')。
  • 多只股票:必须传入列表类型。注意:即使列表中只有一只股票(如 security_list=['600570.SS']),系统也会将其作为多股票处理。在 Python 3.11 环境下,返回的 DataFrame 会多出一列 code;在 Python 3.5 环境下,可能会返回 Panel 对象或列索引为股票代码的 DataFrame。
    解决方法:严格区分单只股票和多只股票的传参方式,并根据返回的数据结构(DataFrame 或 dict)正确解析数据。建议开启 is_dict=True 参数,返回字典格式取数速度相对较快且结构稳定。

3. 未指定 security_list 且未设置全局股票池

原因分析:当调用 get_history 时,如果 security_list=None(默认值),系统会默认获取上下文 universe 中选中的所有股票数据。如果您的策略在 initialize 中没有调用 set_universe() 设置股票池,将无法获取到数据。
解决方法:在 initialize 中使用 set_universe() 设置股票池,或者在调用 get_history 时明确传入 security_list 参数。

4. 获取了 2005 年以前的数据

原因分析:API 限制 get_history 只能获取 2005 年之后的数据。如果请求的时间范围超出此限制,可能会报错或返回空。

正确调用示例

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

def handle_data(context, data):
    # 推荐用法:明确传入单只股票字符串,并使用 is_dict=True 提高速度
    his_dict = get_history(5, '1d', 'close', security_list=g.security, is_dict=True)
    if his_dict and g.security in his_dict:
        # 解析字典数据
        close_data = his_dict[g.security]
        log.info('获取到的历史收盘价数据: %s' % close_data)
    else:
        log.error('未获取到历史数据')

总结:在模拟交易中,请重点排查是否在 run_intervalhandle_data 中同时请求了历史数据,并检查 security_list 的参数类型是否与您的解析逻辑匹配。