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

QMT 期权套利:平价平仓 (Put-Call Parity) 校验与自动化交易策略实现

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

问题描述

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

Title: QMT 期权套利:平价平仓 (Put-Call Parity) 校验与自动化交易

Question: 如何在 QMT 中利用期权认购认沽平价公式编写无风险套利策略?

解决方案

QMT 期权套利:平价平仓 (Put-Call Parity) 校验与自动化交易

1. 认购认沽平价理论 (Put-Call Parity)

对于欧式期权,根据无套利定价原理,同一标的、同一到期日、同一行权价的认购期权(Call)和认沽期权(Put)满足以下平价关系式:

$$C + K \cdot e^{-rT} = P + S$$

其中:

  • $C$:认购期权价格
  • $P$:认沽期权价格
  • $S$:标的资产当前价格
  • $K$:期权行权价
  • $r$:无风险利率
  • $T$:距离到期日的时间(年)

当市场价格偏离该等式并覆盖交易成本与买卖价差时,即存在无风险套利机会:

  1. 正向套利(Conversion):当 $C - P > S - K \cdot e^{-rT}$ 时,买入标的 + 买入认沽期权 + 卖出认购期权。
  2. 反向套利(Reverse Conversion):当 $C - P < S - K \cdot e^{-rT}$ 时,卖出标的 + 卖出认沽期权 + 买入认购期权。

2. QMT 策略逻辑与核心 API

在 QMT Python API 中编写该策略的核心步骤包括:

  • 使用 ContextInfo.get_option_list() 获取指定标的与到期日的期权合约。
  • 使用 ContextInfo.get_full_tick() 获取标的与期权的最新买卖盘口(Bid/Ask)。
  • 计算套利价差,并在利差大于设定门槛时,通过 passorder 进行组合下单。

3. QMT Python 策略源码实现

#encoding:gbk
import math

def init(ContextInfo):
    ContextInfo.accID = '6000000058'  # 替换为实际资金账号
    ContextInfo.set_account(ContextInfo.accID)
    ContextInfo.target_code = '510300.SH'  # 标的ETF
    ContextInfo.expiry_month = '202312'   # 到期月份
    ContextInfo.r = 0.025                 # 无风险利率
    ContextInfo.threshold = 0.005         # 套利利润门槛(元)
    
    # 获取认购与认沽期权列表
    ContextInfo.calls = ContextInfo.get_option_list(ContextInfo.target_code, ContextInfo.expiry_month, 'CALL')
    ContextInfo.puts = ContextInfo.get_option_list(ContextInfo.target_code, ContextInfo.expiry_month, 'PUT')

def handlebar(ContextInfo):
    if not ContextInfo.is_last_bar():
        return
    
    # 获取标的与期权的实时行情
    all_codes = [ContextInfo.target_code] + ContextInfo.calls + ContextInfo.puts
    ticks = ContextInfo.get_full_tick(all_codes)
    
    if ContextInfo.target_code not in ticks:
        return
    
    s_tick = ticks[ContextInfo.target_code]
    s_bid = s_tick['bidPrice'][0] # 标的买一价
    s_ask = s_tick['askPrice'][0] # 标的卖一价
    
    for call_code in ContextInfo.calls:
        detail = ContextInfo.get_option_detail_data(call_code)
        k = detail['OptExercisePrice']
        put_code = call_code.replace('CALL', 'PUT') # 对应认沽合约
        
        if call_code in ticks and put_code in ticks:
            c_tick = ticks[call_code]
            p_tick = ticks[put_code]
            
            c_bid, c_ask = c_tick['bidPrice'][0], c_tick['askPrice'][0]
            p_bid, p_ask = p_tick['bidPrice'][0], p_tick['askPrice'][0]
            
            # 正向套利校验:买标的 + 买Put + 卖Call
            # 成本 = S_ask + P_ask,收益 = C_bid + K
            conversion_profit = (c_bid + k) - (s_ask + p_ask)
            if conversion_profit > ContextInfo.threshold:
                print(f"触发正向套利机会: {call_code}, 预估利润: {conversion_profit}")
                # 示例下单:买入标的,买入Put,卖出Call(期权买入平仓/开仓使用对应opType)
                passorder(23, 1101, ContextInfo.accID, ContextInfo.target_code, 5, -1, 100, ContextInfo)
                passorder(50, 1101, ContextInfo.accID, put_code, 5, -1, 1, ContextInfo)
                passorder(52, 1101, ContextInfo.accID, call_code, 5, -1, 1, ContextInfo)