欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  资讯频道

量化分析师的Python日记【第7天:Q Quant 之初出江湖】

程序员文章站 2022-03-08 14:48:45
...

在 http://uqer.io 中经过前几日的学习,我们已经熟悉了Python中一些常用数值计算库的用法。本篇中,作为Quant中的Q宗(P Quant 和 Q Quant 到底哪个是未来?),我们将尝试把之前的介绍的工具串联起来,小试牛刀。

您将可以体验到:

  1. 如何使用python内置的数学函数计算期权的价格;
  2. 利用 numpy 加速数值计算;
  3. 利用 scipy 进行仿真模拟;
  4. 使用 scipy 求解器计算隐含波动率;

穿插着,我们也会使用matplotlib绘制精美的图标。

1. 关心的问题

我们想知道下面的一只期权的价格:

  • 当前价 spot : 2.45
  • 行权价 strike : 2.50
  • 到期期限 maturity : 0.25
  • 无风险利率 r : 0.05
  • 波动率 vol : 0.25

关于这样的简单欧式期权的定价,有经典的Black - Scholes [1] 公式:

 

Call(S,K,r,τ,σ)d1d2= SN(d1)KerτN(d2),=ln(S/K)+(r+12σ2)τστ,=d1στ.

 

其中S为标的价格,K为执行价格,r为无风险利率,τ=Tt为剩余到期时间。 N(x)为标准正态分布的累积概率密度函数。Call(S,K,r,τ,σ)为看涨期权的价格。

 
 
 
 
 
1
# 参数
2
spot = 2.45
3
strike = 2.50
4
maturity = 0.25
5
r = 0.05
6
vol = 0.25
 
 

观察上面的公式,需要使用一些数学函数,我们把它分为两部分:

  • log,sqrt,exp,这三个函数我们可以从标准库math中找到
  • 标准正态分布的累计概率密度函数,我们使用scipy库中的stats.norm.cdf函数
 
 
 
 
 
1
# 基于Black - Scholes 公式的期权定价公式
2
from math import log, sqrt, exp
3
from scipy.stats import norm
4
5
def call_option_pricer(spot, strike, maturity, r, vol):
6
    
7
    d1 = (log(spot/strike) + (r + 0.5 * vol *vol) * maturity) / vol / sqrt(maturity)
8
    d2 = d1 - vol * sqrt(maturity)
9
    
10
    price = spot * norm.cdf(d1) - strike * exp(-r*maturity) * norm.cdf(d2)
11
    return price
 
 

我们可以使用这个函数计算我们关注期权的结果:

 
 
 
 
 
1
print '期权价格 : %.4f' % call_option_pricer(spot, strike, maturity, r, vol)
 
 
期权价格 : 0.1133
 

2. 使用numpy加速批量计算

大部分的时候,我们不止关心一个期权的价格,而是关心一个组合(成千上万)的期权。我们想知道, 随着期权组合数量的增长,我们计算时间的增长会有多块?

2.1 使用循环的方式

 
 
 
 
 
1
import time
2
import numpy as np
3
4
portfolioSize = range(1, 10000, 500)
5
timeSpent = []
6
7
for size in portfolioSize:
8
    now = time.time()
9
    strikes = np.linspace(2.0,3.0,size)
10
    for i in range(size):
11
        res = call_option_pricer(spot, strikes[i], maturity, r, vol)
12
    timeSpent.append(time.time() - now)
 
 

从下图中可以看出,计算时间的增长可以说是随着组合规模的增长线性上升。

 
 
 
 
 
1
from matplotlib import pylab
2
import seaborn as sns
3
font.set_size(15)
4
sns.set(style="ticks")
5
pylab.figure(figsize = (12,8))
6
pylab.bar(portfolioSize, timeSpent, color = 'r', width =300)
7
pylab.grid(True)
8
pylab.title(u'期权计算时间耗时(单位:秒)', fontproperties = font, fontsize = 18)
9
pylab.ylabel(u'时间(s)', fontproperties = font, fontsize = 15)
10
pylab.xlabel(u'组合数量', fontproperties = font, fontsize = 15)
 
 
<matplotlib.text.Text at 0xdbad950>
量化分析师的Python日记【第7天:Q Quant 之初出江湖】

2.2 使用numpy向量计算

numpy的内置数学函数可以天然的运用于向量:

 
 
 
 
 
1
sample = np.linspace(1.0,100.0,5)
2
np.exp(sample)
 
 
array([ 2.71828183e+00, 1.52434373e+11, 8.54813429e+21, 4.79357761e+32, 2.68811714e+43])

利用 numpy 的数学函数,我们可以重写原先的计算公式 call_option_pricer,使得它接受向量参数。

 
 
 
 
 
1
# 使用numpy的向量函数重写Black - Scholes公式
2
def call_option_pricer_nunmpy(spot, strike, maturity, r, vol):
3
    
4
    d1 = (np.log(spot/strike) + (r + 0.5 * vol *vol) * maturity) / vol / np.sqrt(maturity)
5
    d2 = d1 - vol * np.sqrt(maturity)
6
    
7
    price = spot * norm.cdf(d1) - strike * np.exp(-r*maturity) * norm.cdf(d2)
8
    return price
 
 
 
 
 
 
 
1
timeSpentNumpy = []
2
for size in portfolioSize:
3
    now = time.time()
4
    strikes = np.linspace(2.0,3.0, size)
5
    res = call_option_pricer_nunmpy(spot, strikes, maturity, r, vol)
6
    timeSpentNumpy.append(time.time() - now)
 
 

再观察一下计算耗时,虽然时间仍然是随着规模的增长线性上升,但是增长的速度要慢许多:

 
border-right-width: 30px; border-right-style: solid; b
来自: uqer.io
0
0
评论 共 0 条 请登录后发表评论

发表评论

量化分析师的Python日记【第7天:Q Quant 之初出江湖】 您还没有登录,请您登录后再发表评论

相关推荐

量化分析师的Python日记【第7天:Q Quant 之初出江湖】
量化分析师的Python日记【第7天:Q Quant 之初出江湖】
Global site tag (gtag.js) - Google Analytics