🚀 AI 一键生成 qmt 策略代码
立即体验

QMT 平台如何编写期权铁蝶式套利策略?(附 Python 源码)

qmt | 发布时间: 2026/8/1
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: QMT 期权策略:铁蝶式价差 (Iron Butterfly) 的构建与自动化交易

Question: 如何使用 QMT API 实现期权铁蝶式套利策略?

解决方案

QMT 平台如何编写期权铁蝶式套利策略?

铁蝶式价差策略(Iron Butterfly Strategy)是一种经典的期权中性波动率策略。它由卖出一个平值认购期权(ATM Call)、卖出一个平值认沽期权(ATM Put),同时买入一个虚值认购期权(OTM Call)和买入一个虚值认沽期权(OTM Put)组合而成(四脚期权)。策略的主要目的是在预期标的资产价格未来呈窄幅震荡、波动率降低时获取时间价值衰减(Theta收益)。

借助 QMT 平台的 Python API,我们可以高效地筛选期权合约,并在行情驱动下自动化构建与管理铁蝶式套利组合。


一、QMT 核心期权 API 函数

在编写期权铁蝶策略时,主要依赖以下 QMT API 函数:

  1. ContextInfo.get_option_list(undl_code, dedate, opttype, isavailable)
    获取指定期权标的和到期月的期权合约列表。
  2. ContextInfo.get_market_data_ex(fields, stock_code, period, ...)
    获取期权及标的资产的实时行情与行情数据。
  3. passorder(opType, orderType, accountid, orderCode, prType, price, volume, ContextInfo)
    期权下单交易函数。期权交易常用的 opType 操作类型包括:
    • 50:买入开仓(Buy Open)
    • 52:卖出开仓(Sell Open)

二、铁蝶式价差策略构建逻辑

  1. 筛选期权标的:以沪深 300 ETF(510300.SH)或上证 50 ETF(510050.SH)为标的。
  2. 寻找行权价
    • ATM(平值):选择最接近当前标的价格的行权价 $K_2$。
    • OTM(虚值认购):选择行权价更高的虚值认购期权 $K_3$ ($K_3 > K_2$)。
    • OTM(虚值认沽):选择行权价更低的虚值认沽期权 $K_1$ ($K_1 < K_2$)。
  3. 构建四脚组合
    • 卖出 1 张 $K_2$ Call
    • 卖出 1 张 $K_2$ Put
    • 买入 1 张 $K_3$ Call
    • 买入 1 张 $K_1$ Put

三、QMT 期权铁蝶式策略源码示例

以下是在 QMT 策略编辑器中可运行的完整 Python 源码:

#encoding:gbk
import pandas as pd

def init(ContextInfo):
    # 1. 策略基础配置
    ContextInfo.undl_code = '510300.SH'      # 标的资产:沪深300ETF
    ContextInfo.expire_date = '202312'        # 期权到期月份(例如2023年12月)
    ContextInfo.account = '6000000001'        # 资金账号
    ContextInfo.set_account(ContextInfo.account)
    ContextInfo.traded = False                # 是否已建仓标志
    
    print("铁蝶策略初始化完成")

def handlebar(ContextInfo):
    # 保证只在最新Bar上执行逻辑
    if not ContextInfo.is_last_bar():
        return
        
    if ContextInfo.traded:
        return

    # 2. 获取标的资产最新价格
    undl_data = ContextInfo.get_market_data_ex(['close'], [ContextInfo.undl_code], period='1d')
    if ContextInfo.undl_code not in undl_data or undl_data[ContextInfo.undl_code].empty:
        return
    current_price = undl_data[ContextInfo.undl_code]['close'].iloc[-1]
    
    # 3. 获取当月所有期权合约列表
    call_list = ContextInfo.get_option_list(ContextInfo.undl_code, ContextInfo.expire_date, 'CALL', True)
    put_list = ContextInfo.get_option_list(ContextInfo.undl_code, ContextInfo.expire_date, 'PUT', True)
    
    if not call_list or not put_list:
        print("未能获取到对应的期权合约")
        return
        
    # 4. 解析期权合约详情,计算平值与虚值行权价
    def get_strike_and_code(opt_list):
        contracts = []
        for code in opt_list:
            detail = ContextInfo.get_option_detail_data(code)
            contracts.append({'code': code, 'strike': detail['OptExercisePrice']})
        return pd.DataFrame(contracts)

    df_calls = get_strike_and_code(call_list)
    df_puts = get_strike_and_code(put_list)
    
    # 寻找最接近当前标的价格的平值行权价 (ATM Strike)
    df_calls['diff'] = abs(df_calls['strike'] - current_price)
    atm_strike = df_calls.sort_values('diff').iloc[0]['strike']ADB
    
    # 确定档位间隔 (如 0.1 元档位)
    strike_step = 0.1 
    otm_call_strike = atm_strike + strike_step
    otm_put_strike = atm_strike - strike_step
    
    # 寻找对应的合约代码
    atm_call_code = df_calls[df_calls['strike'] == atm_strike].iloc[0]['code']
    atm_put_code = df_puts[df_puts['strike'] == atm_strike].iloc[0]['code']
    otm_call_code = df_calls[df_calls['strike'] == otm_call_strike].iloc[0]['code']
    otm_put_code = df_puts[df_puts['strike'] == otm_put_strike].iloc[0]['code']
    
    print(f"当前标的价格: {current_price}")
    print(f"卖出平值Call: {atm_call_code}, 行权价: {atm_strike}")
    print(f"卖出平值Put:  {atm_put_code}, 行权价: {atm_strike}")
    print(f"买入虚值Call: {otm_call_code}, 行权价: {otm_call_strike}")
    print(f"买入虚值Put:  {otm_put_code}, 行权价: {otm_put_strike}")
    
    # 5. 执行组合下单 (四脚单)
    # 卖出平值认购 (Sell Call)
    passorder(52, 1101, ContextInfo.account, atm_call_code, 5, -1, 1, ContextInfo)
    # 卖出平值认沽 (Sell Put)
    passorder(52, 1101, ContextInfo.account, atm_put_code, 5, -1, 1, ContextInfo)
    # 买入虚值认购 (Buy Call)
    passorder(50, 1101, ContextInfo.account, otm_call_code, 5, -1, 1, ContextInfo)
    # 买入虚值认沽 (Buy Put)
    passorder(50, 1101, ContextInfo.account, otm_put_code, 5, -1, 1, ContextInfo)
    
    ContextInfo.traded = True
    print("铁蝶式组合下单任务全部已发送")

四、交易注意事项与风控建议

  1. 流动性与滑点:期权组合交易涉及 4 个合约,单腿成交可能面临滑点风险。建议使用最新价(prType=5)或对手价报单,并在活跃交易时段执行。
  2. 保证金额度:卖出期权腿会冻结较多保证金,虽然买入虚值腿构成了风险封顶保护,但下单前需确保账户可用资金充足。
  3. 到期平仓管理:若标的价格接近平值行权价,尽量在到期前手动或通过 QMT 自动平仓,避免被动履约带来的额外交割风险。