问题描述
解决方案
在 JoinQuant 聚宽平台中,要实现期货策略在夜盘开盘时运行,核心在于使用 run_daily 函数配合 time='open' 参数,并正确设置 reference_security(参考标的)。
以下是具体的设置方法和代码示例:
核心设置步骤
- 使用
run_daily函数:这是设置定时任务的主要 API。 - 设置
time='open':这代表在参考标的的“开盘时间”运行。 - 设置
reference_security:这是最关键的一步。必须将其设置为一个拥有夜盘的期货合约代码(如主力合约AG9999.XSGE或具体合约RB2410.XSGE)。- 如果参考标的默认为股票(如
000300.XSHG),time='open'会在 09:30 触发。 - 如果参考标的为有夜盘的期货(如
AG9999.XSGE),time='open'会在夜盘开盘时间(通常为 21:00)触发。
- 如果参考标的默认为股票(如
代码示例
# -*- coding: utf-8 -*-
def initialize(context):
# 设置基准(可选)
set_benchmark('AG9999.XSGE')
# 【关键设置】
# 1. func: 指定要运行的函数名(这里是 market_open_handler)
# 2. time='open': 表示在开盘时运行
# 3. reference_security: 指定参考标的为白银主力合约(有夜盘)
# 这样设置后,如果该合约有夜盘,函数会在 21:00 运行;如果没有夜盘,则在 09:00 运行
run_daily(market_open_handler, time='open', reference_security='AG9999.XSGE')
# 如果需要在开盘后几分钟运行,可以使用 'open+5m'
# run_daily(trade_after_open, time='open+5m', reference_security='AG9999.XSGE')
def market_open_handler(context):
# 这里编写夜盘开盘时需要执行的逻辑
log.info("当前时间: %s,夜盘开盘逻辑触发" % context.current_dt)
# 获取当前参考标的的时间,确认是否为夜盘时间
current_hour = context.current_dt.hour
if current_hour >= 20:
log.info("检测到夜盘交易时段")
# 下单逻辑...
详细说明
-
time参数的灵活性:'open':在开盘第一分钟运行。'open+n m':在开盘后第 n 分钟运行(例如'open+15m')。'open-n m':在开盘前 n 分钟运行(注意:这通常用于before_trading_start的逻辑,但在run_daily中较少用于开盘前,因为run_daily通常在交易时段内触发)。
-
reference_security的重要性:- 聚宽的回测引擎需要依据一个标的的时间轴来驱动策略。
- 不同的期货品种夜盘开盘时间可能不同(大部分是 21:00,但黄金、白银等可能不同,且未来交易所规则可能变化)。绑定具体的期货合约作为参考,可以确保策略紧随该品种的实际交易时间。
-
关于
before_trading_start:- 对于有夜盘的期货策略,
before_trading_start函数也会在夜盘开盘前运行(通常是开盘前半小时左右,例如 20:30 或 20:50),而不是第二天早上的 08:30。因此,盘前的数据处理和初始化也可以放在这个内置函数中。
- 对于有夜盘的期货策略,
Q&A
Q: 如果我直接设置 time='21:00' 可以吗?
A: 可以,但不推荐。
- 如果直接写死时间,当交易所调整交易时间,或者该品种没有夜盘(或夜盘时间不是21:00)时,策略可能会出错或不运行。
- 使用
time='open'配合reference_security是最稳健的做法,它会自动适应标的的实际开盘时间。
Q: 如果参考标的没有夜盘(例如股指期货 IF),time='open' 会在什么时候运行?
A: 如果参考标的(如 IF9999.CCFX)没有夜盘,time='open' 会在白天的开盘时间(通常是 09:30,股指期货可能是 09:30 或 09:15 取决于具体回测年份的规则)运行。
Q: run_daily 和 handle_data 在夜盘都会运行吗?
A: 是的。
run_daily按照你设定的时间运行。handle_data(如果是分钟回测) 会在夜盘的每一分钟(如 21:01, 21:02...)都运行。
Q: 如何在策略中区分当前是夜盘还是日盘?
A: 可以通过 context.current_dt.hour 来判断。通常小时数大于 18 (即晚上6点以后) 可以认为是夜盘时段。例如:
if context.current_dt.hour > 18:
# 夜盘逻辑
pass
else:
# 日盘逻辑
pass