3、Black-Scholes模型推导:BS模型的假设、微分方程推导、BS公式的解析解
说实话,Black-Scholes模型是期权定价的基石。我当年刚入行时,觉得这玩意儿就是一堆天书公式。后来在实盘项目中吃过亏,才真正理解它背后的逻辑。
今天咱们就把它拆开揉碎了讲。你想想看,一个模型能拿诺贝尔奖,肯定有它的过人之处。但再牛的模型,也有它的适用范围。
3.1 BS模型的假设条件
任何模型都有假设,BS也不例外。这些假设就像房子的地基,地基不稳,房子再漂亮也白搭。
BS模型基于以下假设:
- 市场无摩擦:没有交易成本、没有税收、没有保证金要求
- 连续交易:可以随时买卖,没有交易间隔限制
- 无风险利率恒定:r 是常数,且借贷利率相同
- 标的资产价格服从几何布朗运动:dS = μS dt + σS dW
- 不支付股息:期权有效期内,标的资产无分红
- 无套利机会:市场是有效的
- 欧式期权:只能在到期日行权
我个人习惯:每次用BS模型前,我都会先检查这些假设是否基本满足。比如交易成本高的市场,BS定价就会偏差很大。我曾经在某个新兴市场做期权定价,忽略了流动性问题,结果模型和实际价格差了20%以上。
避坑指南:我曾经犯过一个低级错误——假设波动率是常数。实际上波动率会随时间变化,这就是为什么后来有了随机波动率模型。记住:BS模型是起点,不是终点。
3.2 微分方程推导
好,现在咱们进入核心部分。BS微分方程的推导,说白了就是构建一个无风险组合。
思路是这样的:
- 构建一个包含期权和标的资产的投资组合
- 通过调整头寸,消除随机项(dW)
- 利用无套利原理,得到偏微分方程
具体推导过程:
假设期权价格 V(S,t),标的资产价格 S 满足几何布朗运动:
dS = μS dt + σS dW
根据伊藤引理,期权价格的微分:
dV = (∂V/∂t + μS·∂V/∂S + ½σ²S²·∂²V/∂S²) dt + σS·∂V/∂S dW
构建投资组合 Π = V - Δ·S,其中 Δ = ∂V/∂S:
dΠ = dV - Δ·dS
= (∂V/∂t + ½σ²S²·∂²V/∂S²) dt
你看,随机项 dW 被消除了。这就是对冲的精髓。
根据无套利原理,这个无风险组合的收益率应该等于无风险利率:
dΠ = rΠ dt
代入整理,得到BS微分方程:
∂V/∂t + rS·∂V/∂S + ½σ²S²·∂²V/∂S² - rV = 0
小技巧:推导时我习惯先写出伊藤引理,再消去dW项。很多初学者会卡在伊藤引理这一步,其实你把它当成泰勒展开的随机版本就好理解了。
3.3 BS公式的解析解
有了微分方程,还需要边界条件才能求解。对于欧式看涨期权,边界条件是:
- 到期时:V(S,T) = max(S - K, 0)
- 边界条件:V(0,t) = 0,当 S→∞ 时 V(S,t) → S
通过变量变换和热传导方程求解,得到BS公式:
看涨期权价格 C = S·N(d₁) - K·e^(-rT)·N(d₂)
其中:
d₁ = [ln(S/K) + (r + σ²/2)T] / (σ√T)
d₂ = d₁ - σ√T
N(·) 为标准正态分布的累积分布函数
看跌期权价格可以通过看跌-看涨平价关系得到:
P = K·e^(-rT)·N(-d₂) - S·N(-d₁)
我的经验:实际编码时,N(d₁) 和 N(d₂) 的计算要特别注意精度。我一般用 Abramowitz and Stegun 的近似公式,误差控制在 1e-7 以内。别小看这点误差,在实盘交易中,几厘钱的差异可能意味着盈亏。
3.4 代码实现
理论讲完了,咱们看看代码怎么写。这是我在项目中常用的实现:
import numpy as np
from scipy.stats import norm
def black_scholes(S, K, T, r, sigma, option_type='call'):
"""
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)
elif option_type == 'put':
price = K * np.exp(-r*T) * norm.cdf(-d2) - S * norm.cdf(-d1)
else:
raise ValueError("option_type must be 'call' or 'put'")
return price
# 示例
S = 100 # 当前股价
K = 105 # 行权价
T = 0.5 # 6个月
r = 0.03 # 3% 无风险利率
sigma = 0.2 # 20% 波动率
call_price = black_scholes(S, K, T, r, sigma, 'call')
put_price = black_scholes(S, K, T, r, sigma, 'put')
print(f"看涨期权价格: {call_price:.2f}")
print(f"看跌期权价格: {put_price:.2f}")
避坑指南:我曾经在计算 d1 时忘记除以 σ√T,结果算出来的价格完全不对。调试了整整一个下午才发现。所以我的建议是:写完代码后,先用简单数据手动验算一遍。
3.5 知识体系结构图
下面这张图展示了BS模型的核心逻辑,我画了好几个版本才满意:
3.6 模型局限性
BS模型虽然经典,但局限性也很明显。我在实际项目中深有体会:
| 假设 | 现实情况 | 影响 |
|---|---|---|
| 波动率恒定 | 波动率会变化 | 期权价格被低估或高估 |
| 利率恒定 | 利率会波动 | 长期期权定价偏差大 |
| 无交易成本 | 有买卖价差和佣金 | 实际交易成本需考虑 |
| 连续交易 | 有交易时间限制 | 对冲不完美 |
| 无股息 | 股票会分红 | 需调整模型 |
重要提醒:BS模型不是万能的。我见过太多人把BS公式当成圣杯,结果在实盘中亏得血本无归。记住:模型是工具,不是真理。市场永远比模型复杂。
嗯,BS模型的推导就讲到这里。公式虽然看起来复杂,但核心思想其实很简单——通过构建无风险组合来定价。下次你看到期权报价时,不妨想想背后的BS模型,它到底在假设什么,又忽略了什么。
公众号:蓝海资料掘金营,微信deep3321