🚀 AI 一键生成 qmt 策略代码

如何在 QMT 中使用 BSM 模型计算期权理论价格和隐含波动率?

qmt | 发布时间: 2025/11/26
以下内容由 EasyQuant 生成。

问题描述

如何计算一个期权的理论价格和隐含波动率?

解决方案

在 QMT 量化交易平台中,计算期权的理论价格和隐含波动率主要基于 Black-Scholes-Merton (BSM) 模型。QMT 的 ContextInfo 对象提供了内置的 API 函数来直接完成这些计算,无需手动编写复杂的数学公式。

以下是具体的计算方法和代码示例。

1. 核心 API 函数

(1) 计算理论价格:ContextInfo.bsm_price

该函数用于根据标的价格、行权价、无风险利率、波动率等参数计算期权的理论价格。

  • 语法
    ContextInfo.bsm_price(optionType, objectPrices, strikePrice, riskFree, sigma, days, dividend)
  • 参数说明
    • optionType: 期权类型,'C' 代表认购 (Call),'P' 代表认沽 (Put)。
    • objectPrices: 标的资产当前价格 ($S$)。
    • strikePrice: 期权行权价 ($K$)。
    • riskFree: 无风险利率 ($r$),例如 0.03 代表 3%。
    • sigma: 标的年化波动率 ($\sigma$),例如 0.23 代表 23%。
    • days: 距离到期日的剩余天数 ($T$)。
    • dividend: 标的分红率 ($q$),通常设为 0。

(2) 计算隐含波动率:ContextInfo.bsm_iv

该函数用于根据期权的当前市场价格反推隐含波动率。

  • 语法
    ContextInfo.bsm_iv(optionType, objectPrices, strikePrice, optionPrice, riskFree, days, dividend)
  • 参数说明
    • 大部分参数与 bsm_price 相同。
    • optionPrice: 期权的当前市场价格(用于反推波动率)。

(3) 获取实时隐含波动率:ContextInfo.get_option_iv

如果你不需要自己根据模型计算,而是想直接获取交易所或系统计算好的实时隐含波动率,可以使用此函数。

  • 语法ContextInfo.get_option_iv(optioncode)

2. 策略代码示例

以下代码展示了如何在 QMT 策略中计算一个假设场景下的期权理论价格,并验证反推隐含波动率。

# -*- coding: gbk -*-

def init(ContextInfo):
    # 在初始化中可以做一些设置,这里暂时不需要
    pass

def handlebar(ContextInfo):
    # 为了演示,我们只在最后一根K线(最新时刻)运行计算
    if not ContextInfo.is_last_bar():
        return

    # ==========================================
    # 场景假设:
    # 标的:50ETF
    # 标的价格:3.51 元
    # 行权价:3.50 元
    # 无风险利率:3% (0.03)
    # 假设波动率:23% (0.23)
    # 剩余天数:15 天
    # 分红率:0
    # ==========================================

    # 1. 定义参数
    option_type = 'C'       # 认购期权
    obj_price = 3.51        # 标的价格
    strike_price = 3.50     # 行权价
    risk_free = 0.03        # 无风险利率
    sigma = 0.23            # 年化波动率
    days = 15               # 剩余天数
    dividend = 0            # 分红率

    # 2. 计算理论价格 (Theoretical Price)
    # 使用 bsm_price 计算
    theo_price = ContextInfo.bsm_price(option_type, obj_price, strike_price, risk_free, sigma, days, dividend)
    
    print("=" * 30)
    print(f"【参数输入】标的价:{obj_price}, 行权价:{strike_price}, 波动率:{sigma}, 剩余天数:{days}")
    print(f"【计算结果】BSM模型理论价格: {theo_price:.4f}")

    # 3. 计算隐含波动率 (Implied Volatility)
    # 假设我们观察到市场上的期权价格就是上面算出来的 theo_price,我们反推一下波动率
    # 理论上反推出来的结果应该非常接近输入的 sigma (0.23)
    market_price = theo_price 
    
    calc_iv = ContextInfo.bsm_iv(option_type, obj_price, strike_price, market_price, risk_free, days, dividend)
    
    print(f"【反推验证】基于价格 {market_price:.4f} 反推的隐含波动率: {calc_iv:.4f}")

    # 4. 获取指定合约的实时隐含波动率 (Real-time IV)
    # 假设获取 '10003280.SHO' 这个期权合约的实时IV
    # 注意:需要确保有期权行情权限且在交易时段或有历史数据
    target_option = '10003280.SHO'
    real_time_iv = ContextInfo.get_option_iv(target_option)
    print(f"【实时数据】合约 {target_option} 的系统实时隐含波动率: {real_time_iv}")
    print("=" * 30)

3. 注意事项

  1. 参数单位
    • 利率和波动率通常使用小数表示(如 0.03 表示 3%)。
    • days 参数直接传入剩余天数的数值(如 15),不需要转换为年化时间,API 内部会处理。
  2. 数据获取
    • 在实盘中,objectPrices(标的价格)通常通过 ContextInfo.get_market_data_ex 获取标的资产的最新 close 价格。
    • days(剩余天数)可以通过 ContextInfo.get_contract_expire_date 获取到期日后,与当前日期相减计算得出。
  3. 异常值处理
    • 如果输入的参数不合法(例如期权价格为负数,或者无法通过模型收敛计算出 IV),bsm_iv 可能会返回 nan 或异常值,建议在代码中加入判断逻辑。

Q&A

Q: bsm_price 函数支持美式期权吗?
A: 不支持。QMT 的 bsm_price 基于 Black-Scholes-Merton 模型,该模型专门用于计算欧式期权(European Options)的理论价格。对于美式期权,通常需要使用二叉树等数值方法,但 BSM 模型常被用作近似参考。

Q: 如何获取期权的剩余天数 days
A: 可以通过 ContextInfo.get_instrumentdetail(option_code) 获取期权的详细信息,其中包含 ExpireDate(到期日)。然后使用 Python 的 datetime 模块将到期日与当前日期相减,获取天数差。

Q: 为什么 get_option_iv 返回 0 或空值?
A: 这通常是因为:1. 当前账号没有期权行情权限;2. 该合约已经过期或未上市;3. 处于非交易时间且本地没有历史数据缓存。建议先检查行情订阅状态。