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

JoinQuant聚宽策略中data是什么?如何使用及替代方案详解

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

问题描述

data是啥意思呢,请大佬帮忙举个例子,什么场景用data,不写data会有什么不同

解决方案

在 JoinQuant(聚宽)量化平台中,data 是一个非常经典的概念,主要出现在 handle_data(context, data) 函数中。下面为您详细解答 data 的含义、使用场景,以及不使用 data 的区别。

1. data 是什么意思?

在聚宽的 API 中,data 是一个字典(dict)类型的对象,它的 key 是标的代码(如 '000001.XSHE'),value 是当时的 SecurityUnitData 对象

它存放的是前一个单位时间(按天回测就是前一天,按分钟回测就是前一分钟)的数据快照。通过 data[security],你可以获取该标的在当时的开盘价、收盘价、最高价、最低价、成交量、是否停牌等信息,甚至可以直接调用内置方法计算均价。

常用的属性和方法包括:

  • data[security].close: 结束时价格(收盘价)
  • data[security].open: 开始时价格(开盘价)
  • data[security].volume: 成交量
  • data[security].paused: 是否停牌(True/False)
  • data[security].mavg(days): 过去 days 天的每天收盘价的平均值

2. 什么场景用 data?(举个例子)

通常在早期的策略编写中,我们会在 handle_data 中使用 data 来快速获取当前价格或计算均线,从而生成交易信号。

示例:使用 data 编写一个简单的双均线策略

def initialize(context):
    g.security = '000001.XSHE'

# handle_data 每天/每分钟自动运行一次
def handle_data(context, data):
    security = g.security
    
    # 场景1:判断股票今天是否停牌,停牌则不操作
    if data[security].paused:
        return
        
    # 场景2:获取当前价格(上一单位时间结束时的价格)
    current_price = data[security].close
    
    # 场景3:利用 data 自带的方法快速计算 5日 和 10日 均线
    ma5 = data[security].mavg(5)
    ma10 = data[security].mavg(10)
    
    # 产生交易信号
    if ma5 > ma10 and context.portfolio.positions[security].closeable_amount == 0:
        order_value(security, context.portfolio.available_cash)
    elif ma5 < ma10 and context.portfolio.positions[security].closeable_amount > 0:
        order_target(security, 0)

3. 不写 data 会有什么不同?(官方推荐做法)

非常重要的一点: 聚宽官方文档明确指出,为了向前兼容保留了 data 对象,但由于效率问题,现在已经不推荐使用了!

现在的标准写法是使用 run_daily 等定时运行函数,这些自定义函数只接收 context 一个参数,没有 data 参数。如果不使用 data,你需要使用聚宽提供的专门的数据获取 API(如 attribute_historyget_priceget_current_data 等)来替代。

不写 data 的不同之处:

  1. 代码结构不同:不再使用 handle_data,而是用 run_daily 绑定自定义函数。
  2. 获取数据方式不同:不能再用 data[security].close,而是用 attribute_historyget_current_data
  3. 运行效率更高data 对象在底层是按需动态生成的,频繁调用会拖慢回测速度;而直接使用 attribute_history 批量获取数据(如 Pandas DataFrame)效率高得多。

示例:不使用 data 的现代写法(推荐)

def initialize(context):
    g.security = '000001.XSHE'
    # 使用定时函数,每天开盘时运行 market_open
    run_daily(market_open, time='09:30')

# 自定义函数只有 context 参数,没有 data
def market_open(context):
    security = g.security
    
    # 替代场景1:使用 get_current_data 判断是否停牌
    current_data = get_current_data()
    if current_data[security].paused:
        return
        
    # 替代场景2 & 3:使用 attribute_history 获取历史收盘价来计算均线和当前价
    # 获取过去10天的收盘价数据
    hist = attribute_history(security, 10, '1d', ['close'])
    
    # 当前价格(取最后一天)
    current_price = hist['close'][-1]
    
    # 计算均线(利用 Pandas 的 mean 方法)
    ma5 = hist['close'][-5:].mean()
    ma10 = hist['close'].mean()
    
    # 产生交易信号
    if ma5 > ma10 and context.portfolio.positions[security].closeable_amount == 0:
        order_value(security, context.portfolio.available_cash)
    elif ma5 < ma10 and context.portfolio.positions[security].closeable_amount > 0:
        order_target(security, 0)

总结

  • data 是什么:历史遗留的标的数据快照对象,包含价格、成交量和简单的均线计算方法。
  • 使用场景:在 handle_data 中快速获取单只股票的当前状态和简单指标。
  • 不写 data 的区别:你需要改用 run_daily 配合 attribute_history / get_current_data 等 API。这是目前官方强烈推荐的做法,因为它的执行效率更高,且更适合进行多只股票的向量化(Pandas)计算。