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

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

载入模块

import QuantLib as ql
import scipy print(ql.__version__)
1.12

概述

随机模拟通常从产生均匀分布的随机数开始。假设 \(X \sim U [0, 1]\) 是均匀分布的随机变量。任意分布的随机数通常需要对 \(X\) 施加某种变换得到,一般情况下是用累积分布函数的逆函数 \(F^{−1}\),\(F^{−1}(X)\) 的分布就是 \(F\)。其他的变换算法可能不需要 \(F^{−1}\),比如用于生成正态分布的 Box Muller 变换算法。

均匀分布的随机数发生器主要分两种:

  • 伪随机数(wiki
  • 拟随机数,也称低偏差序列(wiki

伪随机数

quantlib-python 提供了以下三种均匀分布的(伪)随机数发生器:

  • KnuthUniformRng,高德纳(Knuth)算法
  • LecuyerUniformRng,L'Ecuyer 算法
  • MersenneTwisterUniformRng,著名的梅森旋转(Mersenne-Twister)算法

随机数发生器的构造函数,

Rng(seed)

其中

  • seed,整数,默认值是 0,作为种子用于初始化相应的确定性序列;

随机数发生器的成员函数:

  • next():返回一个 SampleNumber 对象,作为模拟的结果。
r = rng.next()
v = r.value(r)

用户通过反复调用成员函数 next() 获得一连串的随机数,需要注意的是 r 的类型是 SampleNumber,需要调用 value() 得到对应的浮点数。

例子 1,

def testingRandomNumbers1():
seed = 1 unifMt = ql.MersenneTwisterUniformRng(seed)
unifLec = ql.LecuyerUniformRng(seed)
unifKnuth = ql.KnuthUniformRng(seed) print('{0:<25}{1:<25}{2:<25}'.format(
'Mersenne Twister', 'Lecuyer', 'Knut')) for i in range(10):
print('{0:<25}{1:<25}{2:<25}'.format(
unifMt.next().value(),
unifLec.next().value(),
unifKnuth.next().value())) testingRandomNumbers1()
Mersenne Twister         Lecuyer                  Knut
0.41702199855353683 0.2853808990946861 0.4788952510312594
0.9971848082495853 0.2533581892659171 0.7694635535665499
0.7203244894044474 0.09346853100919404 0.47721285286866455
0.9325573613168672 0.6084968907396475 0.15752737762851
0.00011438119690865278 0.90342026007861 0.6065713927733087

正态分布(伪)随机数

随机模拟中最常见的分布是正态分布,quantlib-python 提供的正态分布随机数发生器有 4 类:

  • CentralLimitABCGaussianRng
  • BoxMullerABCGaussianRng
  • MoroInvCumulativeABCGaussianRng
  • InvCumulativeABCGaussianRng

其中 ABC 特指一种均匀随机数发生器。

具体来讲 4 类发生器分为 12 种:

  • CentralLimitLecuyerGaussianRng
  • CentralLimitKnuthGaussianRng
  • CentralLimitMersenneTwisterGaussianRng
  • BoxMullerLecuyerGaussianRng
  • BoxMullerKnuthGaussianRng
  • BoxMullerMersenneTwisterGaussianRng
  • MoroInvCumulativeLecuyerGaussianRng
  • MoroInvCumulativeKnuthGaussianRng
  • MoroInvCumulativeMersenneTwisterGaussianRng
  • InvCumulativeLecuyerGaussianRng
  • InvCumulativeKnuthGaussianRng
  • InvCumulativeMersenneTwisterGaussianRng

随机数发生器的构造函数:

rng = Rng(seed)
grng = Gaussianrng(rng)

正态分布随机数发生器接受一个对应的均匀分布随机数发生器作为源,以 BoxMullerMersenneTwisterGaussianRng 为例,需要配置一个 MersenneTwisterUniformRng 对象作为随机数的源,使用经典的 Box-Muller 算法得到正态分布随机数。

例子 2,

def testingRandomNumbers2():
seed = 12324
unifMt = ql.MersenneTwisterUniformRng(seed)
bmGauss = ql.BoxMullerMersenneTwisterGaussianRng(unifMt) for i in range(5):
print(bmGauss.next().value()) testingRandomNumbers2()
-1.1756781173398896
0.14110041851886157
1.569582906805544
-0.026736779238941934
-0.8220676600472409

拟随机数

相较于之前描述的“伪”随机数,随机模拟中另一类重要的随机数成为“拟”随机数,也称为低偏差序列。因为收敛性更好,拟随机数通常用于高维随机变量的模拟。quantlib-python 提供的拟随机数有两类,

  • HaltonRsg: Halton 序列
  • SobolRsg: Sobol 序列

HaltonRsg

HaltonRsg 的构造函数,

HaltonRsg(dimensionality,
seed,
randomStart,
randomShift)

其中,

  • dimensionality:整数,设置维度;
  • seed,整数,默认值是 0,作为种子用于初始化相应的确定性序列;
  • randomStart:布尔值,默认是 True,是否随机开始;
  • randomShift:布尔值,默认是 False,是否随机平移。

HaltonRsg 的成员函数,

  • nextSequence():返回一个 SampleRealVector 对象,作为模拟的结果;
  • lastSequence():返回一个 SampleRealVector 对象,作为上一个模拟的结果;
  • dimension():返回维度。

SobolRsg

SobolRsg 的构造函数,

SobolRsg(dimensionality,
seed,
directionIntegers=Jaeckel)

其中,

  • dimensionality:整数,设置维度;
  • seed,整数,默认值是 0,作为种子用于初始化相应的确定性序列;
  • directionIntegers,quantlib-python 的内置变量,默认值是 SobolRsg.Jaeckel,用于 Sobol 序列的初始化。

SobolRsg 的成员函数,

  • nextSequence():返回一个 SampleRealVector 对象,作为模拟的结果;
  • lastSequence():返回一个 SampleRealVector 对象,作为上一个模拟的结果;
  • dimension():返回维度。
  • skipTo(n)n 是整数,跳转到抽样结果的第 n 个维度;
  • nextInt32Sequence():返回一个 IntVector 对象。

例子 3,

def testingRandomNumbers4():
dim = 5
haltonGen = ql.HaltonRsg(dim)
sobolGen = ql.SobolRsg(dim) sampleHalton = haltonGen.nextSequence().value()
sampleSobol = sobolGen.nextSequence().value() print('{0:<25}{1:<25}'.format(
'Halton', 'Sobol')) for i in range(dim):
print('{0:<25}{1:<25}'.format(
sampleHalton[i],
sampleSobol[i])) testingRandomNumbers4()
Halton                   Sobol
0.04081786540336907 0.5
0.8535710143553551 0.5
0.69400573329408 0.5
0.818105927979147 0.5
0.878826694887864 0.5

两类随机数的收敛性比较

最后用一个例子比较两类随机数的收敛性,分别产生正态分布的伪随机数和拟随机数,计算分布的四个统计指标:

  • 均值(理论值等于 0.0);
  • 方差(理论值等于 1.0);
  • 偏度(理论值等于 0.0);
  • 超额峰度(理论值等于 0.0)。
def testingRandomNumbers5():
sobolGen = ql.SobolRsg(1) seed = 12324
unifMt = ql.MersenneTwisterUniformRng(seed)
bmGauss = ql.BoxMullerMersenneTwisterGaussianRng(unifMt) boxMullerStat = ql.IncrementalStatistics()
sobolStat = ql.IncrementalStatistics() invGauss = ql.MoroInverseCumulativeNormal() numSim = 10000 for j in range(numSim):
boxMullerStat.add(bmGauss.next().value())
currSobolNum = sobolGen.nextSequence().value()[0]
sobolStat.add(invGauss(currSobolNum)) stats = {
"BoxMuller Mean:": boxMullerStat.mean(),
"Sobol Mean:": sobolStat.mean(),
"BoxMuller Var:": boxMullerStat.variance(),
"Sobol Var:": sobolStat.variance(),
"BoxMuller Skew:": boxMullerStat.skewness(),
"Sobol Skew:": sobolStat.skewness(),
"BoxMuller Kurtosis:": boxMullerStat.kurtosis(),
"Sobol Kurtosis:": sobolStat.kurtosis()} for k, v in stats.items():
print('{0:>25}{1:>30}'.format(k, v)) testingRandomNumbers5()
          BoxMuller Mean:          0.005966482725988245
Sobol Mean: -0.0002364019095203635
BoxMuller Var: 1.0166044844467006
Sobol Var: 0.9986010126883317
BoxMuller Skew: 0.02100635339070779
Sobol Skew: -7.740573185322994e-05
BoxMuller Kurtosis: -0.0340476839897507
Sobol Kurtosis: -0.020768126049145776

直观上看 Sobol 序列的结果更加接近理论值,这证明使用拟随机数做模拟的收敛速度更好。

QuantLib 金融计算——数学工具之随机数发生器的更多相关文章

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

    目录 QuantLib 金融计算--数学工具之数值积分 概述 常见积分方法 高斯积分 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之数值积分 载入模 ...

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

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

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

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

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

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

  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记录

    IIS中SSL配置.导入:http://www.cnblogs.com/whitewolf/archive/2010/07/07/1773066.html

  2. Windows10远程桌面连接配置

    被控电脑在TP-Link路由器 1.基本设置 被控端电脑设置:1)被控端的电脑系统需要是Windows专业版或者企业版,家庭中文版的系统是不支持远程访问功能的: 2)被控端打开远程桌面功能,在系统的设 ...

  3. 判断字符串是否为回文 python

    回文正序和逆序一样的字符串,例如abccba 方法一 def is_palindrome1(text): l = list(text) l.reverse() t1 = ''.join(l) if t ...

  4. ManualResetEvent,AutoResetEvent说明

    相信不少人对ManualResetEvent,AutoResetEvent的状态比较晕,下面是本人认为最精简的理解 1.只有2种状态,终止态 And 非终止态 终止状态,既然是状态那么一定对应事物,这 ...

  5. python sublime run快捷键设置

    一.Ctrl+Shift+P进行插件“sublimeREPL”安装 二.打开preferences->Key Binding-User,写入以下内容 [ { "keys": ...

  6. 程序员不常用Linux命令集

    1) 关闭指定网卡,如关闭网卡eth0 ifconfig eth0 down 也可以使用ifdown,通常ifdown是一个指向ifup的软链接,而ifup为一个脚本文件. 2) 命令自启动,如希望机 ...

  7. 4D(DLG,DRG,DOM,DEM)

    基于“倾斜+LiDAR+车载”的实景三维建模实现:链接 MapGIS数据可不可以做到数据融合 遥感影像

  8. Codeforces758C Unfair Poll 2017-01-20 10:24 95人阅读 评论(0) 收藏

    C. Unfair Poll time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. 【PAT】1063. Set Similarity (25) 待改进

    Given two sets of integers, the similarity of the sets is defined to be Nc/Nt*100%, where Nc is the ...

  10. WinExec打开exe文件

    1,WinExec():   WinExec主要运行EXE文件,不能运行其他类型的文件.不用引用特别单元.   原型:UINT WinExec(exePath,ShowCmd)   示例,我想要用记事 ...