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

JoinQuant量化平台如何实现商品期货30分钟周期日内交易与数据获取?

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

问题描述

如何实时更新并获取盘中数据?

各位前辈们双节快乐~我是一名刚接触量化的新人。
最近写了一个商品期货的策略,打算在30分钟周期进行日内交易,
我遇到的问题是:行情数据获取、运行频率,都写了every_bar,但回测时依旧是:只在每个交易日的9:30进行买卖。
想请问:如何在盘中实时更新并获取30分钟的数据?
谢谢!

解决方案

你好!欢迎来到量化交易的世界。针对你在JoinQuant(聚宽)平台上写商品期货30分钟周期策略遇到的问题,主要原因通常出在回测频率设置期货参考标的设置上。下面为你详细解答如何解决这个问题并获取30分钟数据。

问题诊断:为什么 every_bar 只在9:30交易?

  1. 回测频率选错了run_daily(func, time='every_bar') 的执行频率取决于你在回测界面右上角选择的“运行频率”。如果你选择了“天”,那么它每天只会在开盘(通常是9:30)执行一次。必须在回测界面将频率选择为“分钟”
  2. 期货的参考标的(reference_security)未设置:默认情况下,run_daily 的时间参照是A股(000001.XSHG),交易时间是9:30-15:00。商品期货有夜盘(如21:00开盘),如果不修改参考标的,引擎会按照A股的时间来跑,导致时间错乱。对于期货策略,必须将 reference_security 设置为对应的期货主力合约

解决方案:如何实时获取30分钟数据并进行日内交易

要实现30分钟周期的日内交易,推荐的做法是:按分钟频率回测,并在代码中通过时间判断或直接使用 get_bars 获取30分钟K线数据

1. 正确的初始化与频率设置

initialize 中,设置期货账户,并正确注册定时运行函数。

# 导入聚宽函数库
import jqdata

def initialize(context):
    # 设定基准(期货策略可以不设或设为0)
    set_benchmark({'000001.XSHG': 0})
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 设置期货账户
    init_cash = context.portfolio.starting_cash 
    set_subportfolios([SubPortfolioConfig(cash=init_cash, type='futures')])
    
    # 定义要交易的期货品种主力合约,例如螺纹钢
    g.security = 'RB9999.XSGE'
    
    # 注册运行函数,注意 reference_security 必须设置为期货合约!
    # 这样才能兼容期货的夜盘时间
    run_daily(market_open, time='every_bar', reference_security=g.security)

2. 获取30分钟数据

market_open(每分钟执行一次)中,你可以使用 get_bars 函数直接获取30分钟级别的K线数据。为了确保只在每30分钟的节点触发交易逻辑,可以通过判断当前分钟数来实现。

def market_open(context):
    # 获取当前时间
    current_dt = context.current_dt
    
    # 控制交易频率:每30分钟执行一次逻辑(例如 00分 和 30分)
    # 注意:期货开盘时间可能是 09:00 或 21:00,具体视品种而定
    if current_dt.minute % 30 != 0:
        return
        
    # 获取具体的交易合约(将主力合约映射为实际合约,如 RB1910.XSGE)
    real_contract = get_dominant_future(g.security, current_dt)
    if not real_contract:
        return
        
    # 获取过去5根30分钟K线数据
    # unit='30m' 表示30分钟周期,include_now=False 表示不包含当前未走完的这根Bar
    bars = get_bars(real_contract, count=5, unit='30m', 
                    fields=['date', 'open', 'close', 'high', 'low', 'volume'], 
                    include_now=False, df=True)
    
    if len(bars) < 5:
        return
        
    # 计算指标,例如简单的均线
    close_prices = bars['close']
    ma5 = close_prices.mean()
    current_price = close_prices.iloc[-1]
    
    # 获取当前持仓
    long_position = context.portfolio.long_positions.get(real_contract)
    short_position = context.portfolio.short_positions.get(real_contract)
    
    # 简单的交易逻辑示例:价格突破均线做多
    if current_price > ma5 and not long_position:
        # 如果有空单,先平空
        if short_position:
            order_target(real_contract, 0, side='short')
        # 开多单 1 手
        order(real_contract, 1, side='long')
        log.info(f"买入开多 {real_contract}")
        
    elif current_price < ma5 and not short_position:
        # 如果有多单,先平多
        if long_position:
            order_target(real_contract, 0, side='long')
        # 开空单 1 手
        order(real_contract, 1, side='short')
        log.info(f"卖出开空 {real_contract}")

总结与注意事项

  1. 回测界面设置:一定要在网页右上角把“运行频率”选为分钟
  2. 参考标的(reference_security):期货策略的 run_daily 必须带上 reference_security='你的期货代码',否则夜盘不会执行。
  3. 数据获取:使用 get_bars(..., unit='30m') 是获取分钟以上级别(如30m, 60m)最标准的方法,它会自动按照主流软件的切分方式为你合成30分钟K线。
  4. 主力合约映射:下单和获取数据时,尽量使用 get_dominant_future88889999 映射为真实的合约代码(如 RB2310.XSGE),因为直接对 9999 下单会报错。

祝你在量化交易的道路上越走越远,双节快乐!