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

聚宽平台如何精简多模式策略并大幅提升回测运行速度?

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

问题描述

聚宽多模式策略如何精简并提升运行速度?
如何在聚宽中精简多模式策略的趋势模块和买入逻辑,同时减少计算量并解决回测运行缓慢的问题?

解决方案

在聚宽(JoinQuant)平台上,多模式策略(如同时包含趋势跟踪、均线突破、多因子选股等模块)由于频繁调用历史数据和进行复杂的逻辑判断,极易导致回测速度变慢甚至因内存超限被系统终止。以下是精简趋势模块与买入逻辑、减少计算量并大幅提升运行速度的系统性优化方案:

一、 核心速度优化策略

  1. 使用 disable_cache() 规避内存超限
    如果策略因内存占用过大被系统终止,可以在 initialize 中调用 disable_cache()。虽然这在某些情况下会降低单次读取速度,但能有效防止大内存策略崩溃。

  2. df=False 替代 DataFrame 提高计算效率
    在调用 historyattribute_history 获取历史数据时,默认会返回 pandas.DataFrame。DataFrame 的创建和操作非常耗时。将参数 df 设为 False,让其返回 numpy.ndarray 字典,可以带来数倍的性能提升。

  3. 精简趋势模块:避免跨日期重复计算
    不要在 handle_data(每分钟执行)中重复获取长周期的日线数据。应将日线级别的趋势判断(如MA5、MA20)放在 before_trading_start(每日一次)中计算,或者使用定时运行函数 run_daily(func, time='9:30') 替代高频的 handle_data

  4. 精简买入逻辑:利用 get_current_data 快速过滤
    在买入前,先通过 get_current_data() 获取当前标的的停牌状态(paused)、是否ST(is_st)以及涨跌停价,快速过滤掉无法交易的股票,避免进入复杂的指标计算流程。


二、 优化前后的策略代码对比

1. 优化前(运行缓慢、计算量大)

# 糟糕的写法:在 handle_data 中每分钟都为所有股票创建 DataFrame 并计算均线
def handle_data(context, data):
    for security in g.stocks:
        # 每一分钟都获取过去5天的日线 DataFrame,极度耗时
        close_data = attribute_history(security, 5, '1d', ['close'], df=True)
        ma5 = close_data['close'].mean()
        current_price = data[security].close
        
        # 复杂的买入逻辑判断
        if current_price > ma5 * 1.01 and context.portfolio.available_cash > 0:
            order_value(security, 10000)

2. 优化后(精简高效、速度提升数倍)

import jqdata

def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    g.stocks = ['000001.XSHE', '000002.XSHE', '000063.XSHE']
    
    # 优化点 1:使用定时运行器,避免使用 handle_data 每分钟无谓计算
    run_daily(trade_logic, time='every_bar') 

def trade_logic(context):
    # 优化点 2:利用 get_current_data 快速过滤停牌和ST,减少后续计算量
    current_data = get_current_data()
    
    for security in g.stocks:
        if current_data[security].paused or current_data[security].is_st:
            continue # 停牌或ST直接跳过,不进行任何数据查询
            
        # 优化点 3:使用 df=False,返回 numpy 数组,速度极快
        hist = attribute_history(security, 5, '1d', ['close'], df=False)
        ma5 = hist['close'].mean() 
        
        current_price = current_data[security].last_price
        cash = context.portfolio.available_cash
        
        # 精简后的买入逻辑
        if current_price > ma5 * 1.01 and cash > 10000:
            order_value(security, 10000)
            log.info("买入: %s" % security)

三、 性能分析工具推荐

在回测时,建议在策略代码的最上方调用 enable_profile()。开启性能分析后,回测结果页面会展示每一行代码的执行次数(Hits)和总耗时(Time),帮助你精准定位策略中耗时最长的“趋势模块”或“买入逻辑”并进行针对性精简。