Appearance
运行函数
注意只有在使用相同的参照标的时,定时运行函数的优先级别为: run_monthly>run_weekly>run_daily 且与函数被注册的顺序无关;handle_data 的执行顺序与前述函数无关,用户策略不应该依赖于这些计划任务执行的顺序。
每日定时执行
run_daily-每日定时执行
每天在指定时刻执行一次自定义策略函数,支持多种时间定义方式。
python
run_daily(func,time,reference_security='sz000001')参数详情
| 参数名 | 类型 | 必选 | 含义与取值说明 |
|---|---|---|---|
| func | function | 是 | 自定义策略函数,必须接受 context 作为唯一参数,函数内部实现具体的策略逻辑。 |
| time | str | 是 | 运行时间,支持三种格式: 1. 具体时间:如 '10:00'、'01:00',在 tick 频率策略中可精确到秒(如 '10:00:05')。 2. 频率同步: 'every_bar',运行频率与策略设置的频率一致(按天则开盘时调用,按分钟则每分钟调用)。 3. 相对开盘时间: 'open'、 'open+5m'、 'open-10m',基于参考标的的开盘时间偏移。 |
| reference_security | str | 否 | 参考标的,用于确定相对开盘时间的基准,默认 'sz000001'(上证指数)。 期货策略需修改为对应主力合约(如 'dsAL8'),以适配夜盘时间。 ⚠️ 当 time 为具体时间时,不可设置此参数。 |
返回值
- 类型:None
- 说明:无返回值,仅用于注册定时执行的回调函数。
完整示例
python
from zltquant import *
def initialize(context):
g.security = 'sz000001' # 初始化持仓标的为平安银行
# 示例1:每天 09:30 固定时间执行
run_daily(trade_at_fixed_time, time='09:30')
# 示例2:每天开盘后 5 分钟执行(基于 sz000001 的 09:30 开盘,实际为 09:35)
run_daily(trade_after_open, time='open+5m', reference_security='sz000001')
# 示例3:与策略频率同步执行(若策略为分钟频率,则每分钟运行一次)
run_daily(trade_every_minute, time='every_bar')
def trade_at_fixed_time(context):
# 具体策略逻辑:开盘买入持仓标的至满仓
oid = order(g.security, 100)
log.info(oid) # 输出:ZLT-0000000-000001
def trade_after_open(context):
# 具体策略逻辑:开盘后5分钟调仓,卖出持仓标的至空仓
oid = order(g.security, 0)
log.info(oid) # 输出:ZLT-0000001-000001
def trade_every_minute(context):
# 具体策略逻辑:每分钟检查标的最新价并打印
last_price = get_current_data()[g.security].last_price
log.info(f"标的{g.security}最新价格:{last_price}") # 输出:标的000001最新价格:15.25
if __name__ == '__main__':
run_main()每周定时执行
run_weekly-每周定时执行
每周在指定的第 N 个交易日的指定时刻,执行一次自定义策略函数。
python
run_weekly(func, monthday, time='09:30', reference_security=None, force=False)参数详情
| 参数名 | 类型 | 必选 | 含义与取值说明 |
|---|---|---|---|
| func | function | 是 | 自定义策略函数,必须接受 context 作为唯一参数。 |
| time | str | 是 | 运行时间,格式与 run_daily 完全一致。 |
| weekday | int | 是 | 每周的第几个交易日(仅正整数),例如 1 代表每周第一个交易日。 |
| reference_security | str | 否 | 参考标的,默认 'sz000001',期货策略需修改为对应主力合约。 ⚠️ 当 time 为具体时间时,不可设置此参数。 |
| force | bool | 否 | 当 weekday 超出本周实际交易日数量时的处理方式: - True(默认):就近取最近的交易日执行。 - False:不执行,等待下一周。 建议设置为 False 以避免逻辑混乱。 |
返回值
- 类型:None
- 说明:无返回值,仅用于注册定时执行的回调函数。
完整示例
python
from zltquant import *
def initialize(context):
# 示例:每周第一个交易日的 09:30 执行(force=False,超出交易日则不执行)
run_weekly(weekly_rebalance, monthday=1, time='09:30', force=False)
g.security = ['sz000001', 'sh600036', 'sz000858'] # 周度调仓股票池
def weekly_rebalance(context):
# 具体策略逻辑:每周等权调仓股票池标的
oid_list = []
for stock in g.security:
oid = order_target_value(stock, context.portfolio.total_value / len(g.security))
oid_list.append(oid)
log.info(oid_list) # 输出:['ZLT-0000002-000001', 'ZLT-0000003-600036', 'ZLT-0000004-000858']
if __name__ == '__main__':
run_main()每月定时执行
run_monthly-每月定时执行
每月在指定的第 N 个交易日的指定时刻,执行一次自定义策略函数,默认时间为 09:30。
python
run_monthly(func, monthday, time='09:30', reference_security=None, force=False)参数详情
| 参数名 | 类型 | 必选 | 含义与取值说明 |
|---|---|---|---|
| func | function | 是 | 自定义策略函数,必须接受 context 作为唯一参数。 |
| time | str | 否 | 运行时间,格式与 run_daily 完全一致,默认值为 '09:30'。 |
| monthday | int | 是 | 每月的第几个交易日(仅正整数),例如 1 代表每月第一个交易日。 |
| reference_security | str | 否 | 参考标的,默认 'sz000001',期货策略需修改为对应主力合约。 ⚠️ 当 time 为具体时间时,不可设置此参数。 |
| force | bool | 否 | 当 monthday 超出本月实际交易日数量时的处理方式: - True(默认):就近取最近的交易日执行。 - False:不执行,等待下一月。 建议设置为 False 以避免逻辑混乱。 |
返回值
- 类型:None
- 说明:无返回值,仅用于注册定时执行的回调函数。
完整示例
python
from zltquant import *
def initialize(context):
# 示例:每月第五个交易日的 14:00 执行(force=False,超出交易日则不执行)
run_monthly(monthly_rebalance, time='14:00', monthday=5, force=False)
g.security = 'sh600519' # 月度调仓标的
def monthly_rebalance(context):
# 具体策略逻辑:每月调仓买入标的至30%仓位
oid = order_target_value(g.security, context.portfolio.total_value * 0.3)
log.info(f"月度调仓订单ID:{oid}") # 输出:月度调仓订单ID:ZLT-0000005-600519
if __name__ == '__main__':
run_main()频率触发函数
handle_data-频率触发函数
python
handle_data(context,data)该函数会根据策略执行时选择的频率触发,其触发时间依据股票的交易时间。
触发规则
- min(分钟级):每分钟触发一次,触发周期为 09:30~15:00
- day(日线级):每天 09:30 触发一次
参数详情
| 参数名 | 类型 | 含义与说明 |
|---|---|---|
| context | 全局上下文对象 | 策略运行的全局上下文,包含账号信息、持仓信息、策略参数等核心运行数据,在策略生命周期内唯一且共享。 |
| data | dict(字典) | 键为标的代码(如 'sz399300'),值为对应标的的 Bar 对象。 🔴 data 是空字典,不能通过 security in data 判断标的是否有数据,必须通过 data[security] 直接访问- 按天回测时,为前一天的 Bar对象 - 按分钟回测时,为前一分钟的 Bar对象 |
返回
- 返回值:None
- 说明:该函数无返回值,仅用于执行策略逻辑
完整示例
python
from zltquant import *
def initialize(context):
# 设置沪深300指数为业绩基准
set_benchmark('sz399300')
g.security = 'sz000001' # 关注平安银行
def handle_data(context, data):
# 获取当前持仓信息
positions = context.portfolio.positions
# 示例:如果持仓为空,则买入平安银行至50%仓位
if not positions:
oid = order_target_value(g.security, context.portfolio.total_value * 0.5)
log.info(f"开仓订单ID:{oid},开仓标的:{g.security}") # 输出:开仓订单ID:ZLT-0000006-000001,开仓标的:000001
# 打印标的前一分钟收盘价
last_close = data[g.security].close
log.info(f"前一分钟收盘价:{last_close}") # 输出:前一分钟收盘价:15.30
if __name__ == '__main__':
run_main()Tick触发函数
handle_tick-Tick触发函数
函数
python
from zltquant import *
def handle_tick(context, tick):
# 编写事件
pass
if __name__ == '__main__':
run_main()说明
handle_tick(context, tick) 用于 tick 级别事件驱动。
仿真模式订阅触发(subscribe 订阅标的)
- 在 initialize() 中通过 subscribe() 订阅的标的产生 tick 数据时,系统会调用一次 handle_tick。
- 若没有 tick 事件(如停牌/无成交/数据源无 tick),则不会调用。
回测模式无订阅 3s 定时器触发
- 在回测模式下,3s 固定触发 handle_tick。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| context | Context | 全局上下文对象,常用字段:context.current_dt、context.previous_date 等。 |
| tick | Tick | Tick 对象,存放触发 handle_tick 的 tick 数据(字段以实际 Tick 对象为准)。 |
返回
- None
示例
python
def initialize(context):
# 注意:subscribe 不支持 count 参数
subscribe("sz000001", frequency="tick")
def handle_tick(context, tick):
sec = getattr(tick, "security", None)
tick_dt = getattr(tick, "datetime", None)
price = getattr(tick, "current", None)
log.info("ctx_dt=", context.current_dt, "sec=", sec, "tick_dt=", tick_dt, "price=", price)
# ctx_dt= 2025-01-02 09:30:00 sec= sz000001 tick_dt= 2025-01-02 09:30:00 price= 10.38开盘前运行
before_trading_start-开盘前运行
每日开盘前运行,该函数参考股票交易时段,启动时间为 09:00。 (注:期货因为有夜盘,开盘时间点不定,若有开盘任务请使用定时任务触发。)
⚡ 重要用法
- 触发时机:每个交易日开盘前(09:00)自动触发,无需手动注册
- 典型用途:选股准备、数据预处理、订阅标的、计算当日指标等
- 执行次数:每个交易日执行一次
⚠️ 必须准确定义函数名和参数:只有严格按照 def before_trading_start(context): 定义,系统才会在开盘前自动调用。函数名或参数不匹配将不会触发。
函数
python
def before_trading_start(context):
# 编写开盘前要做的逻辑
log.info("before_trading_start:", context.current_dt, "previous_date:", context.previous_date)
# 输出示例
# before_trading_start: 2025-01-02 09:00:00 previous_date: 2025-01-01收盘后运行
after_trading_end-收盘后运行
每日收盘后运行,该函数参考股票交易时段,启动时间为 15:30。 (注:期货因为有夜盘,收盘时间点不定,若有收盘任务请使用定时任务触发。)
⚡ 重要用法
- 触发时机:每个交易日收盘后(15:30)自动触发,无需手动注册
- 典型用途:盘后统计、记录持仓、发送通知、清理临时数据等
- 执行次数:每个交易日执行一次
⚠️ 必须准确定义函数名和参数:只有严格按照 def after_trading_end(context): 定义,系统才会在收盘后自动调用。函数名或参数不匹配将不会触发。
函数
python
def after_trading_end(context):
log.info("after_trading_end:", context.current_dt, "previous_date:", context.previous_date)
# 输出示例
# after_trading_end: 2025-01-02 15:00:00 previous_date: 2025-01-01策略结束执行
on_strategy_end-策略结束执行
策略运行结束时触发(回测结束或实盘/仿真停止时)。
⚡ 重要用法
- 触发时机:策略运行结束时自动触发,无需手动注册
- 典型用途:回测总结、输出统计报告、保存结果到文件、清理资源等
- 执行次数:整个策略生命周期仅执行一次
⚠️ 必须准确定义函数名和参数:只有严格按照 def on_strategy_end(context): 定义,系统才会在策略结束时自动调用。函数名或参数不匹配将不会触发。
函数
python
def on_strategy_end(context):
log.info("on_strategy_end")
# 输出示例
# on_strategy_end