
Python for Finance Chapter3
金融数值分析 示例
BSM 模型中的两个基本问题
- 隐含波动率
以某些到期日的期权报价和期权定价公式反推期权的隐含波动率,并汇出图表——这是期权交易者和风险管理者每天都要面对的任务。 - 蒙特卡洛模拟
欧式期权价值的计算。通过蒙特卡罗技术,模拟股票在一段时间中变化。
像Black-Scholes-Merton(1973)这样有深远影响的期权定价公式中,隐含波动率是在其他条件不变的情况下输入公式,得出不同期权行权价格和到期日测得市场报价的那些波动率值。
BSM公式
\begin{aligned}
C\left(S_{t}, K, t, T, r\right) &=S_{t} \cdot N\left(d_{1}\right)-e^{-r(T-t)} \cdot K \cdot N\left(d_{2}\right) \newline
N(d) &=\frac{1}{\sqrt{2 \pi}} \int_{-\infty}^{d} e^{-1 / 2} x^{2} d x \newline
d_{1} &=\frac{\log \left(S_{T} / K\right)+\left(r+\sigma^{2} / 2\right)(T-t)}{\sigma \sqrt{T-t}} \newline
d_{2} &=\frac{\log \left(S_{T} / K\right)+\left(r-\sigma^{2} / 2\right)(T-t)}{\sigma \sqrt{T-t}}
\end{aligned}
不同参数有如下含义:
$S_t$ 在时点t的标的物价格水平;
$\sigma$ 标的物固定波动率(也就是收益的标准差);
$K$ 期权行权价格;
$T$ 期权到期日;
$r$ 固定无风险短期利率;
现在考虑欧式看涨期权的一个报价 $C^*$ 已知的情况。隐含波动率 $\sigma^{imp}$ 是上述公式的隐式方程的解,它没有解析表达式,因此对于隐含波动率 $\sigma^{imp}$ 的求解采用数值方法求解,牛顿迭代法
$$
C^{*}=C\left(\sigma_{n}^{i m p}\right)+\left(\sigma_{n+1}^{i m p}-\sigma_{n}^{i m p}\right) \cdot \frac{\partial C\left(\sigma_{n}^{i m p}\right)}{\partial \sigma_{n}^{i m p}}
$$
$$
\Longrightarrow \sigma_{n+1}^{i m p}=\sigma_{n}^{i m p}-\frac{C\left(\sigma_{n}^{i m p}\right)-C^{*}}{\partial C\left(\sigma_{n}^{i m p}\right) / \partial \sigma_{n}^{i m p}}
$$
期权定价公式对于波动率的偏微分称作希腊字母 Vega,可以得出了 Vega 的闭合方式。
$$
\frac{\partial C}{\partial \sigma}=S_tN(d_1)\sqrt{T-t}
$$
Black-Scholes-Merton python计算公式
1 | import numpy as np |
1 | S0 = 1 |
结果:0.2800420290586886
vxtoxx 为例,比较特殊的 h5 型数据,类似数据库式的数据,后期可以用 SQL 作为数据储存工具,读取csv。但是书中示例式这个。
1 | import pandas as pd |
结果如下所示,因为在每个交易日,根据行权价格,看涨看跌,期权行权时间,更甚还可以各种障碍条款的亚式、欧式、美式的各种期权,因此期权的种类是多种多样的。在2014-3-31日 vstoxx 欧式期权的种类就有395种看涨期权。
1 | <class 'pandas.core.frame.DataFrame'> |
1 | options_data.head() # 看一下头几行长什么样 |
| DATE | EXP_YEAR | EXP_MONTH | TYPE | STRIKE | PRICE | MATURITY | TTM | |
|---|---|---|---|---|---|---|---|---|
| 46170 | 2014-03-31 | 2014 | 4 | C | 1.0 | 16.85 | 2014-04-18 | 0.049 |
| 46171 | 2014-03-31 | 2014 | 4 | C | 2.0 | 15.85 | 2014-04-18 | 0.049 |
| 46172 | 2014-03-31 | 2014 | 4 | C | 3.0 | 14.85 | 2014-04-18 | 0.049 |
| 46173 | 2014-03-31 | 2014 | 4 | C | 4.0 | 13.85 | 2014-04-18 | 0.049 |
| 46174 | 2014-03-31 | 2014 | 4 | C | 5.0 | 12.85 | 2014-04-18 | 0.049 |
1 | futures_data.head() # 看一下期货的头几行 |
| DATE | EXP_YEAR | EXP_MONTH | PRICE | MATURITY | TTM | |
|---|---|---|---|---|---|---|
| 496 | 2014-03-31 | 2014 | 4 | 17.85 | 2014-04-18 | 0.049 |
| 497 | 2014-03-31 | 2014 | 5 | 19.55 | 2014-05-16 | 0.126 |
| 498 | 2014-03-31 | 2014 | 6 | 19.95 | 2014-06-20 | 0.222 |
| 499 | 2014-03-31 | 2014 | 7 | 20.40 | 2014-07-18 | 0.299 |
| 500 | 2014-03-31 | 2014 | 8 | 20.70 | 2014-08-15 | 0.375 |
可以发现,一些期权是很便宜的价内期权(指数水平远高于期权的行权价格)。因此我们应该根据对应到期日的期货价值,分析具有一定(远期)价值的看涨期权。允许与期货水平之间的最大偏差为50%
1 | V0 = 17.6639 |
- 准备画图数据
1 | plot_data = options_data[options_data['IMP_VOL']>0] |
1 | [Timestamp('2014-04-18 00:00:00'), |
- 画图
1 | import matplotlib.pyplot as plt |

在股票或外汇市场中,你将注意到所谓的隐含波动率微笑,而且到期日越短,隐含波动率微笑越明显;到期日越长,越不明显。
期权定价的蒙特卡罗模拟
蒙特卡罗是金融学和数值科学中最重要的算法之一。它之所以重要,是因为在期权定价或者风险管理问题上有很强的能力。和其他数值方法相比,蒙特卡罗方法很容易处理高维问题,在这种问题上复杂度和计算需求通常以线性方式增大。一下例子阐述了python的基于蒙特卡罗模拟的欧式期权估值方法。
Black-Scholes-Merton随机微分方程
$$
dS_t=rS_tdt+\sigma S_tdZ_t
$$
其中, $Z_t$ 是一个布朗运动
上述 SDE 方程的欧拉离散
$$
S_t=S_{t-\Delta_t}\ exp\lgroup \lgroup r -\frac{1}{2}\sigma^2\rgroup \Delta t+\sigma \sqrt{\Delta t}z_t\rgroup
$$
变量Z是标准正态分布随机变量,$0<\Delta_t<T$,是一个足够小的时间间隔。以 $S0=100、$$K=105、$$T=1.0、$$r=0.05、$$\sigma=0.2$ 参数化上述模型,利用前面例子中的计算公式,可以得到精确的期权价值:
1 | S0 = 100 |
结果:8.021352235143176
蒙特卡罗算法流程:
将时间间隔 [0,T] 分为等距的、长度为$\Delta_t$的子时段。
开始循环 $i=1,2,\cdots, l。$
(a) 对于每个时间步$t\in {\Delta_t, 2\Delta_t,\dots, T }$,取伪随机数 Z_t(i)。
(b) 逐个时间步应用伪随机数,确定指数水平$S_T(i)$的T值,以离散化公式2-2的方案
(c) 确定T时点欧式看涨期权的内在价值:$h_t:h_t(ST(i))=max(ST(i)-K, 0)$
(d) 循环到 $i=I$
根据公式2-3,加总内在价值,求平均值,并扣除无风险短期利率。
公式 2-3 欧式看涨期权的蒙特卡罗估算函数:
$$
C_0\approx e^{-rT}\frac{1}{I}\sum_Ih_T(S_T(i))
$$
纯 python
1 | from time import time |
结果:
欧式期权定价 7.9990448881765825.
共计花费时间 24.1s.
Numpy 向量化
使用 Numpy 的欧式看涨期权蒙特卡罗估值(第一个版本)
1 | import math |
结果:
Europen Option Value 8.037
Duration in Seconds 0.746
向量化和纯Python 相比,速度有30倍以上的提升。且估算的蒙特卡罗值和基准值很接近。在对欧拉离散公式进行对数化处理后,我们可以获得更高的效率。
欧拉离散化方法(对数形式):
$$
logS_T=logS_{T-\Delta_t}+(r-(1/2)\sigma^2)\Delta_t + \sigma\sqrt{\Delta_t}z_t
$$
这个版本完全采用递增法,可以在Python层面上不使用任何循环的情况下实现蒙特卡罗算法。
代码:上一例中横着一行表示一条路劲,这里竖着一列表示一条路径,
1 | import math |
结果:
欧式期权定价 8.165807966259603.
共计花费时间 0.6s.
图形化分析
绘制前30条模拟路径:
1 | import matplotlib.pyplot as plt |

模拟结束时模拟指数水平的频率:
1 | plt.hist(S[-1], bins=50) |

期末期权内在价值直方图:
1 | plt.hist(np.maximum(S[-1] - K,0),bins = 50) |

扩展-数据获取 API 接口
pandas DataReader 函数
1 | import numpy as np |
| High | Low | Open | Close | Volume | Adj Close | |
|---|---|---|---|---|---|---|
| Date | ||||||
| 1999-12-31 | 1472.420044 | 1458.189941 | 1464.469971 | 1469.250000 | 374050000 | 1469.250000 |
| 2000-01-03 | 1478.000000 | 1438.359985 | 1469.250000 | 1455.219971 | 931800000 | 1455.219971 |
| 2000-01-04 | 1455.219971 | 1397.430054 | 1455.219971 | 1399.420044 | 1009000000 | 1399.420044 |
| 2000-01-05 | 1413.270020 | 1377.680054 | 1399.420044 | 1402.109985 | 1085500000 | 1402.109985 |
| 2000-01-06 | 1411.900024 | 1392.099976 | 1402.109985 | 1403.449951 | 1092300000 | 1403.449951 |
1 | sp500['42d'] = np.round(pd.Series.rolling(sp500['Close'],window=42).mean()) # 42日均线 |

tushare 获取数据 下载到 MySQL
- 从 tushare 注册账号,获取 API 接口码
1 | import pandas as pd |
| ts_code | trade_date | open | high | low | close | pre_close | change | pct_chg | vol | amount | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 600000.SH | 20200630 | 10.59 | 10.64 | 10.54 | 10.58 | 10.57 | 0.01 | 0.0946 | 228867.64 | 242601.910 |
| 1 | 600000.SH | 20200629 | 10.63 | 10.73 | 10.49 | 10.57 | 10.60 | -0.03 | -0.2830 | 278756.19 | 295223.647 |
| 2 | 600000.SH | 20200624 | 10.54 | 10.61 | 10.50 | 10.60 | 10.48 | 0.12 | 1.1450 | 228738.84 | 241489.165 |
| 3 | 600000.SH | 20200623 | 10.51 | 10.57 | 10.47 | 10.48 | 10.55 | -0.07 | -0.6635 | 196022.12 | 206109.220 |
| 4 | 600000.SH | 20200622 | 10.57 | 10.66 | 10.53 | 10.55 | 10.61 | -0.06 | -0.5655 | 246119.03 | 260728.901 |
- 保存到 MySQL
1 | import pandas as pd |
Python for Finance by Yves Hilpisch(O’Reilly).Copyright 2015 Yves Hilpisch,978-1-491-94528-5