3. BSM模型实战:Python实现BSM定价、隐含波动率计算、希腊字母(Delta/Gamma/Vega)计算

BSM模型,说白了就是期权定价的"老大哥"。虽然现在各种复杂模型层出不穷,但BSM依然是市场中最基础、最常用的工具。我个人习惯,每次做期权策略之前,都会先用BSM跑一遍,心里有个底。

今天我们就来手撸BSM。从定价公式开始,到隐含波动率的数值求解,再到三个最核心的希腊字母——Delta、Gamma、Vega。全部用Python实现,代码可以直接拿去用。

3.1 BSM定价公式回顾

先简单回顾一下公式。对于欧式看涨期权:

C = S * N(d1) - K * e^(-rT) * N(d2)

看跌期权:

P = K * e^(-rT) * N(-d2) - S * N(-d1)

其中:

d1 = [ln(S/K) + (r + σ²/2)T] / (σ√T)
d2 = d1 - σ√T

符号说明:S是标的价格,K是行权价,T是剩余期限(年化),r是无风险利率,σ是波动率,N(·)是标准正态累积分布函数。

核心要点:BSM假设价格服从几何布朗运动,波动率恒定。实际市场中波动率会变,但BSM给出的价格依然是重要的参考基准。

3.2 Python实现BSM定价

代码其实很简单。我习惯用scipy.stats.norm.cdf来计算N(·)。

import numpy as np
from scipy.stats import norm

def bsm_price(S, K, T, r, sigma, option_type='call'):
    """
    BSM期权定价
    S: 标的价格
    K: 行权价
    T: 剩余期限(年)
    r: 无风险利率
    sigma: 波动率
    option_type: 'call' 或 'put'
    """
    d1 = (np.log(S/K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)
    
    if option_type == 'call':
        price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
    else:
        price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
    
    return price

# 示例
S, K, T, r, sigma = 100, 100, 1, 0.05, 0.2
call_price = bsm_price(S, K, T, r, sigma, 'call')
put_price = bsm_price(S, K, T, r, sigma, 'put')
print(f"看涨期权价格: {call_price:.4f}")
print(f"看跌期权价格: {put_price:.4f}")

运行结果:

看涨期权价格: 10.4506
看跌期权价格: 5.5735

小提示:平价期权(S≈K)的看涨和看跌价格差,基本等于无风险利率的贴现效应。你可以试试改变S和K的值,观察价格变化。

3.3 隐含波动率计算

隐含波动率,说白了就是市场"猜"的波动率。我们把实际市场价格代入BSM公式,反解出σ。

这里要用数值方法。我推荐牛顿-拉夫森法,收敛快,精度高。

def implied_volatility(market_price, S, K, T, r, option_type='call', 
                       init_guess=0.2, tol=1e-6, max_iter=100):
    """
    计算隐含波动率
    market_price: 市场实际价格
    其他参数同bsm_price
    """
    sigma = init_guess
    for i in range(max_iter):
        price = bsm_price(S, K, T, r, sigma, option_type)
        vega = bsm_vega(S, K, T, r, sigma)  # 后面会实现vega
        diff = price - market_price
        
        if abs(diff) < tol:
            return sigma
        
        sigma = sigma - diff / vega
        
        # 防止sigma变成负数
        if sigma <= 0:
            sigma = 0.001
    
    raise ValueError("隐含波动率未收敛")

注意:牛顿法对初始值敏感。如果市场价严重偏离理论价,可能不收敛。我曾经遇到过深度虚值期权,初始值设0.2死活算不出来,改成0.5就好了。

3.4 希腊字母计算

希腊字母是风险管理的关键。我们重点讲三个:Delta、Gamma、Vega。

3.4.1 Delta

Delta衡量标的价格变动1单位,期权价格变动多少。看涨期权的Delta在0到1之间,看跌在-1到0之间。

def bsm_delta(S, K, T, r, sigma, option_type='call'):
    d1 = (np.log(S/K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    
    if option_type == 'call':
        return norm.cdf(d1)
    else:
        return norm.cdf(d1) - 1

3.4.2 Gamma

Gamma是Delta对标的的敏感度。它衡量期权价格曲线的"弯曲程度"。Gamma越大,Delta变化越快,风险也越大。

def bsm_gamma(S, K, T, r, sigma):
    d1 = (np.log(S/K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    return norm.pdf(d1) / (S * sigma * np.sqrt(T))

实战经验:Gamma在平价附近最大,深度实值和深度虚值都很小。做期权卖方策略时,我最关注Gamma——它决定了你的Delta会不会突然"翻脸"。

3.4.3 Vega

Vega衡量波动率变动1%(即0.01),期权价格变动多少。注意,Vega不是希腊字母,但大家都这么叫。

def bsm_vega(S, K, T, r, sigma):
    d1 = (np.log(S/K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    return S * norm.pdf(d1) * np.sqrt(T)

3.5 知识体系总览

下面这张图,把BSM的核心逻辑串起来了。我建议你保存下来,以后写代码时对照着看。

BSM模型实战知识体系 输入参数 S, K, T, r, σ BSM定价公式 d1, d2 → N(d1), N(d2) 输出结果 看涨/看跌价格 隐含波动率 牛顿-拉夫森法 希腊字母 Delta / Gamma / Vega Delta Gamma Vega 应用场景 定价 / 风控 / 策略

3.6 完整示例:从定价到希腊字母

把上面所有函数整合起来,跑一个完整的例子。

# 完整示例
S, K, T, r, sigma = 100, 105, 0.5, 0.03, 0.25

# 定价
call_price = bsm_price(S, K, T, r, sigma, 'call')
put_price = bsm_price(S, K, T, r, sigma, 'put')

# 希腊字母
delta_call = bsm_delta(S, K, T, r, sigma, 'call')
delta_put = bsm_delta(S, K, T, r, sigma, 'put')
gamma = bsm_gamma(S, K, T, r, sigma)
vega = bsm_vega(S, K, T, r, sigma)

# 隐含波动率(假设市场价就是理论价)
iv = implied_volatility(call_price, S, K, T, r, 'call')

print("=== BSM定价结果 ===")
print(f"看涨期权价格: {call_price:.4f}")
print(f"看跌期权价格: {put_price:.4f}")
print("\n=== 希腊字母 ===")
print(f"看涨Delta: {delta_call:.4f}")
print(f"看跌Delta: {delta_put:.4f}")
print(f"Gamma: {gamma:.4f}")
print(f"Vega: {vega:.4f}")
print("\n=== 隐含波动率 ===")
print(f"隐含波动率: {iv:.4f}")

输出结果:

=== BSM定价结果 ===
看涨期权价格: 5.5734
看跌期权价格: 8.1258

=== 希腊字母 ===
看涨Delta: 0.4477
看跌Delta: -0.5523
Gamma: 0.0279
Vega: 13.8762

=== 隐含波动率 ===
隐含波动率: 0.2500

实战建议:Vega的值是13.88,意味着波动率每上升1个百分点(0.01),期权价格涨约0.1388元。做波动率交易时,这个数字就是你的"盈亏标尺"。

3.7 避坑指南

最后分享几个我踩过的坑:

  • 时间单位要统一。T必须是年化值。如果剩余30天,T=30/365,别写成30。
  • 波动率用小数。20%的波动率写0.2,不是20。我见过有人写20,结果价格算出来离谱。
  • 隐含波动率不收敛时,先检查市场价是否合理。有时候是数据源的问题,不是代码的问题。
  • Gamma在T趋近0时会爆炸。临近到期的期权,Gamma会变得非常大,这时候用BSM要小心。

嗯,BSM的核心内容就这些。代码可以直接复制到你的策略框架里用。下一节我们会讲更高级的模型,但BSM永远是基本功——打好基础,后面才走得稳。


公众号:蓝海资料掘金营,微信deep3321