🚀 AI 一键生成 joinquant 策略代码

JoinQuant 策略优化:如何高效使用 before_trading_start 函数进行盘前准备?

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

问题描述

怎样在每天开盘前运行一些准备代码?

解决方案

在聚宽(JoinQuant)平台中,要在每天开盘前运行准备代码,最标准和推荐的方法是使用系统内置的 before_trading_start(context) 函数。

以下是详细的实现方法和代码示例。

方法一:使用内置函数 before_trading_start(推荐)

这是聚宽框架提供的标准回调函数。

  • 运行时间:默认在每个交易日的 09:00 运行。
  • 用途:通常用于获取当天的财务数据、筛选股票池、重置每日的全局变量、处理停牌或ST股票过滤等。

代码示例

# -*- coding: utf-8 -*-
import jqdata

def initialize(context):
    # 初始化策略,设置基准等
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    log.info("策略初始化完成")

def before_trading_start(context):
    """
    每天开盘前运行一次 (默认 09:00)
    """
    log.info("---盘前准备开始---")
    
    # 1. 获取当前时间
    current_date = context.current_dt.date()
    log.info("当前日期: %s" % current_date)
    
    # 2. 重置或定义每日需要使用的全局变量
    g.daily_buy_list = [] 
    
    # 3. 示例:获取沪深300成分股作为今日备选股票池
    stocks = get_index_stocks('000300.XSHG')
    
    # 4. 示例:过滤掉今日停牌的股票
    current_data = get_current_data()
    g.buyable_stocks = [stock for stock in stocks if not current_data[stock].paused]
    
    log.info("今日可选股票数量: %d" % len(g.buyable_stocks))
    log.info("---盘前准备结束---")

def handle_data(context, data):
    # 盘中运行逻辑
    pass

方法二:使用 run_daily 定时运行(自定义时间)

如果你需要在 09:00 以外的特定时间(例如 09:15 或 09:25)运行准备代码,可以在 initialize 中使用 run_daily 函数进行注册。

代码示例

# -*- coding: utf-8 -*-
import jqdata

def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    
    # 注册一个自定义函数,在每天 09:10 运行
    run_daily(my_preparation, time='09:10')

def my_preparation(context):
    """
    自定义的盘前准备函数
    """
    log.info("执行自定义盘前准备,时间:%s" % context.current_dt)
    # 在这里编写你的准备逻辑
    # 注意:run_daily 注册的函数只能接收 context 一个参数
    g.my_signal = True

def handle_data(context, data):
    pass

常见用途

在盘前阶段(before_trading_start),通常进行以下操作:

  1. 选股与过滤:调用 get_fundamentals 查询财务数据,或使用 get_industry_stocks 获取行业成分股,并过滤掉 ST、退市或停牌的股票。
  2. 数据预处理:获取历史数据(historyattribute_history)计算技术指标(如均线),为盘中交易做准备。
  3. 变量重置:清空用于记录当日交易状态的全局变量(例如 g.today_bought_count = 0)。
  4. 更新参数:根据市场情况动态调整策略参数(如止损阈值)。

Q&A

Q: before_trading_start 函数中可以下单交易吗?
A: 虽然代码上可以调用 order 系列函数,但由于该函数默认在 09:00 运行,此时交易所尚未开盘(A股竞价在 09:15 开始),因此下的单通常会暂存,直到正式交易时段才会被撮合。建议将下单逻辑放在 handle_data 或通过 run_daily 设置在交易时间运行的函数中。

Q: 如果我在 before_trading_start 中获取 get_current_data(),能拿到当天的开盘价吗?
A: 不能。before_trading_start 默认在 09:00 运行,此时当天的集合竞价尚未开始,因此无法获取当天的开盘价(day_open)。如果需要获取当日开盘价,建议使用 run_daily 将函数设置在 09:25 或 09:30 之后运行。

Q: before_trading_startinitialize 有什么区别?
A: initialize 仅在回测开始的第一天执行一次,用于初始化整个策略的生命周期配置;而 before_trading_start 会在回测期间的每一个交易日开盘前都执行一次。