如果未做特别说明,文中的程序都是 Python3 代码。

QuantLib 金融计算——数学工具之数值积分

载入模块

  1. import QuantLib as ql
  2. import scipy
  3. from scipy.stats import norm
  4. from scipy.stats import lognorm
  5. print(ql.__version__)
  1. 1.12

概述

quantlib-python 提供了许多方法计算标量函数 \(f : R \to R\) 在闭区间上的积分:

\[\int_a^b f(x) dx
\]

对于主要的积分方法,必须提供两个参数:

  • 绝对精度:如果当前计算结果和前一个计算结果的差小于精度,则停止计算。
  • 最大计算次数:如果达到最大计算次数,则停止计算。

对于某些特殊的数值积分,例如高斯积分,还需要提供其他额外参数。

常见积分方法

首先讨论最普通最常见的一类数值积分,quantlib-python 提供了下列方法:

  • TrapezoidIntegralMidPoint
  • SimpsonIntegral
  • GaussLobattoIntegral
  • GaussKronrodAdaptive
  • GaussKronrodNonAdaptive

这些方法在一般的数值分析教科书中都有详细的讨论。在 quantlib-python 中,上述数值积分器对象的构造方式是相同的,如下:

  1. myIntegrator = ql.XXXintegrator(absoluteAccuracy,
  2. maxEvaluations)

计算闭区间 \([a, b]\) 上的积分值:

  1. myIntegrator(f, a, b)

其中 f 是一个“单参数”函数,返回一个浮点数。

例子 1,标准正态密度函数上的积分

  1. def testIntegration1():
  2. absAcc = 0.00001
  3. maxEval = 1000
  4. a = 0.0
  5. b = scipy.pi
  6. numInt1 = ql.TrapezoidIntegralMidPoint(absAcc, maxEval)
  7. numInt2 = ql.SimpsonIntegral(absAcc, maxEval)
  8. numInt3 = ql.GaussLobattoIntegral(maxEval, absAcc)
  9. numInt4 = ql.GaussKronrodAdaptive(absAcc, maxEval)
  10. numInt5 = ql.GaussKronrodNonAdaptive(absAcc, maxEval, absAcc)
  11. analytical = norm.cdf(b) - norm.cdf(a)
  12. print('{0:<30}{1}'.format('Analytical:', analytical))
  13. print('{0:<30}{1}'.format('Midpoint Trapezoidal:', numInt1(norm.pdf, a, b)))
  14. print('{0:<30}{1}'.format('Simpson:', numInt2(norm.pdf, a, b)))
  15. print('{0:<30}{1}'.format('Gauss Lobatto:', numInt3(norm.pdf, a, b)))
  16. print('{0:<30}{1}'.format('Gauss Kronrod Adpt:', numInt4(norm.pdf, a, b)))
  17. print('{0:<30}{1}'.format('Gauss Kronrod Non Adpt:', numInt5(norm.pdf, a, b)))
  18. testIntegration1()
  1. Analytical: 0.4991598418317367
  2. Midpoint Trapezoidal: 0.4991643496589137
  3. Simpson: 0.4991598398355923
  4. Gauss Lobatto: 0.49916005276697556
  5. Gauss Kronrod Adpt: 0.49915984183173506
  6. Gauss Kronrod Non Adpt: 0.4991598418317367

所有结果几乎是一致的。

下面是一个更复杂的例子,直接从欧式看涨期权的积分形式近似计算期权价格。

敲定价格为 \(K\) 的看涨期权的积分形式为:

\[e^{-r \tau} E(S - K)^+ = e^{-r \tau} \int_{K}^{\infty} (x-K)f(x)dx
\]

其中 \(f(x)\) 是对数正态分布的密度函数,均值为:

\[\log(S_0) + (r + \frac{1}{2} \sigma^2)\tau
\]

方差为:

\[s = \sigma \sqrt{\tau}
\]

通常 quantlib-python 提供的数值积分方法不接受额外参数,如果计算涉及额外参数,需要做特殊的转换,将额外参数和积分函数“绑定”成为一个单参数函数。

Python 的语言机制非常灵活,可以通过构造实现“函数体”来绑定积分区间和积分函数,积分区间作为类的参数。或者,可以更简单地编写一个返回函数的函数,

例子 2,积分上限采用 \(10 \times K\)

  1. def callFunc(spot,
  2. strike,
  3. r,
  4. vol,
  5. tau):
  6. mean = scipy.log(spot) + (r - 0.5 * vol * vol) * tau
  7. stdDev = vol * scipy.sqrt(tau)
  8. def inner_func(x):
  9. return (x - strike) * \
  10. lognorm.pdf(
  11. x, stdDev, loc=0, scale=scipy.exp(mean)) * \
  12. scipy.exp(-r * tau)
  13. return inner_func

其中,内部函数 inner_func 作为对象被返回,inner_func 是一个单参数函数。

  1. def testIntegration4():
  2. spot = 100.0
  3. r = 0.03
  4. tau = 0.5
  5. vol = 0.20
  6. strike = 110.0
  7. a = strike
  8. b = strike * 10.0
  9. ptrF = callFunc(spot, strike, r, vol, tau)
  10. absAcc = 0.00001
  11. maxEval = 1000
  12. numInt = ql.SimpsonIntegral(absAcc, maxEval)
  13. print("Call Value: ", numInt(ptrF, a, b))
  14. testIntegration4()

与标准 Black-Scholes 公式得出的结果几乎一致。

  1. Call Value: 2.611902550625855

高斯积分

通常,一个 n 点高斯求积通过选取合适的 \(x_i\) 和 \(w_i\)(\(i = 1, ..., n\))产生 2n − 1 阶(或较低阶)多项式的准确积分值构造出来,

\[\int_{-1}^1 f(x)dx \approx \sum_{i=1}^n w_if(x_i)
\]

存在不同类型的权重函数和区间形式,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

  1. def testIntegration2():
  2. gLagInt = ql.GaussLaguerreIntegration(16) # [0,\infty]
  3. gHerInt = ql.GaussHermiteIntegration(16) # (-\infty, \infty)
  4. gChebInt = ql.GaussChebyshevIntegration(64) # (-1, 1)
  5. gChebInt2 = ql.GaussChebyshev2ndIntegration(64) # (-1, 1)
  6. analytical = norm.cdf(1) - norm.cdf(-1)
  7. print('{0:<15}{1}'.format("Laguerre:", gLagInt(norm.pdf)))
  8. print('{0:<15}{1}'.format("Hermite:", gHerInt(norm.pdf)))
  9. print('{0:<15}{1}'.format("Analytical:", analytical))
  10. print('{0:<15}{1}'.format("Cheb:", gChebInt(norm.pdf)))
  11. print('{0:<15}{1}'.format("Cheb 2 kind:", gChebInt2(norm.pdf)))
  1. Laguerre: 0.49999230923944715
  2. Hermite: 0.9999999834745512
  3. Analytical: 0.6826894921370859
  4. Cheb: 0.6827380724493052
  5. Cheb 2 kind: 0.682595292164792

通常 quantlib-python 提供的高斯积分方法只针对固定的区间,例如 \([-1,1]\),如果需要计算其他区间上的积分,需要做特殊的转换,将积分区间和积分函数“绑定”成为一个单参数函数。区间 \([−1, 1]\) 向 \([a, b]\) 的转换相当简单

\[\int_a^b f(x)dx = \frac{b-a}{2} \int_{-1}^1f \left(\frac{b-a}{2}x + \frac{b+a}{2}\right) dx
\]

类似之前的做法,

  1. def Func(f, a, b):
  2. t1 = 0.5 * (b - a)
  3. t2 = 0.5 * (b + a)
  4. def inner_func(x):
  5. return t1 * f(t1 * x + t2)
  6. return inner_func

例子 4

  1. def testIntegration3():
  2. a = -1.96
  3. b = 1.96
  4. gChebInt = ql.GaussChebyshevIntegration(64)
  5. analytical = norm.cdf(b) - norm.cdf(a)
  6. f = Func(norm.pdf, a, b)
  7. print('{0:<15}{1}'.format("Analytical:", analytical))
  8. print('{0:<15}{1}'.format("Chebyshev:", gChebInt(f)))
  9. testIntegration3()
  1. Analytical: 0.950004209703559
  2. Chebyshev: 0.9500271929144378

QuantLib 金融计算——数学工具之数值积分的更多相关文章

  1. QuantLib 金融计算——数学工具之求解器

    目录 QuantLib 金融计算--数学工具之求解器 概述 调用方式 非 Newton 算法(不需要导数) Newton 算法(需要导数) 如果未做特别说明,文中的程序都是 Python3 代码. Q ...

  2. QuantLib 金融计算——数学工具之插值

    目录 QuantLib 金融计算--数学工具之插值 概述 一维插值方法 二维插值方法 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之插值 载入模块 ...

  3. QuantLib 金融计算——数学工具之优化器

    目录 QuantLib 金融计算--数学工具之优化器 概述 Optimizer Constraint OptimizationMethod EndCriteria 示例 Rosenbrock 问题 校 ...

  4. QuantLib 金融计算——数学工具之随机数发生器

    目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ...

  5. QuantLib 金融计算

    我的微信:xuruilong100 <Implementing QuantLib>译后记 QuantLib 金融计算 QuantLib 入门 基本组件之 Date 类 基本组件之 Cale ...

  6. QuantLib 金融计算——高级话题之模拟跳扩散过程

    目录 QuantLib 金融计算--高级话题之模拟跳扩散过程 跳扩散过程 模拟算法 面临的问题 "脏"的方法 "干净"的方法 实现 示例 参考文献 如果未做特别 ...

  7. QuantLib 金融计算——基本组件之 Currency 类

    目录 QuantLib 金融计算--基本组件之 Currency 类 概述 构造函数 成员函数 如果未做特别说明,文中的程序都是 python3 代码. QuantLib 金融计算--基本组件之 Cu ...

  8. QuantLib 金融计算——修复 BatesProcess 中的两个 Bug

    QuantLib 金融计算--修复 BatesProcess 中的两个 Bug 我发现了 BatesProcess 中的两个 Bug: 基类 HestonProcess::factors 的返回值取决 ...

  9. QuantLib 金融计算——QuantLib 入门

    目录 QuantLib 金融计算--QuantLib 入门 简介 主要功能 安装与使用 学习指南 The HARD Way The EASY Way QuantLib 金融计算--QuantLib 入 ...

随机推荐

  1. iis 搭建ftp

    1.打开iis,添加FTP站点 2.在电脑上建立的FTP服务器别的电脑不能访问 关闭防火墙即可访问防火墙 程序员的基础教程:菜鸟程序员

  2. mybatis框架入门程序:演示通过mybatis实现数据库的模糊查询操作

    1. mybatis的基本准备操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2. 根据用户名查询用户信息: (1)映射文件 ...

  3. CSS中float和Clear的使用

    CSS中float和Clear的使用 本文和大家重点讨论一下CSS中Float和Clear属性的使用,一个float对象可以居左或居右,一个设置为float的对象,将根据设置的方向,左移或右移到其父容 ...

  4. 在ceph中:pool、PG、OSD的关系

    原文:http://www.cnblogs.com/me115/p/6366374.html Pool是存储对象的逻辑分区,它规定了数据冗余的类型和对应的副本分布策略:支持两种类型:副本(replic ...

  5. Kubernetes基本原理与示例

    1. Kubernetes介绍 基本概念 Pod Pod是Kubernetes的基本操作单元,把相关的一个或多个容器构成一个Pod,通常Pod里的容器运行相同的应用.Pod包含的容器运行在同一个Nod ...

  6. Web数据挖掘综述

     

  7. 课堂限时训练-简易计算器·mini dc

    课堂限时训练-简易计算器·mini dc 实验题目 采用后缀表达式法,设计一个建议计算器,实现+.-.*./四种运算. 代码实现 码云链接 关键代码部分及结果如下: 实验分析 首先,分析一下后缀表达式 ...

  8. POJ1679 The Unique MST 2017-04-15 23:34 29人阅读 评论(0) 收藏

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29902   Accepted: 10697 ...

  9. java复习小知识(基础不算,有反射,递归)

    顺序选择循环,三种 1.至于循环和递归 循环效率更高,但是递归在处理文件递归的时候更为常见快捷 在java中实现传多参 2.public static void main(String[]  args ...

  10. linux常见命令-查看磁盘空间

    linux查看磁盘使用情况命令 1. 统一每个目录下磁盘的整体情况: df -h 2. 查看指定目录,在命令后直接放目录名,比如查看“usr”目录使用情况:df -h  /usr/ 3. 查看当前目录 ...