01-期权定价 (Option Pricing)
预计学习时间:4-5 小时
难度:⭐⭐⭐⭐⭐(衍生品定价模块中最核心的部分)
核心问题:“花小钱买一个权利”这件事,到底值多少钱?
概述
本节从最直觉的”买菜权”出发,逐步推导到金融工程最经典的 Black-Scholes-Merton 公式。
"期权是什么" → 二叉树 → BSM 公式 → Greeks → 蒙特卡洛 → 随机波动率 → 波动率微笑
一、期权是什么:从买菜权说起
1.1 看涨期权(Call):花小钱买”涨价的权利”
白话解释:
假设你家附近的蔬菜市场,西红柿今天卖 3 块一斤。你跟菜农谈了一个条件:
“我给你 5 毛钱,一个月后你保证以 3 块一斤的价格卖给我 10 斤西红柿。不管到时候市场价多少。”
这就是一个看涨期权(Call Option):
| 期权术语 | 对应买菜的例子 |
|---|---|
| 标的资产(Underlying) | 西红柿 |
| 行权价(Strike) | 3 块/斤 |
| 权利金(Premium) | 5 毛钱 |
| 到期日(Expiration) | 一个月后 |
| 买方(Buyer) | 你 |
| 卖方(Seller/Writer) | 菜农 |
到期时的两种情况:
- 西红柿涨到 5 块:你行权,花 3 块买到市价 5 块的西红柿,净赚 2 块 × 10 斤 - 0.5 = 19.5 块
- 西红柿跌到 2 块:你不行权(凭什么花 3 块买 2 块的东西?),只损失权利金 0.5 块
关键洞察:你的收益是无限的(价格越涨赚越多),但亏损是有限的(最多亏权利金)。
1.2 看跌期权(Put):花小钱买”跌价的权利”
反过来,假设你是个西红柿批发商,怕一个月后西红柿跌价:
“我给你 5 毛钱,一个月后我保证以 3 块一斤的价格卖给你 10 斤西红柿。”
- 西红柿跌到 1 块:你行权,把市价 1 块的西红柿按 3 块卖出去,净赚 2 块 × 10 斤 - 0.5 = 19.5 块
- 西红柿涨到 5 块:你不行权(干嘛把 5 块的东西按 3 块卖?),只损失权利金 0.5 块
1.3 期权的关键要素
| 要素 | 含义 | 示例 |
|---|---|---|
| 标的资产(S) | 期权所依附的资产 | 股票、指数、商品 |
| 行权价(K) | 约定的买卖价格 | K = 100 元 |
| 到期日(T) | 期权的有效期限 | T = 0.5 年 |
| 权利金(C/P) | 买方付出的价格 | C = 5 元 |
| 看涨/看跌 | 买入/卖出的权利 | Call / Put |
| 欧式/美式 | 到期行权/随时行权 | European / American |
1.4 内在价值 vs 时间价值
期权价格 = 内在价值 + 时间价值
内在价值:如果现在立刻行权,你能赚多少钱
| 类型 | 条件 | 内在价值 |
|---|---|---|
| Call | S > K(实值) | S - K |
| Call | S ⇐ K(虚值/平值) | 0 |
| Put | S < K(实值) | K - S |
| Put | S >= K(虚值/平值) | 0 |
时间价值:期权价格 - 内在价值。到期日越远,时间价值越大(因为未来有更多不确定性)。
import numpy as np
import matplotlib.pyplot as plt
# ============================================================
# 演示内在价值 vs 时间价值
# ============================================================
S = np.linspace(50, 150, 200) # 股价范围
K = 100 # 行权价
# 内在价值
call_intrinsic = np.maximum(S - K, 0)
put_intrinsic = np.maximum(K - S, 0)
# 模拟期权总价格(简单近似:内在价值 + 时间价值)
time_value = 10 * np.exp(-0.02 * np.abs(S - K)) # 距行权价越远,时间价值越低
call_price = call_intrinsic + time_value
put_price = put_intrinsic + time_value
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Call
axes[0].plot(S, call_price, 'b-', lw=2, label='期权总价格')
axes[0].plot(S, call_intrinsic, 'r--', lw=1.5, label='内在价值')
axes[0].fill_between(S, call_intrinsic, call_price, alpha=0.2, color='blue', label='时间价值')
axes[0].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[0].set_title('看涨期权(Call):内在价值 vs 时间价值')
axes[0].set_xlabel('标的资产价格 S')
axes[0].set_ylabel('期权价格')
axes[0].legend()
# Put
axes[1].plot(S, put_price, 'b-', lw=2, label='期权总价格')
axes[1].plot(S, put_intrinsic, 'r--', lw=1.5, label='内在价值')
axes[1].fill_between(S, put_intrinsic, put_price, alpha=0.2, color='blue', label='时间价值')
axes[1].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[1].set_title('看跌期权(Put):内在价值 vs 时间价值')
axes[1].set_xlabel('标的资产价格 S')
axes[1].set_ylabel('期权价格')
axes[1].legend()
plt.tight_layout()
plt.show()
print("内在价值 = max(S - K, 0)(Call)或 max(K - S, 0)(Put)")
print("时间价值 = 期权价格 - 内在价值")
print("越接近到期日,时间价值越小(时间衰减/Theta)")1.5 到期收益图
到期时,期权的价值就是其内在价值。这是理解所有期权策略的基础。
import numpy as np
import matplotlib.pyplot as plt
# ============================================================
# 四种基本期权头寸的到期收益
# ============================================================
S = np.linspace(50, 150, 300)
K = 100
premium = 5 # 权利金
# 到期收益
call_payoff_long = np.maximum(S - K, 0) - premium # 买入 Call
call_payoff_short = premium - np.maximum(S - K, 0) # 卖出 Call
put_payoff_long = np.maximum(K - S, 0) - premium # 买入 Put
put_payoff_short = premium - np.maximum(K - S, 0) # 卖出 Put
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 买入 Call
axes[0, 0].plot(S, call_payoff_long, 'b-', lw=2)
axes[0, 0].axhline(y=0, color='black', linewidth=0.5)
axes[0, 0].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[0, 0].set_title('买入 Call(看涨)')
axes[0, 0].set_xlabel('到期时标的价格 S')
axes[0, 0].set_ylabel('收益')
axes[0, 0].text(130, 30, '最大收益:无限', fontsize=10, color='green')
axes[0, 0].text(70, -3, '最大亏损:权利金', fontsize=10, color='red')
# 卖出 Call
axes[0, 1].plot(S, call_payoff_short, 'r-', lw=2)
axes[0, 1].axhline(y=0, color='black', linewidth=0.5)
axes[0, 1].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[0, 1].set_title('卖出 Call(看涨)')
axes[0, 1].set_xlabel('到期时标的价格 S')
axes[0, 1].set_ylabel('收益')
axes[0, 1].text(130, -30, '最大亏损:无限', fontsize=10, color='red')
axes[0, 1].text(70, 3, '最大收益:权利金', fontsize=10, color='green')
# 买入 Put
axes[1, 0].plot(S, put_payoff_long, 'b-', lw=2)
axes[1, 0].axhline(y=0, color='black', linewidth=0.5)
axes[1, 0].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[1, 0].set_title('买入 Put(看跌)')
axes[1, 0].set_xlabel('到期时标的价格 S')
axes[1, 0].set_ylabel('收益')
axes[1, 0].text(60, 35, '最大收益:K - 权利金', fontsize=10, color='green')
axes[1, 0].text(130, -3, '最大亏损:权利金', fontsize=10, color='red')
# 卖出 Put
axes[1, 1].plot(S, put_payoff_short, 'r-', lw=2)
axes[1, 1].axhline(y=0, color='black', linewidth=0.5)
axes[1, 1].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[1, 1].set_title('卖出 Put(看跌)')
axes[1, 1].set_xlabel('到期时标的价格 S')
axes[1, 1].set_ylabel('收益')
axes[1, 1].text(60, -30, '最大亏损:K - 权利金', fontsize=10, color='red')
axes[1, 1].text(130, 3, '最大收益:权利金', fontsize=10, color='green')
plt.tight_layout()
plt.show()1.6 期权 vs 股票 vs 期货
| 维度 | 股票 | 期货 | 期权 |
|---|---|---|---|
| 权利义务 | 买=权利+义务 | 双方都有义务 | 买方=权利,卖方=义务 |
| 最大亏损 | 全部本金 | 理论无限 | 买方=权利金,卖方=理论无限 |
| 最大收益 | 理论无限 | 理论无限 | 买方 Call=无限,Put=K-权利金 |
| 杠杆 | 1:1 | 高杠杆 | 权利金杠杆 |
| 适合用途 | 长期投资 | 对冲/投机 | 保险/杠杆/策略 |
二、二叉树定价法:期权定价的第一步
2.1 单步二叉树:最简单的定价模型
白话解释:假设明天股票只有两种可能——涨 20% 或跌 20%,概率各 50%。那么今天的期权值多少钱?
核心思想:我们不是用真实概率来定价,而是用风险中性概率。通过构造一个无风险组合(股票 + 期权),让这个组合不管涨跌收益都一样,从而反推出期权价格。
CRR(Cox-Ross-Rubinstein)模型:
设 为上涨倍数, 为下跌倍数, 为无风险增长倍数。
风险中性概率:
期权价格:
import numpy as np
# ============================================================
# 单步二叉树定价
# ============================================================
# 参数设置
S0 = 100 # 当前股价
K = 100 # 行权价
T = 1.0 # 到期时间(年)
r = 0.05 # 无风险利率(年化)
u = 1.2 # 上涨因子(涨 20%)
d = 0.8 # 下跌因子(跌 20%)
# 计算风险中性概率
R = np.exp(r * T) # 无风险增长倍数
p = (R - d) / (u - d) # 风险中性概率
print("=" * 50)
print("单步二叉树定价")
print("=" * 50)
print(f"当前股价 S0 = {S0}")
print(f"行权价 K = {K}")
print(f"无风险利率 r = {r:.2%}")
print(f"上涨因子 u = {u}")
print(f"下跌因子 d = {d}")
print(f"无风险增长 R = {R:.4f}")
print(f"风险中性概率 p = {p:.4f}")
print()
# 到期时股票的可能价格
Su = S0 * u # 涨到 120
Sd = S0 * d # 跌到 80
print(f"到期股价: Su = {Su}, Sd = {Sd}")
# 到期时 Call 的收益
Cu = max(Su - K, 0) # 涨了 → 行权获利 20
Cd = max(Sd - K, 0) # 跌了 → 不行权,收益 0
print(f"Call 到期收益: Cu = {Cu}, Cd = {Cd}")
# 定价:用风险中性概率折现
C0 = np.exp(-r * T) * (p * Cu + (1 - p) * Cd)
print(f"Call 价格 = {C0:.4f}")
# 验证:无风险组合
# 组合 = 买入 Delta 股股票 + 卖出 1 份 Call
# Delta = (Cu - Cd) / (Su - Sd)
delta = (Cu - Cd) / (Su - Sd)
print(f"\n对冲比率 Delta = {delta:.4f}")
print(f"验证:买入 {delta:.4f} 股股票,卖出 1 份 Call")
print(f" 涨了: {delta:.4f} × {Su} - {Cu} = {delta * Su - Cu:.4f}")
print(f" 跌了: {delta:.4f} × {Sd} - {Cd} = {delta * Sd - Cd:.4f}")
print(f" 折现: {max(delta * Su - Cu, delta * Sd - Cd):.4f} × e^(-rT) = "
f"{np.exp(-r * T) * (delta * S0 - C0):.4f}")2.2 多步二叉树:更精确的定价
单步二叉树太粗糙了。真实世界中,股价不是只有”涨 20%“和”跌 20%“两种可能。我们可以把时间段分得更细——比如分成 100 步,每步股价只能小幅变动。
CRR 模型的参数选择:
import numpy as np
import matplotlib.pyplot as plt
# ============================================================
# 多步二叉树定价(欧式 Call)
# ============================================================
def binomial_tree_european(S0, K, T, r, sigma, n_steps, option_type='call'):
"""
多步二叉树定价(欧式期权)
参数:
S0: 当前股价
K: 行权价
T: 到期时间(年)
r: 无风险利率
sigma: 波动率(年化)
n_steps: 二叉树步数
option_type: 'call' 或 'put'
返回:
期权价格
"""
dt = T / n_steps
u = np.exp(sigma * np.sqrt(dt)) # 上涨因子
d = np.exp(-sigma * np.sqrt(dt)) # 下跌因子
disc = np.exp(-r * dt) # 折现因子
p = (disc - d) / (u - d) # 风险中性概率
# 到期时各节点的股票价格
S = np.array([S0 * (u ** j) * (d ** (n_steps - j)) for j in range(n_steps + 1)])
# 到期时的期权收益
if option_type == 'call':
V = np.maximum(S - K, 0)
else:
V = np.maximum(K - S, 0)
# 从到期日倒推回今天
for i in range(n_steps - 1, -1, -1):
V = disc * (p * V[1:] + (1 - p) * V[:-1])
return V[0]
# 参数
S0 = 100
K = 100
T = 1.0
r = 0.05
sigma = 0.2
# 比较不同步数的定价结果
steps_list = [1, 5, 10, 25, 50, 100, 200, 500, 1000]
print("欧式 Call 二叉树定价(收敛性)")
print("=" * 50)
print(f"{'步数':>8} {'Call 价格':>12}")
print("-" * 25)
prices = []
for n in steps_list:
price = binomial_tree_european(S0, K, T, r, sigma, n, 'call')
prices.append(price)
print(f"{n:>8} {price:>12.6f}")
# BSM 解析解(作为参考基准)
from scipy.stats import norm
d1 = (np.log(S0 / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
bsm_price = S0 * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
print(f"{'BSM 基准':>8} {bsm_price:>12.6f}")
# 画收敛图
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(steps_list, prices, 'bo-', markersize=5, label='二叉树价格')
ax.axhline(y=bsm_price, color='red', linestyle='--', label=f'BSM 解析解 = {bsm_price:.4f}')
ax.set_xlabel('二叉树步数')
ax.set_ylabel('期权价格')
ax.set_title('二叉树定价收敛到 BSM 解析解')
ax.legend()
ax.set_xscale('log')
plt.tight_layout()
plt.show()2.3 美式期权的二叉树定价
美式期权可以在到期日之前的任何时间行权。在二叉树中,每个节点需要比较”继续持有”和”立刻行权”的收益,取较大值。
import numpy as np
import matplotlib.pyplot as plt
# ============================================================
# 多步二叉树定价(美式期权)
# ============================================================
def binomial_tree_american(S0, K, T, r, sigma, n_steps, option_type='call'):
"""
多步二叉树定价(美式期权)
美式期权的特殊之处:每个节点都要检查"提前行权是否更划算"
"""
dt = T / n_steps
u = np.exp(sigma * np.sqrt(dt))
d = np.exp(-sigma * np.sqrt(dt))
disc = np.exp(-r * dt)
p = (disc - d) / (u - d)
# 构建完整的二叉树(用二维数组存储每个节点的股票价格和期权价值)
# S[i][j] = 第 i 步、第 j 个节点的股票价格(j 从 0 到 i)
S = np.zeros((n_steps + 1, n_steps + 1))
V = np.zeros((n_steps + 1, n_steps + 1))
# 初始化股票价格树
for i in range(n_steps + 1):
for j in range(i + 1):
S[i][j] = S0 * (u ** j) * (d ** (i - j))
# 到期时的期权收益
for j in range(n_steps + 1):
if option_type == 'call':
V[n_steps][j] = max(S[n_steps][j] - K, 0)
else:
V[n_steps][j] = max(K - S[n_steps][j], 0)
# 从到期日倒推
for i in range(n_steps - 1, -1, -1):
for j in range(i + 1):
# 继续持有的价值(用风险中性概率折现)
continuation = disc * (p * V[i + 1][j + 1] + (1 - p) * V[i + 1][j])
# 立刻行权的价值
if option_type == 'call':
exercise = max(S[i][j] - K, 0)
else:
exercise = max(K - S[i][j], 0)
# 取较大值(美式期权的特征)
V[i][j] = max(continuation, exercise)
return V[0][0]
# 对比欧式和美式 Put
S0, K, T, r, sigma = 100, 100, 1.0, 0.05, 0.2
n_steps = 500
european_put = binomial_tree_european(S0, K, T, r, sigma, n_steps, 'put')
american_put = binomial_tree_american(S0, K, T, r, sigma, n_steps, 'put')
print("=" * 50)
print("欧式 Put vs 美式 Put(S0=100, K=100, T=1年, r=5%, sigma=20%)")
print("=" * 50)
print(f"欧式 Put 价格: {european_put:.4f}")
print(f"美式 Put 价格: {american_put:.4f}")
print(f"提前行权溢价: {american_put - european_put:.4f}")
print()
print("注意:美式 Call 在无股息情况下提前行权不会更有利,")
print("但美式 Put 在股价大幅低于行权价时,提前行权可能更划算。")
# 不同股价下的欧式/美式 Put 价格对比
S_range = np.linspace(60, 140, 20)
euro_puts = [binomial_tree_european(s, K, T, r, sigma, 200, 'put') for s in S_range]
amer_puts = [binomial_tree_american(s, K, T, r, sigma, 200, 'put') for s in S_range]
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(S_range, euro_puts, 'b-', lw=2, label='欧式 Put')
ax.plot(S_range, amer_puts, 'r--', lw=2, label='美式 Put')
ax.fill_between(S_range, euro_puts, amer_puts, alpha=0.2, color='red',
label='提前行权溢价')
ax.axvline(x=K, color='gray', linestyle=':', alpha=0.5)
ax.set_xlabel('股票价格 S')
ax.set_ylabel('Put 价格')
ax.set_title('欧式 Put vs 美式 Put:提前行权溢价')
ax.legend()
plt.tight_layout()
plt.show()三、Black-Scholes-Merton 公式
3.1 从二叉树到连续时间
上面的二叉树定价有一个有趣的现象:当步数越来越多时,价格收敛到一个固定的值。这个极限值就是 BSM 公式的结果。
直觉理解:如果我们在极短的时间 内,让股价只能做微小的变动(),那么在连续时间极限下,股价服从几何布朗运动(GBM)。在这个框架下,通过”连续调整 Delta 对冲”,可以构造一个完美的无风险组合,从而推导出期权价格。
3.2 BSM 公式
在看之前,先理解它在说什么:
BSM 公式回答的是:在给定当前股价、行权价、到期时间、波动率、无风险利率的前提下,一个欧式期权的”公平价格”是多少。
欧式 Call 价格:
欧式 Put 价格:
其中:
白话解读每个变量的含义:
| 变量 | 含义 | 直觉 |
|---|---|---|
| 当前股价 | 股价越高,Call 越值钱 | |
| 行权价 | 行权价越低,Call 越值钱 | |
| 无风险利率 | 利率越高,折现越少,Call 越值钱 | |
| 到期时间 | 时间越长,期权越值钱(不确定性更大) | |
| 波动率 | 波动率越大,期权越值钱(大涨大跌都好) | |
| Delta | ”股价涨 1 元,期权涨多少”的概率权重 | |
| 行权概率 | ”到期时股价超过行权价”的风险中性概率 |
3.3 BSM 公式的假设
| 假设 | 含义 | 现实中的问题 |
|---|---|---|
| 无摩擦市场 | 没有交易成本、没有税收 | 真实交易有成本 |
| 连续交易 | 可以随时买卖、调整仓位 | 真实交易有最小价格变动 |
| 对数正态分布 | 股价收益率服从正态分布 | 真实分布有厚尾和偏斜 |
| 常数波动率 | 波动率不随时间和股价变化 | 波动率微笑说明这不是真的 |
| 无风险利率常数 | 利率不变 | 利率也是随机的 |
| 无股息(或连续股息) | 不考虑分红 | 很多股票有分红 |
这些假设中,常数波动率是最被诟病的。这直接导致了”波动率微笑”问题(后面会讲)。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# ============================================================
# BSM 公式实现
# ============================================================
def bsm_call(S, K, T, r, sigma):
"""欧式看涨期权 BSM 价格"""
d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
return S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
def bsm_put(S, K, T, r, sigma):
"""欧式看跌期权 BSM 价格"""
d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
return K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
# 参数
S0 = 100
K = 100
T = 1.0
r = 0.05
sigma = 0.2
call_price = bsm_call(S0, K, T, r, sigma)
put_price = bsm_put(S0, K, T, r, sigma)
print("BSM 定价结果")
print("=" * 40)
print(f"参数: S0={S0}, K={K}, T={T}, r={r:.2%}, sigma={sigma:.2%}")
print(f"欧式 Call 价格: {call_price:.4f}")
print(f"欧式 Put 价格: {put_price:.4f}")
print(f"Put-Call Parity 验证:")
print(f" C - P = {call_price - put_price:.4f}")
print(f" S - K*e^(-rT) = {S0 - K * np.exp(-r * T):.4f}")
print(f" 两者应该相等(Put-Call Parity)")
# 期权价格随各参数的变化
fig, axes = plt.subplots(2, 3, figsize=(16, 10))
# 1. 随股价变化
S_range = np.linspace(50, 150, 200)
axes[0, 0].plot(S_range, bsm_call(S_range, K, T, r, sigma), 'b-', lw=2, label='Call')
axes[0, 0].plot(S_range, bsm_put(S_range, K, T, r, sigma), 'r-', lw=2, label='Put')
axes[0, 0].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[0, 0].set_title('期权价格 vs 股价')
axes[0, 0].set_xlabel('股价 S')
axes[0, 0].legend()
# 2. 随行权价变化
K_range = np.linspace(50, 150, 200)
axes[0, 1].plot(K_range, bsm_call(S0, K_range, T, r, sigma), 'b-', lw=2, label='Call')
axes[0, 1].plot(K_range, bsm_put(S0, K_range, T, r, sigma), 'r-', lw=2, label='Put')
axes[0, 1].axvline(x=S0, color='gray', linestyle=':', alpha=0.5)
axes[0, 1].set_title('期权价格 vs 行权价')
axes[0, 1].set_xlabel('行权价 K')
axes[0, 1].legend()
# 3. 随波动率变化
sigma_range = np.linspace(0.05, 0.5, 200)
axes[0, 2].plot(sigma_range, bsm_call(S0, K, T, r, sigma_range), 'b-', lw=2, label='Call')
axes[0, 2].plot(sigma_range, bsm_put(S0, K, T, r, sigma_range), 'r-', lw=2, label='Put')
axes[0, 2].set_title('期权价格 vs 波动率')
axes[0, 2].set_xlabel('波动率 sigma')
axes[0, 2].legend()
# 4. 随到期时间变化
T_range = np.linspace(0.01, 3, 200)
axes[1, 0].plot(T_range, bsm_call(S0, K, T_range, r, sigma), 'b-', lw=2, label='Call')
axes[1, 0].plot(T_range, bsm_put(S0, K, T_range, r, sigma), 'r-', lw=2, label='Put')
axes[1, 0].set_title('期权价格 vs 到期时间')
axes[1, 0].set_xlabel('到期时间 T(年)')
axes[1, 0].legend()
# 5. 随利率变化
r_range = np.linspace(0, 0.1, 200)
axes[1, 1].plot(r_range, bsm_call(S0, K, T, r_range, sigma), 'b-', lw=2, label='Call')
axes[1, 1].plot(r_range, bsm_put(S0, K, T, r_range, sigma), 'r-', lw=2, label='Put')
axes[1, 1].set_title('期权价格 vs 无风险利率')
axes[1, 1].set_xlabel('利率 r')
axes[1, 1].legend()
# 6. 随波动率和到期时间的变化(热力图)
sigma_grid = np.linspace(0.05, 0.5, 50)
T_grid = np.linspace(0.01, 3, 50)
SS, TT = np.meshgrid(sigma_grid, T_grid)
CC = bsm_call(S0, K, TT, r, SS)
im = axes[1, 2].contourf(SS, TT, CC, levels=20, cmap='viridis')
plt.colorbar(im, ax=axes[1, 2])
axes[1, 2].set_title('Call 价格热力图(波动率 vs 到期时间)')
axes[1, 2].set_xlabel('波动率 sigma')
axes[1, 2].set_ylabel('到期时间 T')
plt.tight_layout()
plt.show()3.4 Put-Call Parity(看涨-看跌平价)
这是一个不需要任何模型假设的恒等式,是期权定价中最基本的无套利关系:
白话解读:买入 Call + 卖出 Put 的效果,等于持有股票 + 借钱(金额等于 )。
如果这个等式不成立,就存在套利机会。这是检验任何定价模型正确性的第一道关卡。
四、Greeks:期权价格的敏感度分析
4.1 什么是 Greeks
期权价格受多个因素影响。Greeks 描述的是:当某个因素变化一个微小单位时,期权价格变化多少。
这就像开车时的仪表盘——Delta 告诉你速度,Gamma 告诉你加速度,Theta 告诉你时间在流逝。
4.2 五个核心 Greeks
| Greek | 数学定义 | 白话解释 |
|---|---|---|
| Delta () | 股价涨 1 元,期权价格涨多少 | |
| Gamma () | 股价涨 1 元,Delta 变化多少(Delta 的加速度) | |
| Vega () | 波动率涨 1%,期权价格涨多少 | |
| Theta () | 过了一天,期权价格跌多少(时间衰减) | |
| Rho () | 利率涨 1%,期权价格涨多少 |
Delta 的直觉:
- Call 的 Delta 在 0 到 1 之间。股价越高,Delta 越接近 1(几乎确定行权)
- Put 的 Delta 在 -1 到 0 之间。股价越低,Delta 越接近 -1
- ATM 期权的 Delta 大约是 0.5(Call)或 -0.5(Put)
- Delta 也是”对冲比率”——卖 1 份 Call 需要买入 Delta 份股票来对冲
Gamma 的直觉:
- Gamma 衡量 Delta 对股价的敏感度
- Gamma 越大,说明 Delta 变化越快,对冲需要更频繁地调整
- ATM 期权的 Gamma 最大
Theta 的直觉:
- 期权买方每天”损失” Theta(时间流逝对买方不利)
- 期权卖方每天”赚取” Theta(时间流逝对卖方有利)
- 接近到期日时,Theta 衰减加速
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# ============================================================
# BSM Greeks 计算
# ============================================================
def bsm_greeks(S, K, T, r, sigma, option_type='call'):
"""
计算所有 BSM Greeks
返回: dict,包含 delta, gamma, vega, theta, rho
"""
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':
delta = norm.cdf(d1)
theta = (-S * norm.pdf(d1) * sigma / (2 * np.sqrt(T))
- r * K * np.exp(-r * T) * norm.cdf(d2))
else:
delta = norm.cdf(d1) - 1
theta = (-S * norm.pdf(d1) * sigma / (2 * np.sqrt(T))
+ r * K * np.exp(-r * T) * norm.cdf(-d2))
gamma = norm.pdf(d1) / (S * sigma * np.sqrt(T))
vega = S * norm.pdf(d1) * np.sqrt(T) # 注意:vega 是对 sigma 的导数,通常除以 100
rho = K * T * np.exp(-r * T) * norm.cdf(d2) if option_type == 'call' \
else -K * T * np.exp(-r * T) * norm.cdf(-d2)
return {
'delta': delta,
'gamma': gamma,
'vega': vega / 100, # 转换为"波动率变化 1%"的影响
'theta': theta / 365, # 转换为"每天的时间衰减"
'rho': rho / 100 # 转换为"利率变化 1%"的影响
}
# 参数
S0, K, T, r, sigma = 100, 100, 1.0, 0.05, 0.2
greeks = bsm_greeks(S0, K, T, r, sigma, 'call')
print("BSM Greeks(欧式 Call)")
print("=" * 50)
print(f"参数: S={S0}, K={K}, T={T}年, r={r:.2%}, sigma={sigma:.2%}")
for name, value in greeks.items():
print(f" {name:>6} = {value:>10.4f}")
print("\n白话解释:")
print(f" Delta = {greeks['delta']:.4f} → 股价涨 1 元,Call 涨约 {greeks['delta']:.2f} 元")
print(f" Gamma = {greeks['gamma']:.4f} → Delta 的变化速度")
print(f" Vega = {greeks['vega']:.4f} → 波动率涨 1%,Call 涨约 {greeks['vega']:.2f} 元")
print(f" Theta = {greeks['theta']:.4f} → 每天时间衰减约 {abs(greeks['theta']):.2f} 元")
print(f" Rho = {greeks['rho']:.4f} → 利率涨 1%,Call 涨约 {greeks['rho']:.2f} 元")
# Greeks 随股价变化图
S_range = np.linspace(50, 150, 200)
greeks_vs_S = {name: [] for name in ['delta', 'gamma', 'vega', 'theta']}
for s in S_range:
g = bsm_greeks(s, K, T, r, sigma, 'call')
for name in greeks_vs_S:
greeks_vs_S[name].append(g[name])
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].plot(S_range, greeks_vs_S['delta'], 'b-', lw=2)
axes[0, 0].axhline(y=0, color='gray', linewidth=0.5)
axes[0, 0].axhline(y=1, color='gray', linestyle=':', alpha=0.3)
axes[0, 0].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[0, 0].set_title('Delta vs 股价')
axes[0, 0].set_ylabel('Delta')
axes[0, 1].plot(S_range, greeks_vs_S['gamma'], 'r-', lw=2)
axes[0, 1].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[0, 1].set_title('Gamma vs 股价')
axes[0, 1].set_ylabel('Gamma')
axes[1, 0].plot(S_range, greeks_vs_S['vega'], 'g-', lw=2)
axes[1, 0].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[1, 0].set_title('Vega vs 股价')
axes[1, 0].set_ylabel('Vega')
axes[1, 1].plot(S_range, greeks_vs_S['theta'], 'm-', lw=2)
axes[1, 1].axhline(y=0, color='gray', linewidth=0.5)
axes[1, 1].axvline(x=K, color='gray', linestyle=':', alpha=0.5)
axes[1, 1].set_title('Theta vs 股价(每天的时间衰减)')
axes[1, 1].set_ylabel('Theta')
for ax in axes.flat:
ax.set_xlabel('股价 S')
plt.tight_layout()
plt.show()4.3 PDE 视角(简要)
BSM 公式可以看作一个偏微分方程(PDE)的解:
用 Greeks 的语言重新写:
白话解读:时间衰减(Theta 损失)= Gamma 获益 + Delta 获益 - 利息成本。
这意味着:对于 Delta 中性的组合(Delta = 0),Theta 损失由 Gamma 获益来补偿。这是一个做市商每天都在运用的核心关系。
五、蒙特卡洛定价
5.1 原理:模拟大量路径,取期望折现
白话解释:既然我们不知道未来股价会怎么走,那就用计算机模拟 100 万条可能的路径,看看每条路径上期权到期时值多少钱,取平均值,然后折现到现在。
数学表达:
其中 是到期时的股价, 是在风险中性测度下的期望。
在 GBM 模型下, 可以通过以下方式模拟:
注意:漂移率用的是 (无风险利率),而不是真实的期望收益率——这就是”风险中性定价”。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
import time
# ============================================================
# 蒙特卡洛期权定价
# ============================================================
def monte_carlo_call(S0, K, T, r, sigma, n_sims=100000):
"""
蒙特卡洛法定价欧式 Call
原理:模拟大量到期时的股价,取收益的期望然后折现
"""
# 在风险中性测度下模拟到期股价
Z = np.random.standard_normal(n_sims) # 标准正态随机数
ST = S0 * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * Z)
# 到期收益
payoff = np.maximum(ST - K, 0)
# 折现取平均
price = np.exp(-r * T) * np.mean(payoff)
# 标准误差
std_error = np.exp(-r * T) * np.std(payoff) / np.sqrt(n_sims)
return price, std_error
# 参数
S0, K, T, r, sigma = 100, 100, 1.0, 0.05, 0.2
# BSM 基准
d1 = (np.log(S0 / K) + (r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
bsm_price = S0 * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
print("蒙特卡洛定价 vs BSM 解析解")
print("=" * 50)
print(f"BSM 解析解: {bsm_price:.6f}")
print()
for n_sims in [1000, 10000, 100000, 500000, 1000000]:
price, se = monte_carlo_call(S0, K, T, r, sigma, n_sims)
error = abs(price - bsm_price)
print(f"模拟 {n_sims:>10,} 次: MC={price:.6f}, "
f"误差={error:.6f}, 标准误差={se:.6f}")
# 模拟股价路径的可视化
np.random.seed(42)
n_paths = 50
n_steps = 252
dt = T / n_steps
t = np.linspace(0, T, n_steps + 1)
# 路径模拟
Z = np.random.standard_normal((n_steps, n_paths))
S = np.zeros((n_steps + 1, n_paths))
S[0] = S0
for i in range(n_steps):
S[i + 1] = S[i] * np.exp((r - 0.5 * sigma**2) * dt
+ sigma * np.sqrt(dt) * Z[i])
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(t, S[:, :20], alpha=0.5, lw=0.8) # 画前 20 条路径
ax.axhline(y=K, color='red', linestyle='--', lw=1.5, label=f'行权价 K={K}')
ax.axhline(y=S0, color='gray', linestyle=':', alpha=0.5, label=f'当前价 S0={S0}')
ax.set_xlabel('时间(年)')
ax.set_ylabel('股价')
ax.set_title('蒙特卡洛模拟:50 条股价路径')
ax.legend()
plt.tight_layout()
plt.show()5.2 方差缩减技术
朴素蒙特卡洛的收敛速度是 ,即精度提高 10 倍需要模拟次数增加 100 倍。方差缩减技术可以用同样的模拟次数获得更精确的结果。
对偶变量法(Antithetic Variates):
利用正态分布的对称性,对每个随机数 ,同时使用 来模拟。正负路径的平均结果方差更小。
控制变量法(Control Variates):
利用一个已知解析解的”相似”问题来修正估计。比如用远期合约 作为控制变量。
import numpy as np
# ============================================================
# 方差缩减技术
# ============================================================
def mc_antithetic(S0, K, T, r, sigma, n_sims=100000):
"""对偶变量法:利用正态分布对称性减半方差"""
Z = np.random.standard_normal(n_sims // 2)
# 正路径和负路径
ST_plus = S0 * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * Z)
ST_minus = S0 * np.exp((r - 0.5 * sigma**2) * T - sigma * np.sqrt(T) * Z)
payoff_plus = np.maximum(ST_plus - K, 0)
payoff_minus = np.maximum(ST_minus - K, 0)
price = np.exp(-r * T) * np.mean((payoff_plus + payoff_minus) / 2)
std_error = np.exp(-r * T) * np.std((payoff_plus + payoff_minus) / 2) / np.sqrt(n_sims // 2)
return price, std_error
def mc_control_variate(S0, K, T, r, sigma, n_sims=100000):
"""控制变量法:用远期合约作为控制变量"""
Z = np.random.standard_normal(n_sims)
ST = S0 * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * Z)
payoff = np.maximum(ST - K, 0)
# 控制变量:到期股价(期望 = S0 * e^(rT))
cv = ST
# 修正系数
cov_matrix = np.cov(payoff, cv)
beta = cov_matrix[0, 1] / cov_matrix[1, 1]
# 修正后的价格
mc_price = np.exp(-r * T) * np.mean(payoff)
cv_mean = np.mean(cv)
cv_expected = S0 * np.exp(r * T)
adjusted_price = mc_price - beta * np.exp(-r * T) * (cv_mean - cv_expected)
return adjusted_price
# 对比三种方法
n_sims = 100000
bsm_price = 10.4506 # 已知的 BSM 解析解
naive_price, naive_se = monte_carlo_call(S0, K, T, r, sigma, n_sims)
anti_price, anti_se = mc_antithetic(S0, K, T, r, sigma, n_sims)
cv_price = mc_control_variate(S0, K, T, r, sigma, n_sims)
print("方差缩减技术对比")
print("=" * 60)
print(f"BSM 解析解: {bsm_price:.6f}")
print(f"朴素 MC: {naive_price:.6f} (标准误差: {naive_se:.6f})")
print(f"对偶变量法: {anti_price:.6f} (标准误差: {anti_se:.6f})")
print(f"控制变量法: {cv_price:.6f}")
print(f"\n对偶变量法标准误差降低: {(1 - anti_se/naive_se)*100:.1f}%")六、随机波动率模型
6.1 为什么需要随机波动率
BSM 假设波动率是常数,但现实中的波动率是随时间变化的——有时候市场风平浪静,有时候剧烈波动。
BSM 的致命矛盾:如果用 BSM 公式反推不同行权价期权的波动率,你会发现得到的不是同一个常数,而是行权价越偏离 ATM,波动率越高。这个现象叫波动率微笑。
这说明 BSM 的”常数波动率”假设是有问题的。
6.2 Heston 模型
白话解释:股价的波动率不是一个固定值,而是随时间随机变化的,且有自己的均值回归特性。
Heston 模型由两个 SDE 组成:
| 参数 | 含义 | 典型值 |
|---|---|---|
| 波动率的回归速度 | 2-5 | |
| 波动率的长期均值 | 0.04 (即 20% 年化波动率) | |
| 波动率本身的波动率(vol of vol) | 0.3-0.5 | |
| 股价和波动率的相关系数 | -0.5 到 -0.8 | |
| 当前波动率 | 0.04 |
的直觉:股价暴跌时,波动率往往飙升(恐慌)。 捕捉的就是这个”杠杆效应”。
import numpy as np
import matplotlib.pyplot as plt
# ============================================================
# Heston 模型模拟(Euler-Maruyama 离散化)
# ============================================================
def simulate_heston(S0, v0, r, kappa, theta, xi, rho, T, n_steps, n_paths):
"""
Heston 模型路径模拟
参数:
S0: 初始股价
v0: 初始波动率方差 (v = sigma^2)
r: 无风险利率
kappa: 波动率均值回归速度
theta: 波动率长期均值
xi: 波动率的波动率 (vol of vol)
rho: 股价和波动率的相关系数
T: 到期时间
n_steps: 时间步数
n_paths: 模拟路径数
"""
dt = T / n_steps
# 预生成相关随机数
Z1 = np.random.standard_normal((n_steps, n_paths))
Z2 = np.random.standard_normal((n_steps, n_paths))
# 构造相关随机数: W_v = rho * W_S + sqrt(1-rho^2) * Z_independent
W_S = Z1
W_v = rho * Z1 + np.sqrt(1 - rho**2) * Z2
# 初始化路径
S = np.zeros((n_steps + 1, n_paths))
v = np.zeros((n_steps + 1, n_paths))
S[0] = S0
v[0] = v0
# Euler-Maruyama 离散化
for i in range(n_steps):
sqrt_v = np.sqrt(np.maximum(v[i], 0)) # 确保方差非负
S[i + 1] = S[i] * np.exp((r - 0.5 * v[i]) * dt
+ sqrt_v * np.sqrt(dt) * W_S[i])
v[i + 1] = v[i] + kappa * (theta - v[i]) * dt
+ xi * sqrt_v * np.sqrt(dt) * W_v[i]
# Feller 条件: 确保方差不会变成负数
v[i + 1] = np.maximum(v[i + 1], 0)
return S, v
# 参数设置
S0 = 100
v0 = 0.04 # 初始方差 = 0.04,即 sigma = 20%
r = 0.05
kappa = 3.0 # 均值回归速度
theta = 0.04 # 长期方差
xi = 0.5 # vol of vol
rho = -0.7 # 负相关(杠杆效应)
T = 1.0
n_steps = 252
n_paths = 5
np.random.seed(42)
S, v = simulate_heston(S0, v0, r, kappa, theta, xi, rho, T, n_steps, n_paths)
# 可视化
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True)
# 股价路径
for i in range(n_paths):
ax1.plot(np.linspace(0, T, n_steps + 1), S[:, i], alpha=0.7, lw=1)
ax1.set_ylabel('股价 S')
ax1.set_title('Heston 模型:股价路径(波动率随机变化)')
# 波动率路径
for i in range(n_paths):
ax2.plot(np.linspace(0, T, n_steps + 1), np.sqrt(v[:, i]), alpha=0.7, lw=1)
ax2.axhline(y=np.sqrt(theta), color='red', linestyle='--', label=f'长期波动率 sqrt(theta)={np.sqrt(theta):.2f}')
ax2.set_xlabel('时间(年)')
ax2.set_ylabel('波动率 sigma')
ax2.set_title('Heston 模型:波动率路径(均值回归)')
ax2.legend()
plt.tight_layout()
plt.show()
print("Heston 模型参数:")
print(f" kappa = {kappa} (波动率回归速度)")
print(f" theta = {theta} (波动率长期均值)")
print(f" xi = {xi} (波动率的波动率)")
print(f" rho = {rho} (股价-波动率相关系数)")
print(f"\n关键特征:")
print(f" rho < 0 → 股价跌时波动率升(恐慌效应)")
print(f" kappa > 0 → 波动率会回归到长期均值 theta")6.3 局部波动率模型(Dupire)
直觉:波动率不是固定的,也不是随机过程,而是股价的函数。不同股价水平对应不同的波动率。
Dupire 公式可以从期权市场价格反推出局部波动率曲面:
白话解读:给定市场上所有行权价和到期日的期权价格,你可以反推出”在股价为 K、时间为 T 时,波动率应该是多少”。这个局部波动率曲面能完美匹配市场的期权价格。
七、波动率微笑与曲面
7.1 BSM 的矛盾:隐含波动率不是常数
隐含波动率(Implied Volatility, IV):给定期权的市场价格,用 BSM 公式反推出来的波动率。
如果 BSM 的”常数波动率”假设是对的,那么同一个标的、同一到期日的所有期权,不管行权价是多少,反推出来的隐含波动率应该都一样。
但现实不是这样。
7.2 波动率微笑
把不同行权价的隐含波动率画出来,你看到的不是一个水平线,而是一条”微笑”曲线:
- 股票市场:通常呈现” smirk”(偏斜)——低行权价的 IV 高,高行权价的 IV 低。这叫”波动率偏斜(volatility skew)”。
- 外汇市场:更接近对称的”微笑”形状。
为什么会有 skew?
- 杠杆效应:股价暴跌时,公司杠杆上升,风险增大,波动率上升
- 恐慌需求:暴跌时投资者争相买入看跌期权作为保险,推高 Put 的价格(从而推高 IV)
- 尾部风险:暴跌的概率比正态分布预测的要大
7.3 波动率曲面
把不同到期日和行权价的隐含波动率放在一个 3D 图中,就是波动率曲面。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# ============================================================
# 模拟波动率微笑和曲面
# ============================================================
def implied_vol_from_price(S, K, T, r, market_price, option_type='call'):
"""
从市场价格反推隐含波动率(牛顿法)
"""
# 初始猜测
sigma = 0.3
for _ in range(100):
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)
vega = S * norm.pdf(d1) * np.sqrt(T)
else:
price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
vega = S * norm.pdf(d1) * np.sqrt(T)
diff = price - market_price
if abs(diff) < 1e-8:
break
# 牛顿法更新
sigma = sigma - diff / vega
return sigma
# 模拟市场隐含波动率曲面(带有典型的 skew 结构)
S0 = 100
r = 0.05
strikes = np.linspace(70, 130, 25) # 行权价范围
maturities = np.linspace(0.1, 2.0, 20) # 到期时间范围
# 构造模拟的隐含波动率曲面
# 使用一个简单的参数化模型:IV(K, T) = sigma_0 + a * (K/S - 1) / sqrt(T) + b * (K/S - 1)^2
sigma_0 = 0.20 # ATM 波动率
a = -0.15 # skew 参数(负值表示低行权价 IV 高)
b = 0.10 # 曲率参数
iv_surface = np.zeros((len(maturities), len(strikes)))
for i, T in enumerate(maturities):
for j, K in enumerate(strikes):
moneyness = K / S0
iv_surface[i, j] = sigma_0 + a * (moneyness - 1) / np.sqrt(T) + b * (moneyness - 1)**2
iv_surface[i, j] = max(iv_surface[i, j], 0.05) # 确保 IV > 0
# 可视化
fig = plt.figure(figsize=(14, 6))
# 左图:波动率微笑(不同到期日的切片)
ax1 = fig.add_subplot(121)
T_slices = [0.1, 0.5, 1.0, 2.0]
colors = ['red', 'blue', 'green', 'purple']
for T_val, color in zip(T_slices, colors):
idx = np.argmin(np.abs(maturities - T_val))
ax1.plot(strikes, iv_surface[idx, :], color=color, lw=2, label=f'T={T_val}年')
ax1.axvline(x=S0, color='gray', linestyle=':', alpha=0.5, label='ATM (K=S)')
ax1.set_xlabel('行权价 K')
ax1.set_ylabel('隐含波动率')
ax1.set_title('波动率微笑(不同到期日)')
ax1.legend()
# 右图:波动率曲面(3D)
ax2 = fig.add_subplot(122, projection='3d')
K_grid, T_grid = np.meshgrid(strikes, maturities)
ax2.plot_surface(K_grid, T_grid, iv_surface, cmap='viridis', alpha=0.8)
ax2.set_xlabel('行权价 K')
ax2.set_ylabel('到期时间 T')
ax2.set_zlabel('隐含波动率')
ax2.set_title('波动率曲面')
plt.tight_layout()
plt.show()
# 展示隐含波动率反推过程
print("=" * 50)
print("隐含波动率反推示例")
print("=" * 50)
# 用 BSM 在 sigma=0.20 算出"真实"价格
d1 = (np.log(S0 / 100) + (r + 0.5 * 0.20**2) * 1.0) / (0.20 * np.sqrt(1.0))
d2 = d1 - 0.20 * np.sqrt(1.0)
true_price = S0 * norm.cdf(d1) - 100 * np.exp(-r * 1.0) * norm.cdf(d2)
# 反推隐含波动率
iv = implied_vol_from_price(S0, 100, 1.0, r, true_price, 'call')
print(f"BSM 价格(sigma=0.20)= {true_price:.4f}")
print(f"反推隐含波动率 = {iv:.6f}(应该等于 0.20)")7.4 波动率曲面的交易意义
| 现象 | 含义 | 交易策略 |
|---|---|---|
| Skew(低 K 的 IV 高) | 市场认为暴跌风险大 | 买入 Put spread |
| Smile(两端 IV 高) | 市场认为极端行情概率大 | 买入 Straddle |
| 曲面倾斜变化 | 市场风险预期在变化 | 日历价差 |
| ATM IV 上升 | 市场整体恐慌增加 | 卖出期权 |
八、关键概念回顾
| 概念 | 一句话解释 |
|---|---|
| 期权 | 花小钱买一个”在未来以约定价格买卖的权利” |
| BSM 公式 | 在常数波动率假设下,欧式期权的解析定价公式 |
| Delta | 股价涨 1 元,期权涨多少 |
| Gamma | Delta 的变化速度,衡量对冲频率 |
| Theta | 每天的时间价值衰减 |
| Vega | 波动率涨 1%,期权涨多少 |
| 隐含波动率 | 从市场价格反推出的波动率 |
| 波动率微笑 | 不同行权价的隐含波动率不同 |
| Heston 模型 | 波动率本身也是随机过程的定价模型 |
| 蒙特卡洛 | 通过模拟大量路径来估计期权价格 |
推荐阅读
| 书名 | 章节 | 核心价值 |
|---|---|---|
| Options, Futures, and Other Derivatives (Hull) | Ch.13-15, 19-21 | BSM、Greeks、波动率微笑的权威参考 |
| The Concepts and Practice of Mathematical Finance (Joshi) | Ch.6-12 | 直觉解释和实现细节 |
| Stochastic Calculus for Finance II (Shreve) | Ch.5-8 | 严格数学推导 |
版本信息
- 创建日期:2026-03-28
- 最后更新:2026-03-28