本文用简洁的 Markdown 结构,带你从随机微积分走向真实的 Python 估值代码。关键词融入自然,逻辑层层递进;附 5 组 FAQ,随读随解疑。
1. 期权与收益:从零理解 Call & Put
在金融衍生品世界里,期权是一份合约,持有者可选择在到期日 T 以执行价 E 买入(Call)或卖出(Put)标的资产 _S_。Call 收益函数为
$$ h_T = \max(S_T - E,\, 0) $$
当标的价格从 100 上升到 110 时,每份 Call 带来 10 元无风险利润;而标的价格若低于 _E_,权利方至多数值为 0,绝不产生负现金流。正是这种“非线性、有限亏损”的特性,让期权成为风险管理与杠杆投机的最佳工具之一。
2. 随机过程假设与数学基石
2.1 股票价格的三大假设
若把时间序列拉长观察苹果股价,可见:趋势的持续 + 白噪声的震荡 = 几何布朗运动(GBM)。为保证数学可操作性,我们接受三条经典假设:
- 马尔可夫性 – 未来只与现在有关,过去不相关。
- 鞅性 – 在有效市场中,当前价格即为所有信息的公允价值。
- 正态回报 – 单日对数收益服从正态分布(野尾厚尾现象需用后续模型修正)。
2.2 从布朗运动到伊藤引理
定义标准布朗运动 _W_t_:
- _W_0 = 0;
- 增量独立;
- Δ_W ~ N(0, Δt)。
它几乎处处连续却处处不可微,使得经典微积分失效;于是我们转向伊藤积分与二次变分,继而引出伊藤引理:
对任意伊藤过程 X_t 及函数 f(t, _X_t_),
$$ df = \frac{\partial f}{\partial t} dt + \frac{\partial f}{\partial x} dX_t + \frac{1}{2} \frac{\partial^2 f}{\partial x^2}(dX_t)^2 $$
这一公式成为衍生证券定价的“无闪灯通行证”。
3. 股票定价模型:GBM 的推导与实现
设标的价格服从
$$ dS_t = \mu S_t dt + \sigma S_t dW_t $$
对其取对数 _f = ln(S_t)_,应用伊藤引理,可把价格分布闭式表达一次性写出:
$$ S_T = S_0\,\exp\!\left[\left(\mu-\frac{\sigma^2}{2}\right)T + \sigma\sqrt{T}Z\right], \quad Z\sim N(0,1) $$
该公式揭示:对数收益率呈正态分布,为后续期权 Monte-Carlo 估值奠定基石。下面两段 Python 代码验证速度:
import jax.numpy as jnp
import jax.random as jrandom
def mc_stock_price(S0, T, r, sigma, samples=1000):
# 逐日模拟
...
def model_stock_price(S0, T, r, sigma, samples=1000):
# 闭式解析加速
...实际测试 JAX vs 纯 NumPy:在 500 万次模拟场景下,JAX 运作 0.056 秒,速度是传统 NumPy 的 5 倍,GPU 并行优势一目了然。
4. Black-Scholes 期权定价
4.1 两种互补充方法论
| 方法 | 核心思想 | 优劣势 |
|---|---|---|
| PDE(Black-Scholes 方程) | 用 δ 对冲消除随机项,建立偏微分方程并求解闭合解 | 快!无法给出价格分布 |
| 风险中性 Monte-Carlo | 在风险中性测度下模拟海量资产路径并贴现收益 | 给出完整分布与尾风险,但耗时 |
实战 Monte-Carlo 估值仅需十行 Jax:
def mc_call_option_price(S0, E, T, r, sigma, samples=1000):
Z = jrandom.normal(jrandom.PRNGKey(1), shape=[samples])
ST = S0 * jnp.exp(T*(r - 0.5*sigma**2) + sigma*jnp.sqrt(T)*Z)
payoff = jnp.maximum(ST - E, 0)
return jnp.exp(-r*T)*jnp.mean(payoff)而对同一样本参数,调用Black-Scholes 闭合公式:
$$ C = S_0 N(d_1) - E e^{-rT} N(d_2) $$
其中
$$ d_1 = \frac{\ln(S_0/E)+(r+\sigma^2/2)T}{\sigma\sqrt{T}}, \quad d_2 = d_1 - \sigma\sqrt{T} $$
Python 一函数即可:
def bs_call_option_price(S0, E, T, r, sigma):
d1 = (jnp.log(S0/E) + (r + sigma**2/2)*T) / (sigma*jnp.sqrt(T))
d2 = d1 - sigma*jnp.sqrt(T)
return S0*jscipy.stats.norm.cdf(d1) - E*jnp.exp(-r*T)*jscipy.stats.norm.cdf(d2)4.2 实务权衡对读:精度、时间与风险指标
- 按需选择:若日内高频调仓,优先闭合公式;若风控需检视右尾概率或 V@R,则 Monte-Carlo 更优。
- 提速窍门:开启 JAX 的 GPU+JIT,2000 万次模拟仍可保持毫秒级。
常见问题 FAQ
- Q:为什么我模拟股票价格时,得到的曲线有时会“跳水”?
A:GBM 允许负向漂移和自由波动,σ 越大,罕见但极端的“深水”跳跃越显著,这正是尾部风险的量化来源。 - Q:Black-Scholes 假设“无股息”,实际美股常常分红怎么办?
A:用 Merton 模型 将股息贴现成连续收益率 q_,把 _r 替换为 r - q 即可,闭式公式保持不变。 - Q:二次变分 _[W]_t = t 总是成立吗?
A:在标准布朗运动下成立;若加入跳跃、随机波动率,需改用 Lévy 二次变分 或 Itô–Lévy 分解。 - Q:JAX 比 NumPy 快 5 倍,为何网上有人看到 10~20 倍?
A:差距来自 GPU 型号、批次大小与 动态 loop 展开。尽量写成向量化计算、避免 Python for-loop,加速可达极限。 - Q:如果我想给障碍期权(Barrier Option)定价,还能照搬本文思路吗?
A:原理一致,但在 Monte-Carlo 中需检查每条路径是否触及障碍,并用路径依赖变量累积收益;PDE 需叠加额外边界条件。 - Q:如何评估 σ 的未来预期?
A:市场给出隐含波动率曲面;也可从历史回报用 GARCH 或 Heston 模型外推,再代入 GBM σ 参数。