问题描述
解决方案
在 PTrade 策略系统中,run_daily 函数用于设置按日周期性运行的定时任务。time 参数用于指定具体的触发时间。
以下是关于 time 参数设置的详细说明及注意事项:
run_daily 函数 time 参数设置详解
1. 参数格式
time 参数必须是一个字符串(String),格式为 'HH:MM'(24小时制)。
- 例如:
'09:30','14:50','10:00'。
2. 不同运行模式下的限制
根据策略运行环境(回测或实盘)以及回测频率(日线或分钟线),time 参数的生效规则有所不同:
A. 股票回测 - 分钟级别 (Minute Level)
- 有效范围:
'09:31'~'11:30'和'13:00'~'15:00'。 - 说明:在分钟回测中,定时任务只能在交易时段内触发。
- 注意:如果你设置的时间不在这个范围内(例如
'09:00'),在分钟回测中该函数可能不会被触发。
B. 股票回测 - 日线级别 (Daily Level)
- 生效时间:固定为 15:00。
- 说明:当回测频率选择为“日线”时,无论
time参数设置为何值(例如设置'10:00'或'14:00'),系统都会忽略该设置,统一在每个交易日的收盘时(15:00)执行该函数。
C. 实盘交易 (Live Trading)
- 有效范围:
'00:00'~'23:59'。 - 说明:实盘环境中,时间设置非常灵活,不受交易时间限制。
- 常见用途:
- 盘前:设置
'09:10'或'09:25'进行盘前选股或数据准备。 - 盘中:设置
'10:00'进行定时风控检查。 - 尾盘:设置
'14:50'进行尾盘撮合或调仓。
- 盘前:设置
3. 代码示例
以下代码展示了如何在 initialize 中设置多个不同时间的定时任务:
def initialize(context):
# 设置股票池
g.security = '600570.SS'
set_universe(g.security)
# 示例 1:盘中定时任务 (适用于分钟回测和实盘)
# 每天上午 10:30 执行 check_risk 函数
run_daily(context, check_risk, time='10:30')
# 示例 2:尾盘选股/交易 (适用于分钟回测和实盘)
# 每天下午 14:50 执行 trade_logic 函数
run_daily(context, trade_logic, time='14:50')
# 示例 3:盘前处理 (仅适用于实盘交易)
# 每天早上 09:10 执行 pre_market_check 函数
# 注意:在分钟回测中,此时间点不会触发
run_daily(context, pre_market_check, time='09:10')
def check_risk(context):
log.info("执行风控检查")
def trade_logic(context):
log.info("执行尾盘交易逻辑")
# 示例:买入股票
order(g.security, 100)
def pre_market_check(context):
log.info("执行盘前数据准备")
Q&A 常见问题解答
Q1: run_daily 函数可以在 handle_data 中调用吗?
A: 不可以。run_daily 只能在 initialize 初始化函数中调用。如果在 handle_data 中调用,会导致重复注册任务,引发逻辑错误或内存溢出。
Q2: 如果我在日线回测中设置 time='09:30',它会在开盘时买入吗?
A: 不会。在日线级别回测中,run_daily 的 time 参数会被忽略,所有 run_daily 注册的函数都会在 15:00(收盘后)执行。如果需要开盘买入,请使用分钟级别回测,或者在 handle_data 中编写逻辑(日线回测的 handle_data 也是在 15:00 执行,但基于当日数据)。
Q3: 实盘交易中,如果服务器重启了,run_daily 还会执行吗?
A: 会。只要策略重新启动并执行了 initialize,run_daily 就会重新注册。如果重启时间错过了设定的 time,当天的任务将不会补做;如果重启时间在设定 time 之前,则会正常触发。
Q4: 可以设置多个 run_daily 吗?
A: 可以。你可以多次调用 run_daily 来注册不同的函数在不同的时间点执行,它们互不冲突。
Q5: time 参数支持秒吗?比如 '14:50:30'?
A: 不支持。run_daily 的精度为分钟,格式严格为 'HH:MM'。如果需要秒级定时任务(例如每隔几秒执行一次),请在实盘交易中使用 run_interval 函数。