3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
网格交易是一种基于价格震荡进行低买高卖(或高卖低买)的自动化交易策略。在商品期货交易中,结合双向网格(多空同时挂单)与动态风控体系,可以在震荡行情中获取稳定的波段收益。
本文将基于 QMT(迅投量化原生 Python API)介绍如何编写一个商品期货动态双向网格策略,并包含关键的资金与持仓风控机制。
在 QMT 策略编辑器中,需定义 init 与 handlebar 核心函数。策略编写示例如下:
#coding:gbk
import numpy as np
def init(ContextInfo):
# 1. 策略基本设置
ContextInfo.symbol = 'rb2401.SF' # 交易合约(以螺纹钢为例)
ContextInfo.set_universe([ContextInfo.symbol])
ContextInfo.account = '110476' # 资金账号
ContextInfo.set_account(ContextInfo.account)
# 2. 网格参数配置
ContextInfo.grid_ratio = 0.01 # 网格间距 1%
ContextInfo.order_lots = 1 # 每单交易手数
ContextInfo.max_pos = 5 # 单向最大持仓手数
ContextInfo.base_price = 0.0 # 初始网格基准价
# 3. 全局状态控制
ContextInfo.long_pos = 0 # 多头持仓
ContextInfo.short_pos = 0 # 空头持仓
print("【策略初始化】商品期货双向网格策略加载成功")
def handlebar(ContextInfo):
# 只在最新 Bar 或 Tick 来时运行核心逻辑
if not ContextInfo.is_last_bar():
return
# 获取最新行情
ticks = ContextInfo.get_full_tick([ContextInfo.symbol])
if ContextInfo.symbol not in ticks:
return
last_price = ticks[ContextInfo.symbol]['lastPrice']
# 初始化基准价格
if ContextInfo.base_price == 0.0:
ContextInfo.base_price = last_price
print(f"【基准价设定】初始网格基准价: {ContextInfo.base_price}")
return
# 获取账户资金与持仓风控
account_info = get_trade_detail_data(ContextInfo.account, 'FUTURE', 'ACCOUNT')
if account_info:
available_cash = account_info[0].m_dAvailable
balance = account_info[0].m_dBalance
# 风控:保证金占用超过 80% 时停止开仓
if (balance - available_cash) / balance > 0.8:
print("【风控警告】保证金占用率过高,暂停开仓")
return
# 更新持仓数据
positions = get_trade_detail_data(ContextInfo.account, 'FUTURE', 'POSITION')
ContextInfo.long_pos = 0
ContextInfo.short_pos = 0
for pos in positions:
if pos.m_strInstrumentID == ContextInfo.symbol.split('.')[0]:
if pos.m_nDirection == 48: # 多头
ContextInfo.long_pos = pos.m_nVolume
elif pos.m_nDirection == 49: # 空头
ContextInfo.short_pos = pos.m_nVolume
# 4. 双向网格交易逻辑
upper_grid = ContextInfo.base_price * (1 + ContextInfo.grid_ratio)
lower_grid = ContextInfo.base_price * (1 - ContextInfo.grid_ratio)
# ---- 价格突破下轨:触发多头开仓 或 空头止盈 ----
if last_price <= lower_grid:
# 空头止盈平仓
if ContextInfo.short_pos > 0:
print(f"【平空止盈】最新价 {last_price} <= 下轨 {lower_grid}")
passorder(8, 1101, ContextInfo.account, ContextInfo.symbol, 5, -1, ContextInfo.order_lots, ContextInfo)
ContextInfo.base_price = last_price
# 多头逢低开仓(需受最大持仓限制)
elif ContextInfo.long_pos < ContextInfo.max_pos:
print(f"【开多进场】最新价 {last_price} <= 下轨 {lower_grid}")
passorder(0, 1101, ContextInfo.account, ContextInfo.symbol, 5, -1, ContextInfo.order_lots, ContextInfo)
ContextInfo.base_price = last_price
# ---- 价格突破上轨:触发空头开仓 或 多头止盈 ----
elif last_price >= upper_grid:
# 多头止盈平仓
if ContextInfo.long_pos > 0:
print(f"【平多止盈】最新价 {last_price} >= 上轨 {upper_grid}")
passorder(6, 1101, ContextInfo.account, ContextInfo.symbol, 5, -1, ContextInfo.order_lots, ContextInfo)
ContextInfo.base_price = last_price
# 空头逢高开仓(需受最大持仓限制)
elif ContextInfo.short_pos < ContextInfo.max_pos:
print(f"【开空进场】最新价 {last_price} >= 上轨 {upper_grid}")
passorder(3, 1101, ContextInfo.account, ContextInfo.symbol, 5, -1, ContextInfo.order_lots, ContextInfo)
ContextInfo.base_price = last_price
max_pos,导致浮亏扩大。建议配合 ATR 指标设置全局止损线。ContextInfo.get_contract_multiplier(code) 获取合约乘数,精准计算所需的保证金。prType=5)下单,实盘中为提高成交率可将 prType 设置为对手价(14)或挂单价(13)。