QuantLib 金融计算——数学工具之随机数发生器
如果未做特别说明,文中的程序都是 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 变换算法。
均匀分布的随机数发生器主要分两种:
伪随机数
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 金融计算——数学工具之随机数发生器的更多相关文章
- QuantLib 金融计算——数学工具之数值积分
目录 QuantLib 金融计算--数学工具之数值积分 概述 常见积分方法 高斯积分 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之数值积分 载入模 ...
- QuantLib 金融计算——数学工具之求解器
目录 QuantLib 金融计算--数学工具之求解器 概述 调用方式 非 Newton 算法(不需要导数) Newton 算法(需要导数) 如果未做特别说明,文中的程序都是 Python3 代码. Q ...
- QuantLib 金融计算——数学工具之插值
目录 QuantLib 金融计算--数学工具之插值 概述 一维插值方法 二维插值方法 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之插值 载入模块 ...
- QuantLib 金融计算——数学工具之优化器
目录 QuantLib 金融计算--数学工具之优化器 概述 Optimizer Constraint OptimizationMethod EndCriteria 示例 Rosenbrock 问题 校 ...
- 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 入 ...
随机推荐
- halcon的tuple算子功能总结
- 我读《从Paxos到zookeeper分布式一致性原理与实践》
从年后拿到这本书开始阅读,到准备系统分析师考试之前,终于读完了一遍,对Zookeeper有了一个全面的认识,整本书从理论到应用再到细节的阐述,内容安排从逻辑性和实用性上都是很优秀的,对全面认识Zook ...
- Docker添加官方加速源(必须)
在国内使用Docker必须用加速镜像不然的话无论是pull 官方的还是私有的镜像都会WAIT TIME EXCEED 下面给出macos的添加方式,非常简单 macOS 对于使用 macOS 的用户, ...
- PHP 微信公众号开发 - 消息推送
项目微信公众号开发,需要做用户消息推送,记录下来以便日后使用 1,接上一篇文章,可以查看如何获取用户openid PHP 微信公众号开发 - 获取用户信息 2,添加模板消息 3,查看模板详情 根据模板 ...
- asp.net mvc 5框架揭秘(文摘)
第1章 asp.net + mvc 1.1.2 什么是MVC模式: model:对应用状态和业务功能的封装,同时包含数据和行为的领域模型. view:实现可视化界面的呈现并捕捉最终用户的交互操作. c ...
- ceph故障:too many PGs per OSD
原文:http://www.linuxidc.com/Linux/2017-04/142518.htm 背景 集群状态报错,如下: # ceph -s cluster 1d64ac80-21be-43 ...
- Oracle学习笔记(三)
五.操作表 1.表分为行和列 约定:每行数据唯一性,每列数据同类性,每列列名唯一性. 2.数据类型 字符型 -- 固定长度的字符类型 字符类型:CHAR(n)(MAX n=2000).NCHAR(MA ...
- Python + selenium + unittest装饰器 @classmethod
前言 前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间. 于是就想是不是可以 ...
- 基于jCOM搭建Java-微软信息桥梁(上)
本文将重点讨论BEA的Java/COM解决方案,是全文的第一部分,细致分析BEA提供的Java/COM互操作解决方案—jCOM的实现原理. 一.jCOM简介 据Gartner的研究分析,在名列全球前1 ...
- iptables命令(备忘)
语法 iptables(选项)(参数) 选项 -t<表>:指定要操纵的表: -A:向规则链中添加条目: -D:从规则链中删除条目: -i:向规则链中插入条目: -R:替换规则链中的条目: ...