3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 QMT 量化交易平台中,init(ContextInfo) 是策略的初始化函数。它是策略生命周期的起点,在整个策略运行过程中(无论是回测还是实盘),它只会在开始时被调用一次。
它的核心作用是配置环境和定义全局状态。你可以把它理解为策略的“设置面板”和“内存仓库”。
以下是关于 init 函数中应该包含内容的详细说明:
init 函数的核心职责在 init 中,你通常需要完成以下五类操作:
这是连接策略与交易柜台的关键。
ContextInfo.set_account(account_id)passorder)将无法正常工作或无法接收回报。定义策略关注的标的集合。
ContextInfo.set_universe(stock_list)get_history_data)默认会使用这里设置的股票池。如果不设置,后续获取数据可能需要每次手动指定代码列表,且回测效率可能降低。虽然可以在界面上设置,但在代码中设置可以确保策略逻辑的一致性,且代码设置的优先级高于界面。
ContextInfo.capital = 1000000ContextInfo.set_commission(...)ContextInfo.set_slippage(...)ContextInfo.start / ContextInfo.end由于 handlebar 函数会随行情频繁运行,定义在 handlebar 内部的普通变量会在每次运行结束后销毁。如果你需要记录**“上一次买入价格”、“当前持仓天数”、“策略状态开关”**等跨周期的数据,必须在 init 中将它们挂载到 ContextInfo 对象上。
ContextInfo.my_last_buy_price = 0如果你需要策略在特定的时间点运行(例如每天 14:50 进行尾盘选股),而不是每根 K 线都运行,可以在这里注册定时任务。
ContextInfo.run_time(...)严格来说,Python 语法要求函数体不能为空(至少要写个 pass),但从策略运行的角度看:
必须项:
def init(ContextInfo): 必须存在。ContextInfo.set_account(...)。如果没有这一步,交易回报回调(如 order_callback)不会生效,下单时若不指定账号也会报错。非必须但极重要项:
ContextInfo.set_universe(...)。除非你的策略完全不依赖历史数据接口的默认行为,否则这是基础。下面是一个标准的 init 函数模板,涵盖了上述要点:
# -*- coding: gbk -*-
def init(ContextInfo):
# 1. 【必须】设置资金账号
# 实盘中请替换为真实的资金账号,回测时可随意填写
my_account = '600000248'
ContextInfo.set_account(my_account)
# 2. 【建议】设置股票池
# 设定策略要操作的标的,例如:平安银行和贵州茅台
stock_list = ['000001.SZ', '600519.SH']
ContextInfo.set_universe(stock_list)
# 3. 【回测专用】设置回测参数 (代码优先级 > 界面设置)
# 设置初始资金为 100 万
ContextInfo.capital = 1000000
# 设置手续费:股票买入万三,卖出万三加千一印花税
# 参数顺序: [买入印花税, 卖出印花税, 开仓佣金, 平仓佣金, 平今佣金, 最低佣金]
ContextInfo.set_commission(0, [0, 0.001, 0.0003, 0.0003, 0, 5])
# 设置滑点:按固定价格 0.01 元
ContextInfo.set_slippage(1, 0.01)
# 4. 【逻辑核心】定义全局变量
# 注意:必须挂载在 ContextInfo 下,才能在 handlebar 中被调用和修改
ContextInfo.hold_days = 0 # 记录持仓天数
ContextInfo.last_entry_price = {} # 记录每只股票的入场价格
ContextInfo.stop_loss_pct = 0.05 # 定义全局止损比例 5%
# 5. 【进阶】设置定时器 (可选)
# 例如:每天 10:00:00 运行一次名为 on_time_check 的自定义函数
# ContextInfo.run_time("on_time_check", "1nDay", "2023-01-01 10:00:00", "SH")
print("策略初始化完成")
init 函数是策略的配置中心。
init 里写交易逻辑(如判断均线金叉下单),因为这里没有行情驱动,只运行一次。init 里把所有后续需要用到的“状态变量”都定义好,防止在 handlebar 中出现 NameError 或变量重置的问题。Q1: 如果我在 init 里写了死循环 while True 会怎么样?
A1: 策略会卡死在初始化阶段,永远无法进入 handlebar 处理行情,甚至导致客户端无响应。init 必须快速执行完毕。
Q2: ContextInfo.benchmark (基准) 可以在 init 里设置吗?
A2: QMT 的 Python API 中 ContextInfo.benchmark 是只读属性,不支持通过代码设置。回测基准需要在策略编辑器的“回测参数”面板中手动选择。
Q3: 我可以在 init 里获取历史数据吗?
A3: 可以。你可以调用 ContextInfo.get_history_data 来计算一些盘前指标(例如计算过去一年的波动率作为今天的参考),但要注意此时获取的是策略启动时刻之前的数据。
Q4: 为什么我的全局变量在 handlebar 里报错说不存在?
A4: 请检查是否在 init 中使用了 ContextInfo.变量名 = 值 的形式。如果只是写 my_var = 0,它只是 init 函数内的局部变量,函数运行完就销毁了,必须挂载到 ContextInfo 对象上才能跨函数传递。