问题描述
解决方案
在 JoinQuant(聚宽)平台中,若要在每天收盘前 10 分钟(即 14:50)执行交易逻辑,最标准且推荐的方法是在 initialize 函数中使用 run_daily API 进行定时任务注册。
实现方法
- 计算时间:A股收盘时间为 15:00,收盘前 10 分钟即为 14:50。
- 调用函数:使用
run_daily(func, time='14:50')。 - 定义逻辑:编写一个自定义函数(例如
close_market_trading),在其中写入具体的交易代码。
代码示例
以下是一个完整的策略代码框架:
# -*- coding: utf-8 -*-
import jqdata
def initialize(context):
"""
初始化函数,设定基准、全局变量及定时运行函数
"""
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 设定要操作的股票,例如平安银行
g.security = '000001.XSHE'
# 【核心代码】设置在每天 14:50 (收盘前10分钟) 运行 close_market_trading 函数
run_daily(close_market_trading, time='14:50')
def close_market_trading(context):
"""
收盘前10分钟执行的交易逻辑
"""
log.info("当前时间为 14:50,开始执行收盘前交易策略")
# 获取当前时间
current_date = context.current_dt.date()
# 示例交易逻辑:全仓买入 g.security
# 获取当前现金
cash = context.portfolio.available_cash
# 如果有现金,则买入
if cash > 0:
order_value(g.security, cash)
log.info(f"在 {current_date} 14:50 买入 {g.security}")
def handle_data(context, data):
"""
盘中运行函数(可选)
如果您的策略只需要在14:50运行,此函数可以留空或删除
"""
pass
注意事项
- 时间格式:
time参数必须是字符串格式,例如'14:50'。 - 执行频率:
run_daily注册的函数每天只会执行一次。 - 与 handle_data 的区别:虽然可以在
handle_data中通过判断context.current_dt来实现同样的功能,但使用run_daily效率更高,且代码结构更清晰,是官方推荐的做法。 - 回测频率:此设置在“按天回测”和“按分钟回测”中均有效。如果是按天回测,该函数会在当天的 bar 数据合成之前运行(即你可以认为是在收盘前一瞬间运行,但在按天回测中无法精确到分钟级的盘口撮合,通常用于以收盘价成交的逻辑)。
Q&A
Q: 如果我想在收盘前 3 分钟执行,应该怎么设置?
A: 将 run_daily 中的 time 参数设置为 '14:57' 即可。
Q: run_daily 可以设置多个不同的时间点吗?
A: 可以。你可以在 initialize 中多次调用 run_daily,分别指定不同的函数和不同的时间。例如:run_daily(func1, time='10:00') 和 run_daily(func2, time='14:50')。
Q: 在按天回测模式下,time='14:50' 会生效吗?
A: 会生效。在按天回测中,run_daily 指定的具体时间(如 14:50)会被视为当天的交易逻辑触发点。但在按天回测中,无法获取分钟级别的盘中价格波动,通常成交价会默认为收盘价(取决于具体的撮合设置)。如果对盘中价格敏感,建议使用分钟级回测。