Skip to content

运行函数

注意只有在使用相同的参照标的时,定时运行函数的优先级别为: run_monthly>run_weekly>run_daily 且与函数被注册的顺序无关;handle_data 的执行顺序与前述函数无关,用户策略不应该依赖于这些计划任务执行的顺序。

每日定时执行

run_daily 每天在指定时刻执行一次自定义策略函数,支持多种时间定义方式。

python
run_daily(func,time,reference_security='sz000001')

参数详情

参数名类型必选含义与取值说明
funcfunction自定义策略函数,必须接受 context 作为唯一参数,函数内部实现具体的策略逻辑。
timestr运行时间,支持三种格式:
1. 具体时间:如 '10:00'、'01:00',在 tick 频率策略中可精确到秒(如 '10:00:05')。
2. 频率同步: 'every_bar',运行频率与策略设置的频率一致(按天则开盘时调用,按分钟则每分钟调用)。
3. 相对开盘时间: 'open'、 'open+5m'、 'open-10m',基于参考标的的开盘时间偏移。
reference_securitystr参考标的,用于确定相对开盘时间的基准,默认 'sz000001'(上证指数)。
期货策略需修改为对应主力合约(如 'dsAL8'),以适配夜盘时间。
⚠️ 注意:当 time 为具体时间时,不可设置此参数。

返回值

  • 类型:None
  • 说明:无返回值,仅用于注册定时执行的回调函数。

完整示例

python
def initialize(context):
    context.symbol = '000001'  # 初始化持仓标的为平安银行
    # 示例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_target_percent(context.symbol, 1.0)
    print(oid)  # 输出:ZLT-0000000-000001

def trade_after_open(context):
    # 具体策略逻辑:开盘后5分钟调仓,卖出持仓标的至空仓
    oid = order_target_percent(context.symbol, 0)
    print(oid)  # 输出:ZLT-0000001-000001

def trade_every_minute(context):
    # 具体策略逻辑:每分钟检查标的最新价并打印
    last_price = get_latest_price(context.symbol)[0]
    print(f"标的{context.symbol}最新价格:{last_price}")  # 输出:标的000001最新价格:15.25

每周定时执行

run_weekly 每周在指定的第 N 个交易日的指定时刻,执行一次自定义策略函数。

python
run_weekly(func,time,weekday,reference_security='sz000001',force=True)

参数详情

参数名类型必选含义与取值说明
funcfunction自定义策略函数,必须接受 context 作为唯一参数
timestr运行时间,格式与 run_daily 完全一致。
weekdayint每周的第几个交易日(仅正整数),例如 1 代表每周第一个交易日。
reference_securitystr参考标的,默认 'sz000001',期货策略需修改为对应主力合约。
⚠️ 注意:当 time 为具体时间时,不可设置此参数。
forcebool当 weekday 超出本周实际交易日数量时的处理方式:
- True(默认):就近取最近的交易日执行。
- False:不执行,等待下一周。
建议设置为 False 以避免逻辑混乱。

返回值

  • 类型:None
  • 说明:无返回值,仅用于注册定时执行的回调函数。

完整示例

python
def initialize(context):
    # 示例:每周第一个交易日的 09:30 执行(force=False,超出交易日则不执行)
    run_weekly(weekly_rebalance, time='09:30', weekday=1, force=False)
    context.stock_pool = ['000001', '600036', '000858']  # 周度调仓股票池

def weekly_rebalance(context):
    # 具体策略逻辑:每周等权调仓股票池标的
    oid_list = []
    for stock in context.stock_pool:
        oid = order_target_percent(stock, 1/len(context.stock_pool))
        oid_list.append(oid)
    print(oid_list)  # 输出:['ZLT-0000002-000001', 'ZLT-0000003-600036', 'ZLT-0000004-000858']

每月定时执行

run_monthly 每月在指定的第 N 个交易日的指定时刻,执行一次自定义策略函数,默认时间为 09:30。

python
run_monthly(func, time='09:30', monthday, reference_security='sz000001', force=True)

参数详情

参数名类型必选含义与取值说明
funcfunction自定义策略函数,必须接受 context 作为唯一参数
timestr运行时间,格式与 run_daily 完全一致,默认值为 '09:30'。
monthdayint每月的第几个交易日(仅正整数),例如 1 代表每月第一个交易日。
reference_securitystr参考标的,默认 'sz000001',期货策略需修改为对应主力合约。
⚠️ 注意:当 time 为具体时间时,不可设置此参数。
forcebool当 monthday 超出本月实际交易日数量时的处理方式:
- True(默认):就近取最近的交易日执行。
- False:不执行,等待下一月。
建议设置为 False 以避免逻辑混乱。

返回值

  • 类型:None
  • 说明:无返回值,仅用于注册定时执行的回调函数。

完整示例

python
def initialize(context):
    # 示例:每月第五个交易日的 14:00 执行(force=False,超出交易日则不执行)
    run_monthly(monthly_rebalance, time='14:00', monthday=5, force=False)
    context.monthly_stock = '600519'  # 月度调仓标的

def monthly_rebalance(context):
    # 具体策略逻辑:每月调仓买入标的至30%仓位
    oid = order_target_percent(context.monthly_stock, 0.3)
    print(f"月度调仓订单ID:{oid}")  # 输出:月度调仓订单ID:ZLT-0000005-600519

频率触发函数

handle_data

python
handle_data(context,data)

该函数会根据策略执行时选择的频率触发,其触发时间依据股票的交易时间。

触发规则

  • min(分钟级):每分钟触发一次,触发周期为 09:30~15:00
  • day(日线级):每天 09:30 触发一次

参数详情

参数名类型含义与说明
context全局上下文对象策略运行的全局上下文,包含账户信息、持仓信息、策略参数等核心运行数据,在策略生命周期内唯一且共享。
datadict(字典)键为标的代码(如 'sh000300'),值为对应标的的 Bar 对象。
该对象存储了前一个单位时间的数据:
- 按天回测时,为前一天的 OHLCV(开盘、最高、最低、收盘、成交量)等数据
- 按分钟回测时,为前一分钟的 OHLCV 等数据

返回

  • 返回值:None
  • 说明:该函数无返回值,仅用于执行策略逻辑

完整示例

python
def initialize(context): 
    # 设置沪深300指数为业绩基准
    set_benchmark('sh000300')
    context.target_stock = '000001'  # 关注平安银行

def handle_data(context, data): 
    # 获取当前持仓信息
    positions = context.portfolio.positions
    # 示例:如果持仓为空,则买入平安银行至50%仓位
    if not positions and context.target_stock in data:
        oid = order_target_percent(context.target_stock, 0.5)
        print(f"开仓订单ID:{oid},开仓标的:{context.target_stock}")  # 输出:开仓订单ID:ZLT-0000006-000001,开仓标的:000001
    # 打印标的前一分钟收盘价
    if context.target_stock in data:
        last_close = data[context.target_stock].close
        print(f"前一分钟收盘价:{last_close}")  # 输出:前一分钟收盘价:15.30

运行函数

Tick触发函数

handle_tick-根据tick频率触发运行的函数

函数

python
def handle_tick(context, tick):
    # 编写事件
    pass

说明

handle_tick(context, tick) 用于 tick 级别事件驱动。

  • 订阅触发(subscribe 订阅标的)
    • 当策略在 initialize() 中通过 subscribe() 订阅的标的产生 tick 数据时,系统会调用一次 handle_tick。
    • 若没有 tick 事件(如停牌/无成交/数据源无 tick),则不会调用。
  • 无订阅 3s 定时器触发(原文需修正)
    • 回测模式下,不订阅任何数据时 不会触发 handle_tick(仅触发 on_strategy_end)。
    • “不同运行模式行为可能不同,以实际环境为准”。

参数

参数类型说明
contextContext全局上下文对象,常用字段:context.current_dt、context.previous_date 等。
tickTickTick 对象,存放触发 handle_tick 的 tick 数据(字段以实际 Tick 对象为准)。

返回

  • None

  • subscribe() 不支持 count 关键字参数,否则会报错: TypeError("subscribe() got an unexpected keyword argument 'count'") 文档示例中请勿使用 count=。

示例

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)
    print("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。 (注:期货因为有夜盘,开盘时间点不定,若有开盘任务请使用定时任务触发。)

python
def before_trading_start(context):
    # 编写开盘前要做的逻辑
    print("before_trading_start:", context.current_dt, "previous_date:", context.previous_date)

def initialize(context):
    pass

# 输出示例
# before_trading_start: 2025-01-02 09:00:00 previous_date: 2025-01-01

收盘后运行

after_trading_end

每日收盘后运行,该函数参考股票交易时段,启动时间为 15:30。 (注:期货因为有夜盘,收盘时间点不定,若有收盘任务请使用定时任务触发。)

python
def after_trading_end(context):
    print("after_trading_end:", context.current_dt, "previous_date:", context.previous_date)

def initialize(context):
    pass

# 输出示例
# after_trading_end: 2025-01-02 15:00:00 previous_date: 2025-01-01

策略结束执行

on_strategy_end

python
def on_strategy_end(context):
    print("on_strategy_end")

# 输出示例
# on_strategy_end

文档版本: 1.0.0 | 发布于 2025-01-29