3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant (聚宽) 平台中,使用 run_daily(func, time='every_bar') 却发现没有每分钟运行,最根本的原因是:你的回测或模拟交易的“运行频率”设置成了“天”,而不是“分钟”。
根据 JoinQuant API 文档的说明:
time="every_bar"只能在run_daily中调用,运行时间和您设置的频率(回测页面右上方设置)一致。按天会在交易日的开盘时调用一次,按分钟会在交易时间每分钟运行。
也就是说,every_bar 里的 bar 指的是你当前策略的 K 线周期。如果你选了日线(天频率),一个 bar 就是一天,它就每天跑一次;如果你选了分钟线(分钟频率),一个 bar 就是一分钟,它才会每分钟跑一次。
步骤 1:修改回测/模拟交易频率
在聚宽策略编写页面的右上方(或者创建模拟交易的设置页面),找到**“运行频率”选项,将其从“天”修改为“分钟”**。
步骤 2:检查代码逻辑
你的代码逻辑基本是正确的,只要频率设置对了,stop_loss 函数就会每分钟被调用一次。以下是优化后的代码示例:
# 导入聚宽函数库
import jqdata
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 注册定时运行函数,time='every_bar' 依赖于全局频率设置
# 必须在界面上将频率设置为“分钟”!
run_daily(stop_loss, time='every_bar', reference_security='000300.XSHG')
# 设置止损:跌幅大于8% 止损
def stop_loss(context):
# 打印当前时间,如果是分钟频率,这里会每分钟打印一次
log.info('函数运行时间: ' + str(context.current_dt))
# 遍历可卖出的持仓股票
for stock in context.portfolio.positions:
if context.portfolio.positions[stock].closeable_amount > 0:
# 假设 g.position_dict 已经在其他地方正确维护了昨收价
# 这里为了演示,直接获取昨收价
pre_close = attribute_history(stock, 1, '1d', ['close'])['close'][0]
# 获取当前分钟的最新价格
# 注意:在分钟频率下,可以直接使用 data[stock].close 或 get_current_data()
current_data = get_current_data()
current_price = current_data[stock].last_price
# -8个点止损 (即当前价低于昨收价的 92%)
if current_price < pre_close * 0.92:
log.info("触发止损,卖出 %s, 当前价: %f, 昨收价: %f" % (stock, current_price, pre_close))
order_target(stock, 0)
handle_data除了 run_daily 配合 every_bar,你也可以直接使用 handle_data 函数。handle_data 的触发机制同样依赖于全局频率设置。只要设置为分钟频率,handle_data 就会每分钟执行一次。
def initialize(context):
set_benchmark('000300.XSHG')
set_option('use_real_price', True)
# 如果回测频率设置为“分钟”,此函数每分钟运行一次
def handle_data(context, data):
for stock in context.portfolio.positions:
if context.portfolio.positions[stock].closeable_amount > 0:
current_price = data[stock].close
pre_close = data[stock].pre_close
if current_price < pre_close * 0.92:
log.info("止损卖出 %s" % stock)
order_target(stock, 0)
every_bar 只是声明“跟随全局频率”,真正的控制开关在界面的频率下拉菜单里。get_bars 或 history),推荐使用 get_current_data() 获取最新价,以提高回测速度。run_daily 和 handle_data,选择其中一种方式实现即可。