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

import QuantLib as ql
import scipy

print(ql.__version__)

1.12


## 概述

• 伪随机数（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)


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


## 正态分布（伪）随机数

• CentralLimitABCGaussianRng
• BoxMullerABCGaussianRng
• MoroInvCumulativeABCGaussianRng
• InvCumulativeABCGaussianRng

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

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


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


## 拟随机数

• 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 对象。

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):
currSobolNum = sobolGen.nextSequence().value()[0]

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


## 扩展阅读

《QuantLib 金融计算》系列合集

posted @ 2018-12-16 00:08  xuruilong100  阅读(1122)  评论(0编辑  收藏  举报