3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
铁蝶式价差策略(Iron Butterfly Strategy)是一种经典的期权中性波动率策略。它由卖出一个平值认购期权(ATM Call)、卖出一个平值认沽期权(ATM Put),同时买入一个虚值认购期权(OTM Call)和买入一个虚值认沽期权(OTM Put)组合而成(四脚期权)。策略的主要目的是在预期标的资产价格未来呈窄幅震荡、波动率降低时获取时间价值衰减(Theta收益)。
借助 QMT 平台的 Python API,我们可以高效地筛选期权合约,并在行情驱动下自动化构建与管理铁蝶式套利组合。
在编写期权铁蝶策略时,主要依赖以下 QMT API 函数:
ContextInfo.get_option_list(undl_code, dedate, opttype, isavailable):ContextInfo.get_market_data_ex(fields, stock_code, period, ...):passorder(opType, orderType, accountid, orderCode, prType, price, volume, ContextInfo):opType 操作类型包括:
50:买入开仓(Buy Open)52:卖出开仓(Sell Open)510300.SH)或上证 50 ETF(510050.SH)为标的。以下是在 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("铁蝶式组合下单任务全部已发送")
prType=5)或对手价报单,并在活跃交易时段执行。