问题描述
解决方案
在 JoinQuant(聚宽)平台中,要设置策略在每天收盘前 10 分钟(即 14:50)运行,需要在 initialize 函数中使用 run_daily API 进行定时任务注册。
实现方法
使用 run_daily(func, time='14:50') 函数。其中 func 是您自定义的需要在该时间点执行的函数名,time 参数指定具体的运行时间。
代码示例
# -*- coding: utf-8 -*-
def initialize(context):
# 设置基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 注册定时运行函数
# time='14:50' 表示在每天的 14:50:00 触发 before_market_close 函数
run_daily(before_market_close, time='14:50')
def before_market_close(context):
"""
该函数会在每天 14:50 被调用
"""
log.info("当前时间是 14:50,开始执行收盘前策略逻辑")
# 获取当前时间
current_dt = context.current_dt
# 示例:获取平安银行的最新价
current_data = get_current_data()
price = current_data['000001.XSHE'].last_price
print("平安银行当前价格: ", price)
# 在此处添加您的交易逻辑,例如检查是否需要平仓或调整仓位
# ...
关键点说明
- 函数参数:通过
run_daily调用的自定义函数(如上例中的before_market_close)只能接收一个参数context。它不像handle_data那样接收data参数。如果需要获取行情数据,请在函数内部使用get_current_data()、history()或attribute_history()等 API。 - 执行频率:
- 按天回测:
run_daily指定具体时间(如 '14:50')在按天回测中通常没有实际意义,因为按天回测每天只运行一次(通常视为收盘后结算)。如果必须在盘中特定时间触发逻辑,建议使用分钟回测。 - 按分钟回测/模拟交易:策略会在 14:50:00 准时触发该函数。
- 按天回测:
- 冲突避免:建议不要在同一个策略中混用
run_daily定时任务和handle_data,除非您非常清楚它们的执行顺序。通常推荐使用多个run_daily来替代handle_data以获得更清晰的时间控制。
Q&A
Q: run_daily 可以设置多个不同的时间点吗?
A: 可以。您可以在 initialize 中多次调用 run_daily,分别指定不同的函数和时间。例如:
run_daily(func_morning, time='10:00')
run_daily(func_afternoon, time='14:00')
Q: 如果我在 14:50 下单,是按什么价格成交?
A: 在分钟回测或模拟交易中,如果在 14:50:00 触发函数并下单:
- 市价单:通常按 14:50 这一分钟的收盘价或下一分钟的开盘价成交(取决于回测引擎的具体撮合逻辑,通常是即时撮合)。
- 限价单:会根据 14:50 及之后的行情进行撮合。
Q: run_daily 支持秒级精度吗?
A: 支持。在分钟或 Tick 级回测中,time 参数可以精确到秒,例如 time='14:50:30'。但在普通的分钟回测中,通常建议精确到分即可。