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

ptrade 获取几百只股票历史行情太慢?利用 is_dict=True 参数实现极速提速

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

问题描述

ptrade 性能优化:利用 get_history 的 is_dict=True 参数加速大数据量读取
ptrade 获取几百只股票的历史行情太慢,如何优化 get_history 的提速技巧?

解决方案

在 ptrade 量化交易平台中,当我们需要获取几百只甚至上千只股票的历史行情时,默认返回的 pandas.DataFramepandas.Panel 对象会因为内部的格式转换和索引构建,导致严重的性能瓶颈。为了解决这一痛点,ptrade 官方在 get_history 接口中提供了一个极速优化参数:is_dict=True

1. 为什么 is_dict=True 能大幅提速?

  • 免去 DataFrame 构建开销:默认情况下,ptrade 需要将底层的 C++ 或二进制数据结构转换为 Python 的 pandas.DataFrame。当股票数量极多时,这种转换非常耗时。
  • 极简的数据结构:当设置 is_dict=True 时,接口会直接返回一个 OrderedDict,其内部的值为 numpy.ndarray(结构化数组)。这种原生数组的读取和传输速度极快,非常适合大数据量的量化回测与实盘计算。

2. get_history 接口参数说明

get_history(count, frequency='1d', field='close', security_list=None, fq=None, include=False, fill='nan', is_dict=True)
  • is_dict:设置为 True 时,返回 OrderedDict 格式 {str: array()},取数速度相对较快。

3. 返回的数据格式对比

  • 默认格式 (is_dict=False):返回复杂的 pandas.DataFrame,包含时间索引和多列。
  • 优化格式 (is_dict=True):返回如下结构:
    OrderedDict([
        ('000001.SZ', array([(202309220931, 11.03, 11.07), ...], dtype=[('datetime', '<i8'), ('open', '<f8'), ('close', '<f8')]))
    ])
    

4. 提速优化示例代码

以下是一个完整的策略示例,展示了如何在 before_trading_starthandle_data 中利用 is_dict=True 快速获取并处理多只股票的历史收盘价:

def initialize(context):
    # 订阅沪深300成分股(约300只股票)
    g.security = get_index_stocks('000300.XBHS')
    set_universe(g.security)

def handle_data(context, data):
    # 1. 开启 is_dict=True 极速获取过去5天的收盘价
    # 此时返回的是 OrderedDict,key 为股票代码,value 为 numpy 结构化数组
    history_dict = get_history(
        count=5, 
        frequency='1d', 
        field=['datetime', 'close'], 
        security_list=g.security, 
        is_dict=True
    )
    
    if history_dict is None:
        return
        
    # 2. 快速遍历和计算,无需经过慢速的 DataFrame 索引
    for code in g.security:
        if code in history_dict:
            stock_data = history_dict[code]
            # 获取最近5天的收盘价数组
            close_prices = stock_data['close']
            
            # 计算5日均价(利用 numpy 的 mean,速度极快)
            ma5 = close_prices.mean()
            
            # 获取最新价格进行逻辑判断
            current_price = data[code]['close']
            
            # 策略逻辑示例
            if current_price > ma5 * 1.01:
                log.info("股票 %s 突破5日均线,触发买入信号" % code)

5. 性能优化黄金法则

  1. 多字段获取:如果需要多个字段,尽量在 field 中一次性传入(如 ['open', 'close', 'volume']),配合 is_dict=True 一次性读出,避免多次调用 get_history
  2. 避免多线程冲突:请注意,get_historyget_price 接口不支持多线程同时调用。在 run_dailyrun_interval 等定时任务中,避免与 handle_data 在同一时刻调用,否则可能导致获取数据为空。