You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用QuantLib计算DataFrame各行看涨期权价格偏差问题

期权定价与实际价格偏差过大的原因分析

问题背景

用户持有标普500执行价K=500的期权链数据,尝试通过Black-Scholes模型计算看涨期权价格,但计算结果与实际收盘价偏差极大(例如实际价格0.95时,计算值仅0.013527)。

原始期权链数据

date,call_open,call_high,call_low,call_close,put_open,put_high,put_low,put_close,stock_open,stock_high,stock_low,stock_close,stock_volume
2024-01-31 15:30:00,1.03,1.82,0.88,0.95,11.72,12.78,11.34,12.55,488.62,489.09,487.52,487.76,61890.0
2024-01-31 15:30:00,1.03,1.82,0.88,0.95,11.72,12.78,11.34,12.55,488.62,489.09,487.52,487.76,61890.0
2024-01-31 16:00:00,0.95,0.96,0.79,0.84,12.55,13.80,12.47,13.48,487.73,487.83,486.39,486.75,81468.0
2024-01-31 16:00:00,0.95,0.96,0.79,0.84,12.55,13.80,12.47,13.48,487.73,487.83,486.39,486.75,81468.0
2024-01-31 17:00:00,0.84,0.92,0.81,0.86,13.48,13.88,12.76,13.39,486.74,487.48,486.34,486.84,53420.0

计算结果与实际偏差示例

date,call_open,call_high,call_low,call_close,put_open,put_high,put_low,put_close,stock_open,stock_high,stock_low,stock_close,stock_volume,option_pricing
2024-01-31 15:30:00,1.03,1.82,0.88,0.95,11.72,12.78,11.34,12.55,488.62,489.09,487.52,487.76,61890.0,0.013527
2024-01-31 15:30:00,1.03,1.82,0.88,0.95,11.72,12.78,11.34,12.55,488.62,489.09,487.52,487.76,61890.0,0.013527
2024-01-31 16:00:00,0.95,0.96,0.79,0.84,12.55,13.80,12.47,13.48,487.73,487.83,486.39,486.75,81468.0,0.006911
2024-01-31 16:00:00,0.95,0.96,0.79,0.84,12.55,13.80,12.47,13.48,487.73,487.83,486.39,486.75,81468.0,0.006911
2024-01-31 17:00:00,0.84,0.92,0.81,0.86,13.48,13.88,12.76,13.39,486.74,487.48,486.34,486.84,53420.0,0.007350

使用的计算代码

import pandas as pd
file_path = "path/expiry_20240214_strike_500.csv"
data = pd.read_csv(file_path)
data = data.dropna(subset=['stock_close'])
data


def compute_option_pricing(row):
    S = row['stock_close']  
    K = 500  
    v = data['stock_close'].std() / 100 
    ri = 0.0528 # 取自美国财政部2024年2月国债利率
    

    date = pd.to_datetime(row['date'])
    today = ql.Date(date.day, date.month, date.year)
    expiry = pd.to_datetime("2024-02-14")
    expiry = ql.Date(expiry.day, expiry.month, expiry.year) 
    
    # 设置评估日期
    ql.Settings.instance().evaluationDate = today
    
    # 定义期权工具
    option = ql.EuropeanOption(ql.PlainVanillaPayoff(ql.Option.Call, K),
                               ql.EuropeanExercise(expiry))
    
    # 市场参数
    u = ql.SimpleQuote(S)
    r = ql.SimpleQuote(ri)
    sigma = ql.SimpleQuote(v)
    riskFreeCurve = ql.FlatForward(0, ql.TARGET(), ql.QuoteHandle(r), ql.Actual365Fixed())
    volatility = ql.BlackConstantVol(0, ql.TARGET(), ql.QuoteHandle(sigma), ql.Actual365Fixed())
    
    # 定价模型
    process = ql.BlackScholesProcess(ql.QuoteHandle(u), 
                                     ql.YieldTermStructureHandle(riskFreeCurve),
                                     ql.BlackVolTermStructureHandle(volatility))
    
    # 定价引擎
    engine = ql.AnalyticEuropeanEngine(process)
    option.setPricingEngine(engine)
    
    return option.NPV()

# 应用函数计算期权价格
data['call_option_pricing'] = data.apply(compute_option_pricing, axis=1)

偏差原因分析

1. 波动率参数计算错误

这是核心问题:

  • 代码中直接使用data['stock_close'].std() / 100作为波动率,但该数据集仅包含3个不同的分钟级收盘价,计算出的标准差本身极小(约0.5左右),除以100后得到的波动率仅0.005,远低于标普500实际年化波动率(通常在10%-30%之间)。
  • Black-Scholes模型要求输入年化波动率,正确的计算方式应为:
    1. 计算标的资产的收益率序列(如日度收益率:(当日收盘价/昨日收盘价)-1)
    2. 取收益率序列的标准差
    3. 乘以sqrt(252)(年化因子,假设一年252个交易日)得到年化波动率。
      若使用分钟级数据,需乘以sqrt(252*每日交易分钟数)(如美股每日交易390分钟,则sqrt(252*390)≈313)。

2. 波动率样本量不足

仅用3个分钟级价格点计算标准差,完全不具备统计意义,无法反映标的资产的真实波动水平。需要至少数月的历史数据来计算合理的波动率。

3. 潜在的标的类型不匹配

若期权标的是标普500期货而非现货,应使用Black模型而非Black-Scholes模型,但此问题对当前偏差的影响远小于波动率错误。

修正建议

  • 重新计算波动率:获取至少3个月的标普500日度收盘价数据,计算日度收益率的标准差后乘以sqrt(252)得到年化波动率,输入模型时无需除以100(若收益率为小数形式)。
  • 替换波动率来源:若无法获取足够历史数据,可使用期权市场的隐含波动率(可从期权链数据中通过反向推导Black-Scholes模型得到),这是更贴近实际市场的波动率参数。

内容的提问来源于stack exchange,提问作者user113156

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:59:51