策略生命周期与回调函数
本文讲解期魔方期货策略的完整生命周期、每个回调函数的触发时机与参数、以及启动阶段的执行顺序。
策略生命周期
一个期货策略从启动到停止,会依次经历以下阶段:
on_init
↓
on_auth (可选)
↓
on_tick ──→ on_bar_run(on_bar) (行情流)
↓
on_order ──→ on_trade (报单/成交)
↓
on_error (如有) / on_stop
回调速查表
| 回调函数 | 触发时机 | 传入参数 | 是否必写 |
|---|---|---|---|
on_init(context) |
策略启动时调用一次 | context | ✅ 必写 |
on_tick(context) |
每次行情推送时调用 | context | ✅ 必写 |
on_bar(context) |
每根 K 线收盘时调用 | context | 推荐 |
on_order(context, order) |
每次接收到报单状态时 | context, order | 可选 |
on_allorder(context, ...) |
报单回复时调用 | ... | 可选 |
on_trade(context, trade) |
每次接收到成交时 | context, trade | 可选 |
on_error(context, err) |
策略出错时调用 | context, err | 可选 |
on_stop(context) |
策略停止前调用 | context | 可选 |
启动阶段细节
- 平台加载策略编译文件,构造策略实例
- 执行
on_init:此时可以初始化全局变量、加载模型 / 因子、订阅数据 - 如果有
on_auth,验证用户是否有权限运行 - 开始接收行情流,进入主循环:
on_tick→on_bar(收 K 线时)
Bar 与 Tick
on_tick:频率高(每秒多次甚至数十次),适合做快速信号、超短线策略on_bar:频率取决于 K 线周期(日线一天一次、分钟线一小时几十次),适合中长线、信号不敏感的策略
下单、订单和成交
def on_tick(context):
# 在 tick 里触发信号
if signal:
buy_open(1, 'rb2510') # 快捷报单
def on_order(context, order):
# order 是报单的当前状态(未成交/部分成交)
pass
def on_trade(context, trade):
# trade 是最终成交的记录
pass
各回调详解
on_init(context) — 策略启动
触发时机:策略启动时调用一次。
典型用途:
- 初始化全局变量(
context.xxx = ...) - 解析订阅合约参数
- 初始状态准备
def on_init(context):
context.holdings = {} # 记录每个品种的持仓
on_tick(context) — 每次行情推送
触发时机:期货合约每次有新的报价进来时调用。
典型用途:
- 高频信号判断
- 调用
on_bar_run(on_bar, context)实现 K 线收线逻辑 - 盘口数据处理
def on_tick(context):
# 大多数策略都用这个模式:tick 驱动 bar 逻辑
on_bar_run(on_bar, context)
on_bar(context) — 每根 K 线收盘
触发时机:每根 K 线收线时(由 on_tick 中的 on_bar_run 触发)。
典型用途:信号生成、调仓、K 线级别指标计算。
def on_bar(context):
klines = get_kline('rb2510', 'D1', 600)
# 计算信号、调仓等
on_bar_run(func, arg) — 注册 K 线处理回调
说明:用来注册 K 线处理回调函数,此回调函数只在每根 K 线收线时运行一次。
触发时机:在 on_tick 中调用;每当 K 线收线时,平台会自动触发其注册的回调函数。
输入参数:
| 参数 | 参数名称 | 参数类型 | 是否必填 | 描述 |
|---|---|---|---|---|
| func | K 线数据处理回调函数 | 函数 | 是 | 通常传入 on_bar |
| arg | func 的参数 | 任意 | 否 | 通常传入 context,可附带额外参数 |
返回值:无
典型用途:
- 实现 K 线收线逻辑,让策略只在每根 K 线收盘时运行一次
- 避免每个 tick 都执行计算密集的 K 线指标,降低运算开销
- 与 tick 级逻辑解耦,便于组织多周期策略
接口案例:
def on_tick(context):
...
# tick 数据处理逻辑
tick_data_process(context)
...
# 注册 on_bar:K 线收线时运行
on_bar_run(on_bar, context, other_params)
def on_bar(context, other_params):
"""需要被逐根 K 线运行的策略代码"""
...
提示:若策略不需要收线执行,可在
on_tick中省略on_bar_run调用。
on_order(context, order) — 接收委托单
说明:返回委托单信息的方法,此处 order 为未成交状态的报单信息;用于存储和访问交易过程中的各种状态和信息;可在此处对订单状态进行分析和调控。
触发时机:每次 OrderStatus 发生改变时调用一次(包括未成交、部分成交、撤单等状态)。
输入参数:
| 参数 | 参数名称 | 参数类型 | 是否必填 | 描述 |
|---|---|---|---|---|
| context | 运行时状态对象 | object | 是 | 用于存储和传递运行时状态 |
| order | 订单信息 | dict | 否 | 字段详见对象 ORDER_DATA |
order 关键字段(完整字段见 ORDER_DATA):
| 字段 | 类型 | 说明 |
|---|---|---|
InstrumentID |
str | 合约代码 |
Direction |
str | 买卖方向 |
LimitPrice |
float | 限价 |
VolumeTotalOriginal |
int | 报单数量 |
VolumeTraded |
int | 已成交数量 |
VolumeTotal |
int | 总成交量 |
OrderStatus |
str | 订单状态('0':全部成交;'1':部分成交还在队列中;'2':部分成交不在队列中;'3':未成交还在队列中;'4':未成交不在队列中;'5':撤单;'a':未知;'b':尚未触发;'c':已触发;) |
OrderSubmitStatus |
str | 订单提交状态('0':已经提交;'1':撤单已经提交;'2':修改已经提交;'3':已经接受;'4':报单已经被拒绝;'5':撤单已经被拒绝;'6':改单已经被拒绝;) |
OrderSysID |
str | 订单在交易所系统的唯一标识 |
OrderRef |
str | 报单引用 |
CombOffsetFlag |
str | 组合开平标志 |
StatusMsg |
str | 状态信息 |
ExchangeID |
str | 交易所代码 |
InsertTime |
str | 订单插入时间 |
UpdateTime |
str | 行情交易数据更新时间 |
接口案例:
def on_order(context, order):
order_status = order.get("OrderStatus")
CombOffsetFlag = order.get("CombOffsetFlag")
StatusMsg = order.get("StatusMsg")
if order_status == "5":
if CombOffsetFlag == "0":
# 清除开启任务等待序列
context.open_task.clear()
else:
# 清除关闭任务等待序列
context.close_task.clear()
注意事项:每次 OrderStatus 发生改变该函数会返回一次,目前返回情况只有以下几种:
a -> 0a -> 3 -> 0a -> 3 -> 4 -> 0a -> 5a -> 3 -> 5
on_allorder(context, order) — 接收订单发送请求的回复
说明:on_order 只能收到本任务发送请求的回复,on_allorder 会接收任务挂在账户的所有订单回复,仅在任务中使用,回测中不可用。
触发时机:账户挂载的所有订单回复时调用。
输入参数:
| 参数 | 参数名称 | 参数类型 | 是否必填 | 描述 |
|---|---|---|---|---|
| context | 运行时状态对象 | object | 是 | 用于存储和传递运行时状态 |
| order | 订单信息 | dict | 否 | 字段同 ORDER_DATA |
接口案例:
def on_allorder(context, order):
put_log("收到order信息", "INFO")
put_log(f"{order}", "INFO")
on_trade(context, trade) — 接收成交单
说明:接收成交单信息的方法,此处 trade 为已成交状态的报单信息;字段与 on_order 中 order 对象相同(ORDER_DATA),但值会有一定差异。
触发时机:每次接收到成交记录时调用。
输入参数:
| 参数 | 参数名称 | 参数类型 | 是否必填 | 描述 |
|---|---|---|---|---|
| context | 运行时状态对象 | object | 是 | 用于存储和传递运行时状态 |
| trade | 成交信息 | dict | 否 | 字段详见对象 ORDER_DATA |
trade 关键字段(含成交单专属字段):
| 字段 | 类型 | 说明 |
|---|---|---|
InstrumentID |
str | 合约代码 |
Direction |
str | 买卖方向('0':买;'1':卖) |
OffsetFlag |
str | 开平标志('0':开仓;'1':平仓;'2':强平;'3':平今;'4':平昨;'5':强减;'6':本地强平) |
Price |
float | 成交价格 |
Volume |
int | 成交数量 |
TradeID |
str | 成交编号 |
OrderSysID |
str | 订单在交易所系统的唯一标识 |
req_id |
str | 报单订单号 |
TradeTime |
str | 交易时间 |
TradeDate |
str | 交易日期 |
TradeType |
str | 成交类型('#':组合持仓拆分为单一持仓,初始化不应包含该类型的持仓;'0':普通成交;'1':期权执行;'2':OTC成交;'3':期转现衍生成交;'4':组合衍生成交;'5':大宗交易成交;) |
TradingRole |
str | 交易角色 |
HedgeFlag |
str | 投机套保标志 |
OrderRef |
str | 报单引用 |
ExchangeID |
str | 交易所代码 |
接口案例:
def on_trade(context, trade):
trade_id = trade.get("TradeID")
price = trade.get("Price")
volume = trade.get("Volume")
put_log(f"成交: id={trade_id}, price={price}, volume={volume}", "INFO")
on_error(context, err) — 错误处理
触发时机:策略运行过程中发生异常时。
def on_error(context, err):
put_log(f'策略错误: {err}', level='ERROR')
on_stop(context) — 策略停止
触发时机:用户手动停止策略、或策略正常结束前调用一次。适合做收尾工作(如保存数据、释放资源)。
def on_stop(context):
put_log('策略已停止', level='INFO')
附录:ORDER_DATA 完整字段表
以下为 on_order 委托单与 on_trade 成交单的完整字段表,两个回调的 order/trade 对象均透从此对象,但取值场景不同(详见各回调章节说明)。
ORDER_DATA 委托单对象字段(on_order)
| 参数 | 参数名称 | 参数类型 | 回测/任务 | 描述 |
|---|---|---|---|---|
| AccountID | 投资者帐号 | str | ALL | |
| ActiveTime | 激活时间 | str | ALL | |
| ActiveTraderID | 激活交易 ID | str | ALL | |
| ActiveUserID | 操作用户代码 | str | ALL | |
| BranchID | 营业部编号 | str | ALL | |
| BrokerID | 经纪公司代码 | str | ALL | |
| BrokerOrderSeq | 系统的报单编号 | int | ALL | |
| BusinessUnit | 业务单元 | str | ALL | |
| CancelTime | 撤销时间 | str | ALL | |
| ClearingPartID | 清算会员编号 | str | ALL | |
| ClientID | 交易编码 | str | ALL | |
| CombHedgeFlag | 组合投机套保标志 | str | ALL | |
| CombOffsetFlag | 组合开平标志 | str | ALL | |
| ContingentCondition | 触发条件 | str | ALL | |
| CurrencyID | 币种代码 | str | ALL | |
| Direction | 买卖方向 | str | ALL | |
| ExchangeID | 交易所代码 | str | ALL | |
| ExchangeInstID | 合约在交易所的代码 | str | ALL | |
| ForceCloseReason | 强平原因 | str | ALL | |
| FrontID | 后台前置编号 | int | ALL | |
| GTDDate | GTD 日期 | str | ALL | |
| IPAddress | IP 地址 | str | ALL | |
| InsertDate | 订单插入日期 | str | ALL | |
| InsertTime | 订单插入时间 | str | ALL | |
| InstallID | 安装编号 | int | ALL | |
| InstrumentID | 合约代码 | str | ALL | |
| InvestUnitID | 投资单元代码 | str | ALL | |
| InvestorID | 投资者代码 | str | ALL | |
| IsAutoSuspend | 自动挂起标志 | int | ALL | 1:自动挂起;0:非自动挂起 |
| IsSwapOrder | 互换单标志 | str | ALL | |
| LimitPrice | 限价 | float | ALL | |
| MacAddress | Mac 地址 | str | ALL | |
| MinVolume | 最小成交量 | int | ALL | |
| NotifySequence | 报单提示序号 | int | ALL | |
| OrderLocalID | 系统分配的唯一标识符 | str | ALL | |
| OrderPriceType | 报单价格条件 | str | ALL | |
| OrderRef | 报单引用 | str | ALL | |
| OrderSource | 标识订单的来源 | str | ALL | '0':来自参与者;'1':来自管理员; |
| OrderStatus | 订单的状态 | str | ALL | '0':全部成交;'1':部分成交还在队列中;'2':部分成交不在队列中;'3':未成交还在队列中;'4':未成交不在队列中;'5':撤单;'a':未知;'b':尚未触发;'c':已触发; |
| OrderSubmitStatus | 订单的提交状态 | str | ALL | '0':已经提交;'1':撤单已经提交;'2':修改已经提交;'3':已经接受;'4':报单已经被拒绝;'5':撤单已经被拒绝;'6':改单已经被拒绝; |
| OrderSysID | 订单在交易所系统的唯一标识 | str | ALL | |
| OrderType | 订单类型 | str | ALL | '0':正常;'1':报价衍生;'2':组合衍生;'3':组合报单;'4':条件单;'5':互换单;'6':大宗交易成交衍生;'7':期转现成交衍生; |
| ParticipantID | 参与者的唯一标识 | str | ALL | |
| RelativeOrderSysID | 关联订单的系统编号 | str | ALL | |
| RequestID | 请求编号 | int | ALL | |
| SequenceNo | 序号 | int | ALL | |
| SessionID | 会话编号 | int | ALL | |
| SettlementID | 结算编号 | int | ALL | |
| StatusMsg | 状态信息 | str | ALL | |
| StopPrice | 止损价 | int | ALL | |
| SuspendTime | 顺序消费过程中消费失败后的延时时间 | str | ALL | |
| TimeCondition | 报单有效期类型 | str | ALL | |
| TraderID | 交易所交易员代码 | str | ALL | |
| TradingDay | 交易系统日期 | str | ALL | |
| UpdateTime | 行情交易数据的更新时间 | str | ALL | |
| UserForceClose | 强制平仓标志 | str | ALL | |
| UserID | 用户代码 | str | ALL | |
| UserProductInfo | 用户端产品信息 | str | ALL | |
| VolumeCondition | 成交量类型 | str | ALL | |
| VolumeTotal | 总成交量 | int | ALL | |
| VolumeTotalOriginal | 数量 | int | ALL | |
| VolumeTraded | 已成交数量 | int | ALL | |
| ZCETotalTradedVolume | 郑商所某一期货品种的总成交量 | int | ALL | |
| reserve1 | (保留字段) | |||
| reserve2 | (保留字段) | |||
| reserve3 | (保留字段) |
ORDER_DATA 成交单对象字段(on_trade)
成交单对象在委托单字段基础上新增以下成交专属字段(描述列标 专属),部分字段仅在任务中返回(描述列标 任务):
| 参数 | 参数名称 | 参数类型 | 回测/任务 | 描述 |
|---|---|---|---|---|
| AccountID | 投资者帐号 | str | 任务 | |
| ActiveTime | 激活时间 | str | 任务 | |
| ActiveTraderID | 激活交易 ID | str | 任务 | |
| ActiveUserID | 操作用户代码 | str | 任务 | |
| BranchID | 营业部编号 | str | 任务 | |
| BrokerID | 经纪公司代码 | str | ALL | |
| BrokerOrderSeq | 系统的报单编号 | int | ALL | |
| BusinessUnit | 业务单元 | str | ALL | |
| CancelTime | 撤销时间 | str | 任务 | |
| ClearingPartID | 清算会员编号 | str | ALL | |
| ClientID | 交易编码 | str | ALL | |
| CombHedgeFlag | 组合投机套保标志 | str | 任务 | |
| CombOffsetFlag | 组合开平标志 | str | 任务 | |
| ContingentCondition | 触发条件 | str | 任务 | |
| CurrencyID | 币种代码 | str | ALL | |
| Direction | 买卖方向 | str | ALL | '0':买;'1':卖; |
| ExchangeID | 交易所代码 | str | ALL | |
| ExchangeInstID | 合约在交易所的代码 | str | ALL | |
| ForceCloseReason | 强平原因 | str | 任务 | |
| FrontID | 后台前置编号 | str | 任务 | |
| GTDDate | GTD 日期 | str | 任务 | |
| IPAddress | IP 地址 | str | 任务 | |
| InsertDate | 订单插入日期 | str | 任务 | |
| InsertTime | 订单插入时间 | str | 任务 | |
| InstallID | 安装编号 | str | 任务 | |
| InstrumentID | 合约代码 | str | ALL | |
| InvestUnitID | 投资单元代码 | str | ALL | |
| InvestorID | 投资者代码 | str | ALL | |
| IsAutoSuspend | 自动挂起标志 | str | 任务 | |
| IsSwapOrder | 互换单标志 | str | 任务 | |
| LimitPrice | 限价 | str | 任务 | |
| MacAddress | Mac 地址 | str | 任务 | |
| MinVolume | 最小成交量 | str | 任务 | |
| NotifySequence | 报单提示序号 | str | 任务 | |
| OrderLocalID | 系统分配的唯一标识符 | str | ALL | |
| OrderPriceType | 报单价格条件 | str | 任务 | |
| OrderRef | 报单引用 | str | ALL | |
| OrderSource | 标识订单的来源 | str | 任务 | |
| OrderStatus | 订单的状态 | str | 任务 | |
| OrderSubmitStatus | 订单的提交状态 | str | 任务 | |
| OrderSysID | 订单在交易所系统的唯一标识 | str | ALL | |
| OrderType | 订单类型 | str | 任务 | |
| ParticipantID | 参与者的唯一标识 | str | ALL | |
| RelativeOrderSysID | 关联订单的系统编号 | str | 任务 | |
| RequestID | 请求编号 | str | 任务 | |
| SequenceNo | 序号 | int | ALL | |
| SessionID | 会话编号 | int | 任务 | |
| SettlementID | 结算编号 | int | ALL | |
| StatusMsg | 状态信息 | str | 任务 | |
| StopPrice | 止损价 | str | 任务 | |
| SuspendTime | 顺序消费过程中消费失败后的延时时间 | str | 任务 | |
| TimeCondition | 报单有效期类型 | str | 任务 | |
| TraderID | 交易所交易员代码 | str | ALL | |
| TradingDay | 交易系统日期 | str | ALL | |
| UpdateTime | 行情交易数据的更新时间 | str | 任务 | |
| UserForceClose | 强制平仓标志 | str | 任务 | |
| UserID | 用户代码 | str | ALL | |
| UserProductInfo | 用户端产品信息 | str | 任务 | |
| VolumeCondition | 成交量类型 | str | 任务 | |
| VolumeTotal | 总成交量 | str | 任务 | |
| VolumeTotalOriginal | 数量 | str | 任务 | |
| VolumeTraded | 已成交数量 | str | 任务 | |
| ZCETotalTradedVolume | 郑商所某一期货品种的总成交量 | str | 任务 | |
| reserve1 | (保留字段) | str | 任务 | |
| reserve2 | (保留字段) | str | 任务 | |
| reserve3 | (保留字段) | str | 任务 | |
| req_id | 报单订单号 | str | ALL | |
| HedgeFlag | 投机套保标志 | str | ALL | |
| OffsetFlag | 开平标志 | str | ALL | '0':开仓;'1':平仓;'2':强平;'3':平今;'4':平昨;'5':强减;'6':本地强平; |
| Price | 价格 | float | ALL | |
| PriceSource | 价格来源 | str | ALL | |
| TradeDate | 交易日期 | str | ALL | |
| TradeID | 成交编号 | str | ALL | |
| TradeSource | 成交来源 | str | ALL | |
| TradeTime | 交易时间 | str | ALL | |
| TradeType | 成交类型 | str | ALL | '#':组合持仓拆分为单一持仓,初始化不应包含该类型的持仓;'0':普通成交;'1':期权执行;'2':OTC成交;'3':期转现衍生成交;'4':组合衍生成交;'5':大宗交易成交; |
| TradingRole | 交易角色 | str | ALL | |
| Volume | 数量 | int | ALL |
相关阅读
- [外置参数与 Base 全局变量]
- [核心API 实时行情数据]
- [核心API 历史K线数据]
- [核心API 账户持仓查询]
- [核心API 衍生数据]
- [核心API 合约信息查询]

评论
登录后参与讨论,与站内账号体系共用。