套利与常用示例
套利是期货量化的高频需求,极智量化在这方面提供了灵活的支持:既兼容交易所标准套利合约,也能自由组合多腿自定义套利。本章把套利、止损止盈、参数优化这些实战常用模式一次讲清。
两种套利思路
| 类型 | 做法 | 关键点 |
|---|---|---|
| 交易所标准套利 | 订阅极星 SPD 套利合约行情,对交易所标准套利合约下单 | 无法直接取标准套利行情,须先订阅对应 SPD 行情驱动逻辑 |
| 自定义套利 | 分别订阅每腿合约,自己算价差、自己决定两腿下单 | 最灵活,可做跨期、跨品种、内外盘 |
交易所标准套利
标准套利要先订阅 SPD 套利合约行情作为触发源,再对交易所标准套利合约下单。以 TA107/TA109 套利为例:
import talib
g_params['p1'] = 5 # 短周期
g_params['p2'] = 15 # 长周期
g_params['dot'] = 1 # 突破点位
spd = 'SPD|s|TA|107|109' # 极星SPD套利合约(驱动行情)
code = 'ZCE|S|TA|107|109' # 交易所标准套利合约(下单标的)
def initialize(context):
SetBarInterval(spd, 'M', 1, 2000) # 订阅策略触发行情
SetBarInterval(code, 'M', 1, 2000) # 必须订阅下单合约行情,否则下单失败
def handle_data(context):
if context.contractNo() != spd: # 只在SPD行情触发时执行
return
if CurrentBar() < g_params['p2']:
return
_close = Close(spd, 'M', 1)
ma1 = talib.MA(_close, g_params['p1'])[-1]
ma2 = talib.MA(_close, g_params['p2'])[-1]
dot = g_params['dot'] * PriceTick('ZCE|F|TA|107')
if ma1 - ma2 > dot and BuyPosition(code) == 0:
Buy(1, _close[-1], code)
elif ma2 - ma1 > dot and SellPosition(code) == 0:
SellShort(1, _close[-1], code)
注意两点:触发合约判断用
context.contractNo() != spd;下单合约的行情必须订阅,否则会下单失败。
自定义跨期套利
自定义套利最自由——订阅每一腿,自己构造价差序列,再对两腿分别下单。下面是一个简洁的双均线价差套利(TA105 与 TA109):
import talib
import numpy as np
code1 = "ZCE|F|TA|105"
code2 = "ZCE|F|TA|109"
p1, p2, dot, qty = 5, 20, 1, 1
spds = [] # 全局价差序列
def initialize(context):
SetBarInterval(code1, 'M', 1, 2000)
SetBarInterval(code2, 'M', 1, 2000)
SetOrderWay(2)
def handle_data(context):
prc1 = Close(code1, 'M', 1)
prc2 = Close(code2, 'M', 1)
if len(prc1) == 0 or len(prc2) == 0:
return
global spds
spd_c = prc1[-1] - prc2[-1] # 当根价差
if len(prc1) > len(spds): # 新Bar:追加
spds.append(spd_c)
else: # 同Bar:更新末尾
spds[-1] = spd_c
if len(spds) < p2:
return
sma1 = talib.MA(np.array(spds), p1)
sma2 = talib.MA(np.array(spds), p2)
tick = dot * PriceTick()
if sma1[-1] > sma2[-1] + tick and MarketPosition(code1) <= 0:
Buy(qty, prc1[-1], code1)
SellShort(qty, prc2[-1], code2) # 做强腿、做空弱腿
elif sma1[-1] < sma2[-1] - tick and MarketPosition(code1) >= 0:
SellShort(qty, prc1[-1], code1)
Buy(qty, prc2[-1], code2)
PlotNumeric("sma1", sma1[-1], 0x0000FF, False)
PlotNumeric("sma2", sma2[-1], 0xFF0000, False)
PlotNumeric("fit", NetProfit() - TradeCost(), RGB_Purple(), False, True)
价差序列的维护是一个通用技巧:用「新 Bar 追加、同 Bar 更新」的模式保持一根 Bar 一个值。把均线换成布林带(talib.BBANDS)就是布林带套利,换成唐奇安通道就是海龟式突破,思路完全一致。
止损止盈
极智量化支持三种内置止盈止损,在 initialize 里设置,触发时自动平仓:
| 函数 | 含义 |
|---|---|
SetStopPoint(n) | 固定点止损:价格跌破开仓价 n×最小变动价位时平仓 |
SetWinPoint(n) | 固定点止盈:价格超过开仓价 n×最小变动价位时平仓 |
SetFloatStopPoint(start, back) | 浮动止损:盈利超过 start 点后启动,从最高点回撤 back 点时平仓 |
def initialize(context):
SetBarInterval('ZCE|Z|SR|MAIN', 'M', 1, 500)
SetStopPoint(10) # 跌破 10 个最小变动价位止损
SetWinPoint(20) # 超过 20 个最小变动价位止盈
SetFloatStopPoint(20, 10) # 盈利 20 点启动,回撤 10 点平仓
所有点数都要乘以品种的最小变动价位。浮动止损能「让盈利奔跑」,多头止损价 = 启用后最高价 − 回撤价位,空头反之。
参数优化
用 g_params 字典定义可优化参数,运行后右键策略选「参数优化」,设置最小值/最大值/步长,平台会遍历所有参数组合回测并列出收益、胜率等指标:
g_params['fast'] = 12 # 快周期
g_params['slow'] = 26 # 慢周期
g_params['back'] = 9 # DEA 周期
def handle_data(context):
if CurrentBar() < g_params['slow'] + g_params['back'] - 1:
return
diff, dea, macd = talib.MACD(Close(), g_params['fast'],
g_params['slow'], g_params['back'])
...
两个注意点:g_params 的值只在约定函数内部才随优化值更新,函数外部的全局变量不会跟着变(需要时在 initialize 里把 g_params['x'] 赋给全局变量);新增 g_params 键后要重新添加策略,参数优化界面才能提取到新参数。
常用模式速查
- 多合约:多次
SetBarInterval订阅不同合约,最多 50 个;第一个为基准合约。 - 多周期:同一合约订阅不同周期,Tick/秒/分钟/日均可,秒线用类型
'T'+ 非零周期。 - 主力换月:
SetTriggerType(7)订阅换月事件,由你自己决定换月时的仓位处理。 - 持仓同步:用
Buy/Sell下单出现仓差时,界面点「同步持仓」一键矫正。
小结
标准套利订阅 SPD 行情、对标准套利合约下单;自定义套利自建价差序列、两腿分别下单;均线/布林/突破只是价差判据不同。止损止盈三件套按点数设置;参数优化用 g_params 并注意值只在约定函数内生效。到此,极智量化从环境、指标、下单到套利与优化已形成闭环——左侧导航可随时回查任一章节。