QuantLib 金融计算——数学工具之数值积分
如果未做特别说明,文中的程序都是 Python3 代码。
QuantLib 金融计算——数学工具之数值积分
载入模块
import QuantLib as ql
import scipy
from scipy.stats import norm
from scipy.stats import lognorm
print(ql.__version__)
1.12
概述
quantlib-python 提供了许多方法计算标量函数 \(f : R \to R\) 在闭区间上的积分:
\]
对于主要的积分方法,必须提供两个参数:
- 绝对精度:如果当前计算结果和前一个计算结果的差小于精度,则停止计算。
- 最大计算次数:如果达到最大计算次数,则停止计算。
对于某些特殊的数值积分,例如高斯积分,还需要提供其他额外参数。
常见积分方法
首先讨论最普通最常见的一类数值积分,quantlib-python 提供了下列方法:
TrapezoidIntegralMidPoint
SimpsonIntegral
GaussLobattoIntegral
GaussKronrodAdaptive
GaussKronrodNonAdaptive
这些方法在一般的数值分析教科书中都有详细的讨论。在 quantlib-python 中,上述数值积分器对象的构造方式是相同的,如下:
myIntegrator = ql.XXXintegrator(absoluteAccuracy,
maxEvaluations)
计算闭区间 \([a, b]\) 上的积分值:
myIntegrator(f, a, b)
其中 f
是一个“单参数”函数,返回一个浮点数。
例子 1,标准正态密度函数上的积分
def testIntegration1():
absAcc = 0.00001
maxEval = 1000
a = 0.0
b = scipy.pi
numInt1 = ql.TrapezoidIntegralMidPoint(absAcc, maxEval)
numInt2 = ql.SimpsonIntegral(absAcc, maxEval)
numInt3 = ql.GaussLobattoIntegral(maxEval, absAcc)
numInt4 = ql.GaussKronrodAdaptive(absAcc, maxEval)
numInt5 = ql.GaussKronrodNonAdaptive(absAcc, maxEval, absAcc)
analytical = norm.cdf(b) - norm.cdf(a)
print('{0:<30}{1}'.format('Analytical:', analytical))
print('{0:<30}{1}'.format('Midpoint Trapezoidal:', numInt1(norm.pdf, a, b)))
print('{0:<30}{1}'.format('Simpson:', numInt2(norm.pdf, a, b)))
print('{0:<30}{1}'.format('Gauss Lobatto:', numInt3(norm.pdf, a, b)))
print('{0:<30}{1}'.format('Gauss Kronrod Adpt:', numInt4(norm.pdf, a, b)))
print('{0:<30}{1}'.format('Gauss Kronrod Non Adpt:', numInt5(norm.pdf, a, b)))
testIntegration1()
Analytical: 0.4991598418317367
Midpoint Trapezoidal: 0.4991643496589137
Simpson: 0.4991598398355923
Gauss Lobatto: 0.49916005276697556
Gauss Kronrod Adpt: 0.49915984183173506
Gauss Kronrod Non Adpt: 0.4991598418317367
所有结果几乎是一致的。
下面是一个更复杂的例子,直接从欧式看涨期权的积分形式近似计算期权价格。
敲定价格为 \(K\) 的看涨期权的积分形式为:
\]
其中 \(f(x)\) 是对数正态分布的密度函数,均值为:
\]
方差为:
\]
通常 quantlib-python 提供的数值积分方法不接受额外参数,如果计算涉及额外参数,需要做特殊的转换,将额外参数和积分函数“绑定”成为一个单参数函数。
Python 的语言机制非常灵活,可以通过构造实现“函数体”来绑定积分区间和积分函数,积分区间作为类的参数。或者,可以更简单地编写一个返回函数的函数,
例子 2,积分上限采用 \(10 \times K\)
def callFunc(spot,
strike,
r,
vol,
tau):
mean = scipy.log(spot) + (r - 0.5 * vol * vol) * tau
stdDev = vol * scipy.sqrt(tau)
def inner_func(x):
return (x - strike) * \
lognorm.pdf(
x, stdDev, loc=0, scale=scipy.exp(mean)) * \
scipy.exp(-r * tau)
return inner_func
其中,内部函数 inner_func
作为对象被返回,inner_func
是一个单参数函数。
def testIntegration4():
spot = 100.0
r = 0.03
tau = 0.5
vol = 0.20
strike = 110.0
a = strike
b = strike * 10.0
ptrF = callFunc(spot, strike, r, vol, tau)
absAcc = 0.00001
maxEval = 1000
numInt = ql.SimpsonIntegral(absAcc, maxEval)
print("Call Value: ", numInt(ptrF, a, b))
testIntegration4()
与标准 Black-Scholes 公式得出的结果几乎一致。
Call Value: 2.611902550625855
高斯积分
通常,一个 n 点高斯求积通过选取合适的 \(x_i\) 和 \(w_i\)(\(i = 1, ..., n\))产生 2n − 1 阶(或较低阶)多项式的准确积分值构造出来,
\]
存在不同类型的权重函数和区间形式,quantlib-python 提供了如下几种:
GaussLaguerreIntegration
:计算 \(\int_0^{\infty} f(x)dx\) 的广义 Gauss Laguerre 积分;权重函数为 \(w(x,s) := x^s e^{-x} , s>-1\)GaussHermiteIntegration
:计算 \(\int_{-\infty}^{\infty} f(x)dx\) 的 Gauss Hermite 积分;权重函数为 \(w(x,\mu) = |x|^{2\mu} e^{-x^2} , \mu > -0.5\)GaussJacobiIntegration
:计算 \(\int_{-1}^1 f(x)dx\) 的Gauss Jacobi 积分;权重函数为 \(w(x,\alpha, \beta) = (1-x)^\alpha(1+x)^\beta , \alpha,\beta > 1\)GaussHyperbolicIntegration
:计算 \(\int_{-\infty}^{\infty} f(x)dx\) 的高斯双曲积分;权重函数为 \(w(x) = \frac{1}{\cosh(x)}\)GaussLegendreIntegration
:计算 \(\int_{-1}^1 f(x)dx\) 的 Gauss Legendre 积分;权重函数为 \(w(x)=1\)GaussChebyshevIntegration
:计算 \(\int_{-1}^1 f(x)dx\) 的第一类 Gauss Chebyshev 积分;权重函数为\(w(x) = \sqrt{(1-x^2)}\)GaussChebyshev2ndIntegration
:计算 \(\int_{-1}^1 f(x)dx\) 的第二类 Gauss Legendre 积分;权重函数为 \(w(x, \lambda) = (1+x^2)^{\lambda - 1/2}\)
例子 3
def testIntegration2():
gLagInt = ql.GaussLaguerreIntegration(16) # [0,\infty]
gHerInt = ql.GaussHermiteIntegration(16) # (-\infty, \infty)
gChebInt = ql.GaussChebyshevIntegration(64) # (-1, 1)
gChebInt2 = ql.GaussChebyshev2ndIntegration(64) # (-1, 1)
analytical = norm.cdf(1) - norm.cdf(-1)
print('{0:<15}{1}'.format("Laguerre:", gLagInt(norm.pdf)))
print('{0:<15}{1}'.format("Hermite:", gHerInt(norm.pdf)))
print('{0:<15}{1}'.format("Analytical:", analytical))
print('{0:<15}{1}'.format("Cheb:", gChebInt(norm.pdf)))
print('{0:<15}{1}'.format("Cheb 2 kind:", gChebInt2(norm.pdf)))
Laguerre: 0.49999230923944715
Hermite: 0.9999999834745512
Analytical: 0.6826894921370859
Cheb: 0.6827380724493052
Cheb 2 kind: 0.682595292164792
通常 quantlib-python 提供的高斯积分方法只针对固定的区间,例如 \([-1,1]\),如果需要计算其他区间上的积分,需要做特殊的转换,将积分区间和积分函数“绑定”成为一个单参数函数。区间 \([−1, 1]\) 向 \([a, b]\) 的转换相当简单
\]
类似之前的做法,
def Func(f, a, b):
t1 = 0.5 * (b - a)
t2 = 0.5 * (b + a)
def inner_func(x):
return t1 * f(t1 * x + t2)
return inner_func
例子 4
def testIntegration3():
a = -1.96
b = 1.96
gChebInt = ql.GaussChebyshevIntegration(64)
analytical = norm.cdf(b) - norm.cdf(a)
f = Func(norm.pdf, a, b)
print('{0:<15}{1}'.format("Analytical:", analytical))
print('{0:<15}{1}'.format("Chebyshev:", gChebInt(f)))
testIntegration3()
Analytical: 0.950004209703559
Chebyshev: 0.9500271929144378
QuantLib 金融计算——数学工具之数值积分的更多相关文章
- QuantLib 金融计算——数学工具之求解器
目录 QuantLib 金融计算--数学工具之求解器 概述 调用方式 非 Newton 算法(不需要导数) Newton 算法(需要导数) 如果未做特别说明,文中的程序都是 Python3 代码. Q ...
- QuantLib 金融计算——数学工具之插值
目录 QuantLib 金融计算--数学工具之插值 概述 一维插值方法 二维插值方法 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之插值 载入模块 ...
- QuantLib 金融计算——数学工具之优化器
目录 QuantLib 金融计算--数学工具之优化器 概述 Optimizer Constraint OptimizationMethod EndCriteria 示例 Rosenbrock 问题 校 ...
- QuantLib 金融计算——数学工具之随机数发生器
目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ...
- QuantLib 金融计算
我的微信:xuruilong100 <Implementing QuantLib>译后记 QuantLib 金融计算 QuantLib 入门 基本组件之 Date 类 基本组件之 Cale ...
- QuantLib 金融计算——高级话题之模拟跳扩散过程
目录 QuantLib 金融计算--高级话题之模拟跳扩散过程 跳扩散过程 模拟算法 面临的问题 "脏"的方法 "干净"的方法 实现 示例 参考文献 如果未做特别 ...
- QuantLib 金融计算——基本组件之 Currency 类
目录 QuantLib 金融计算--基本组件之 Currency 类 概述 构造函数 成员函数 如果未做特别说明,文中的程序都是 python3 代码. QuantLib 金融计算--基本组件之 Cu ...
- QuantLib 金融计算——修复 BatesProcess 中的两个 Bug
QuantLib 金融计算--修复 BatesProcess 中的两个 Bug 我发现了 BatesProcess 中的两个 Bug: 基类 HestonProcess::factors 的返回值取决 ...
- QuantLib 金融计算——QuantLib 入门
目录 QuantLib 金融计算--QuantLib 入门 简介 主要功能 安装与使用 学习指南 The HARD Way The EASY Way QuantLib 金融计算--QuantLib 入 ...
随机推荐
- 有关jQuery valid 验证多个同name属性的input的问题
今天遇到需要动态添加多个同name属性的input框,用jQuery valid进行验证时,没有指定不同的id,验证只会在第一个显示提示信息,因为jQuery valid显示的提示信息是根据每个inp ...
- 将Oracle数据库设置为归档模式及非归档模式
一.将Oracle数据库设置为归档模式 1)sql>shutdown normal/immediate;2)sql>startup mount;3)sql>alter databas ...
- 此实现不是Windows平台FIPS验证的加密算法的一部分
运行wpf程序,出现错误“此实现不是Windows平台FIPS验证的加密算法的一部分”. 解决方法: 1.在window中打开功能里输入regedit,回车打开注册器: 2.进入如下路径中 HKEY_ ...
- Windows本地Linux虚拟机ping不通的解决办法
解决办法:启动虚拟机双网卡支持: 网卡1:Host-Only网络 网卡2:NAT网络 设置好以后,可以在Linux主机中ifconfig查看本地Host-Only的网络地址,与电脑中的地址应该是同一网 ...
- nignx重启
.进入nginx安装目录sbin下 .输入./nginx -s reload
- Java07
/* 定义一个类Demo,其中定义一个求两个数据和的方法, 定义一个测试了Test,进行测试. 变量什么时候定义为成员变量: 如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量. ...
- Java中的一些代理技术
使用cglib,asm 对接口进行拦截,这里需要调用Invoke方法 final IUserService userService=new UserService(); Enhancer enhanc ...
- mvc数组绑定-jquery ajax
var list=[];//数组 list[0]=1001; list[1]=1002; list[1]=1003; var json_data = { selected: list}; $.ajax ...
- CodeForces 687B Remainders Game(数学,最小公倍数)
题意:给定 n 个数,一个数 k,然后你知道一个数 x 取模这个 n 个的是几,最后问你取模 k,是几. 析:首先题意就看了好久,其实并不难,我们只要能从 n 个数的最小公倍数是 k的倍数即可,想想为 ...
- CentOS6.4 X86_64 kvm+PXE备忘
Install 安装 1 2 3 4 5 # yum install qemu-kvm qemu-img # 使用kvm至少要安装的包,一个提供用户级别kvm模拟器,一个提供磁盘镜像的管理 # 安装虚 ...