跳转到正文

策略生命周期 ​

只实现策略需要的回调。策略日志通过 from localquant.apis import logger 导入,在回调内使用。运行入口见运行与配置,行情查询的时间边界见行情 API。

回调与权限 ​

回调签名用途与下单权限
init(context)运行开始时一次,初始化参数、订阅和自有数据;不能下单或调用 history_bars
before_trading(context)每日盘前;不能下单
open_auction(context, bar_dict)每日竞价,可下单;行情对象提供开盘价及涨跌停价,无当日 close/high/low
handle_bar(context, bar_dict)日线每天一次、分钟每根 bar 一次,可下单;可读取该 bar 的完整 OHLCV
after_trading(context)每日盘后,用于统计和策略状态记录;不能下单

股票基金日线顺序为盘前 → 竞价 → 收盘 BAR → 盘后,时间依次为 00:00、00:00、15:00、15:30。其分钟回测盘前为 09:01、竞价为 09:28,BAR 时间见分钟事件网格。这些是回测事件时间,不是实际委托发送时间。

期货日线的 BAR 在 15:15,连续系列只允许在 handle_bar 下单。期货分钟没有 open_auction,盘前及 BAR 按实际分钟数据产生,夜盘使用独立的交易日,见期货时间与回调。

每日结算发生在下一交易日盘前之前,最后一日于回测结束前结算;结果的每日账户记录在结算后生成。因此 after_trading 读到的账户可能尚未包含当日结算费用。

回调开始前,已有持仓在竞价按有效开盘价估值,在 BAR 按当前 bar 收盘价估值;缺少有效报价时保留此前估值。策略直接使用 portfolio.total_value、position.market_value,无需手工重估。

scheduler ​

从 localquant.api 导入 scheduler 与时间规则函数;模块在运行启动时注册,在init内部导入即可。任务只在init注册,均返回None;回调为 func(context, bar_dict)。

python
def init(context):
    from localquant.api import scheduler, physical_time
    scheduler.run_daily(rebalance, time_rule=physical_time(14, 50))

def rebalance(context, bar_dict):
    pass

run_daily ​

python
scheduler.run_daily(func, time_rule=None)

func是接收两个参数的函数;time_rule是时间规则整数、字符串 "before_trading" 或None。None采用09:31规则,每交易日一次。

run_weekly ​

python
scheduler.run_weekly(func, weekday=None, tradingday=None, time_rule=None)

func、time_rule同run_daily。weekday与tradingday必须且只能提供一个:

参数类型 / 默认说明
weekdayint | None,默认None1~7对应周一到周日,假日不顺延
tradingdayint | None,默认None周内第n个交易日,1~5;-1~-5倒数,0无效

run_monthly ​

python
scheduler.run_monthly(func, tradingday=None, time_rule=None)

func、time_rule同run_daily。tradingday虽然默认None,但调用时必须提供正或负整数:1~23为月内第n个交易日,-1~-23为倒数,0无效;所选序号不存在则不触发。

时间规则 ​

以下函数返回整数时间规则,传给time_rule:

函数参数类型与默认含义
physical_time(hour=0, minute=0)hour/minute为int,24小时制指定钟表时间,如physical_time(14, 50)
market_open(hour=0, minute=0)hour/minute为int,偏移量股票日盘09:31基准后移,按股票午休折算
market_close(hour=0, minute=0)hour/minute为int,偏移量股票日盘15:00基准前移,按股票午休折算

分钟回测在规则时间被bar时间跨过时触发,不会自行生成缺失行情。日频下有效交易时段的时间规则退化为当日BAR执行,不产生14:50等盘中成交事件。time_rule="before_trading"在用户before_trading前触发,bar_dict=None,不能下单。

默认模块顺序下,BAR先撮合已有订单,再执行定时任务,最后进入handle_bar;同阶段任务按注册顺序执行。定时任务不能拦截已经发生的存量订单撮合。

交易日序号根据已加载日历计算。按周/月交易日调度时,加载范围须覆盖涉及的完整周/月,正式回测可更短;期货自动多载前后一天不足以保证这一条件。月中截断加载时,tradingday=-1可能把加载终点误当月末。无法加载完整周期时,使用事先准备的完整交易日历明确调仓日期。

这些时间规则面向股票基金日盘。真实月合约日频定时任务也不能改变日线成交模型;期货分钟,尤其夜盘与系列策略,应在handle_bar中按context.now和context.trading_date判断时点。系列不能在scheduler下单。

成交事件 ​

python
subscribe_event(event_type, handler)

从 localquant.apis 导入,返回None,仅在init注册。event_type为 EVENT 枚举,实际成交使用EVENT.TRADE;handler是两个参数的Python函数 handler(context, event)。事件对象不是字典,使用属性访问。

python
from localquant.apis import EVENT, subscribe_event

def init(context):
    context.filled = []
    subscribe_event(EVENT.TRADE, on_trade)

def on_trade(context, event):
    trade = event.trade
    context.filled.append((trade.datetime, trade.order_book_id, trade.last_quantity))

成交事件可来自普通策略订单、分红再投资、期货移仓或到期清仓,event.order可能为None。Trade字段见成交对象。事件用于观察实际成交;交易决策仍放在允许下单的策略回调,不在成交通知里递归下单。

localquant documentation