外观
策略生命周期
只实现策略需要的回调。策略日志通过 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):
passrun_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必须且只能提供一个:
| 参数 | 类型 / 默认 | 说明 |
|---|---|---|
weekday | int | None,默认None | 1~7对应周一到周日,假日不顺延 |
tradingday | int | 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字段见成交对象。事件用于观察实际成交;交易决策仍放在允许下单的策略回调,不在成交通知里递归下单。