1. 期权定价模型实现与比较
任务目标
实现Black-Scholes、二叉树和蒙特卡洛三种欧式看涨期权定价模型,在给定相同参数下比较定价结果与计算耗时,验证三种模型收敛于同一理论价值。
环境依赖
仅需Python 3.8+标准库(math、random、time),无需第三方库。随机数使用固定种子保证可复现。
完整实现
import math
import random
import time
# ---------- 公共参数 ----------
S0 = 100.0 # 标的现价
K = 105.0 # 行权价
T = 1.0 # 到期时间(年)
r = 0.05 # 无风险利率
sigma = 0.20 # 波动率
N_BIN = 500 # 二叉树步数
N_MC = 100000 # 蒙特卡洛路径数
SEED = 42
# ---------- 1. Black-Scholes 解析解 ----------
def bs_call(S0, K, T, r, sigma):
d1 = (math.log(S0 / K) + (r + 0.5 * sigma**2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
# 标准正态分布CDF(数值近似)
def norm_cdf(x):
return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0)))
return S0 * norm_cdf(d1) - K * math.exp(-r * T) * norm_cdf(d2)
# ---------- 2. 二叉树模型(CRR) ----------
def binomial_call(S0, K, T, r, sigma, N):
dt = T / N
u = math.exp(sigma * math.sqrt(dt))
d = 1.0 / u
p = (math.exp(r * dt) - d) / (u - d)
# 到期日期权价值
prices = [S0 * (u ** (N - i)) * (d ** i) for i in range(N + 1)]
values = [max(0.0, px - K) for px in prices]
# 逆向递推
for step in range(N - 1, -1, -1):
for i in range(step + 1):
values[i] = math.exp(-r * dt) * (p * values[i] + (1 - p) * values[i + 1])
return values[0]
# ---------- 3. 蒙特卡洛模拟 ----------
def mc_call(S0, K, T, r, sigma, n_paths, seed):
rng = random.Random(seed)
dt = T # 单步模拟
drift = (r - 0.5 * sigma**2) * dt
vol = sigma * math.sqrt(dt)
total = 0.0
for _ in range(n_paths):
z = rng.gauss(0.0, 1.0)
ST = S0 * math.exp(drift + vol * z)
total += max(0.0, ST - K)
return math.exp(-r * T) * total / n_paths
# ---------- 运行与比较 ----------
# BS
t0 = time.perf_counter()
bs_price = bs_call(S0, K, T, r, sigma)
t_bs = time.perf_counter() - t0
# 二叉树
t0 = time.perf_counter()
bin_price = binomial_call(S0, K, T, r, sigma, N_BIN)
t_bin = time.perf_counter() - t0
# 蒙特卡洛
t0 = time.perf_counter()
mc_price = mc_call(S0, K, T, r, sigma, N_MC, SEED)
t_mc = time.perf_counter() - t0
# 输出结果
print(f"Black-Scholes: {bs_price:.4f} 耗时 {t_bs*1000:.2f} ms")
print(f"二叉树 (N={N_BIN}): {bin_price:.4f} 耗时 {t_bin*1000:.2f} ms")
print(f"蒙特卡洛 (N={N_MC}): {mc_price:.4f} 耗时 {t_mc*1000:.2f} ms")
print(f"二叉树误差: {abs(bin_price - bs_price)/bs_price*100:.3f}%")
print(f"蒙特卡洛误差: {abs(mc_price - bs_price)/bs_price*100:.3f}%")
运行方式
将代码保存为 option_pricing.py,在终端执行:
python option_pricing.py
验证方法与判定标准
程序输出三种模型的价格与耗时。判定通过条件:
- 二叉树价格与BS价格偏差小于0.5%(N=500时通常偏差<0.1%);
- 蒙特卡洛价格与BS价格偏差在1%以内(10万条路径下标准误约0.15元,对应约0.5%相对误差);
- 耗时排序符合预期:BS < 二叉树 < 蒙特卡洛。
若需更高蒙特卡洛精度,可增大N_MC至50万,误差将降至0.2%以内,但耗时线性增加。
关键说明
- 二叉树采用CRR参数化,步数
N_BIN决定收敛精度,500步已足够; - 蒙特卡洛使用单步几何布朗运动模拟,
SEED=42固定随机序列,每次运行结果一致; - BS模型为标准正态CDF的erf近似,精度达1e-15,不影响比较结论。