问题描述
解决方案
在聚宽(JoinQuant)平台中,要实现策略只在每周一的开盘时间运行,最直接且推荐的方法是使用 run_weekly 定时运行函数。
您需要在 initialize 函数中调用 run_weekly,并将 weekday 参数设置为 1(代表周一),time 参数设置为 '09:30'(代表开盘时间)。
以下是具体的代码实现示例:
# -*- coding: utf-8 -*-
import jqdata
def initialize(context):
"""
初始化函数,设定基准、复权模式及定时任务
"""
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 设定日志级别
log.set_level('order', 'error')
# 【核心代码】设置每周一开盘运行
# func: 要运行的函数名
# weekday: 1 代表周一 (1-5分别代表周一至周五)
# time: '09:30' 代表开盘时间 (也可以使用 'open')
run_weekly(weekly_trading_logic, weekday=1, time='09:30')
def weekly_trading_logic(context):
"""
每周一开盘时执行的交易逻辑
"""
log.info("当前时间: %s,正在执行周一开盘策略..." % context.current_dt)
# 获取当前日期是周几(为了验证)
# isoweekday(): 1=周一, 7=周日
weekday = context.current_dt.isoweekday()
if weekday == 1:
log.info("确认今天是周一,开始执行选股和交易...")
# --- 在此处编写您的选股和交易逻辑 ---
# 示例:获取平安银行的当前价格
current_price = get_current_data()['000001.XSHE'].last_price
log.info("平安银行当前价格: %s" % current_price)
else:
# 注意:如果周一休市,run_weekly 可能会顺延到该周的第一个交易日(如周二)
# 如果您严格要求只在“日历上的周一”运行,可以在这里做个判断直接 return
log.info("今天是周%s,非周一,跳过执行(因周一可能休市顺延导致)。" % weekday)
def handle_data(context, data):
"""
按分钟或按天回测时每单位时间调用
如果全权使用 run_weekly,此函数可以留空
"""
pass
代码及参数详解
-
run_weekly(func, weekday, time, ...):func: 您自定义的交易函数名称(如上例中的weekly_trading_logic),该函数必须接受context作为参数。weekday=1: 指定每周的第几个交易日。1表示周一。time='09:30': 指定运行的具体时间。'09:30'是A股的开盘时间。您也可以使用'open',效果相同。
-
关于节假日顺延的说明:
- 如果某一周的周一恰逢法定节假日(休市),聚宽的
run_weekly机制通常会寻找该周内最近的一个交易日来执行(例如周二)。 - 如果您严格希望只在“日历上的星期一”运行(即如果周一休市,这周就不交易了),建议在自定义函数内部增加
if context.current_dt.isoweekday() == 1:的判断,如上述代码示例所示。
- 如果某一周的周一恰逢法定节假日(休市),聚宽的
Q&A
Q: 如果我设置 time='open' 和 time='09:30' 有什么区别?
A: 对于股票策略,两者通常效果一致,都是在 09:30:00 触发。但如果您交易的是期货,'open' 会自动适配不同品种的开盘时间(部分期货有夜盘或不同的开盘时间),而 '09:30' 则是强制在 09:30 执行。对于股票策略,建议使用 '09:30' 以避免歧义。
Q: run_weekly 和 handle_data 可以同时使用吗?
A: 可以。run_weekly 用于处理定时的低频逻辑(如周选股),handle_data 用于处理每一分钟或每一天的实时逻辑(如止损监控)。但请注意不要在两个函数中对同一只股票发出冲突的指令。
Q: 如果我想在周一收盘前运行怎么办?
A: 可以将 time 参数修改为 '14:50' 或 '14:55',例如 run_weekly(func, weekday=1, time='14:50')。