公式背后的函数
scipy.special 收集了公式里反复出现的有名字的函数。对金融最有用的是正态累积分布函数 Φ(x),即 special.ndtr。它与误差函数的关系是 Φ(x)=21(1+erf(x/2))。现价 S、行权价 K、利率 r、波动率 σ、期限 T 的看涨期权的布莱克–斯科尔斯价格要用它两次:C=SΦ(d1)−Ke−rTΦ(d2),其中 d1=σTln(S/K)+(r+σ2/2)T,d2=d1−σT。价格对波动率的敏感度叫做 vega,等于 Sφ(d1)T,其中 φ 是正态密度。牛顿法求隐含波动率需要的正是 vega。
另一类特殊函数处理过大或过小的数。阶乘增长极快,171! 就已经超出计算机中普通小数的范围,但 lnn! 很容易:special.gammaln(n+1)。special.comb(n, k) 统计 n 步树中有 k 次上行的路径数。special.logsumexp 通过提出最大的 x 安全地计算 ln∑exi,所以 ln(e1000+e1000)=1000+ln2 不会溢出。special.expit(x)=1/(1+e^{-x}) 像逻辑模型那样把任何得分变成 0 到 1 之间的概率。规则是:数可能极大或极小时用对数计算,最后才取指数。
Φ(x)=21(1+erf(2x)),C=SΦ(d1)−Ke−rTΦ(d2),vega=Sφ(d1)T,ln∑exi=m+ln∑exi−m(1) 看涨期权价格与隐含波动率一步取
S=K=100,
r=0,
σ=0.2,
T=1。则
d1=0.1,
d2=−0.1,
Φ(0.1)=0.5398,
Φ(−0.1)=0.4602。所以
C=100⋅(0.5398−0.4602)=7.97。
0.1 处的正态密度为
0.3970,因此 vega 为
100⋅0.3970⋅1=39.70。若市场价格是
9.00,模型价格偏低
1.03,牛顿一步把波动率提高到
0.2+1.03/39.70=0.2261。要算
Φ(1),可用
erf(0.7071)=0.6827,于是
Φ(1)=21(1+0.6827)=0.8413。几个小工具:
expit(2)=0.8808,
ln4!=3.178,
(310)=120。在真实数据上,SPY 日收益的标准差是
1.196%。下跌
5% 是
z=−4.21 个标准差,
Φ(−4.21)=1.26⋅10−5,正态模型认为约
315 年才发生一次;而在
5,403 天的数据中,它出现了
20 天。
- 直接用名字:
ndtr、erf、expit、gammaln、comb 和 logsumexp 能代替好几页手写的数学。 - 极端值用对数计算:用
gammaln 和 logsumexp,而不是阶乘或巨大指数之和。 - vega 驱动求解器:隐含波动率的牛顿一步就是价格差除以 vega。
实验:评分内容
- 由 erf 得到正态函数10 分
- 布莱克–斯科尔斯看涨期权20 分
- Vega10 分
- 隐含波动率一步15 分
- 各函数的用途15 分
- 安全的相加方法10 分
- 为什么通过对数计算阶乘20 分