金融工程与并行计算:第二章 仿真法在财务工程的使用 Part 1

Anyone attempting to generate random numbers by deterministic means is, of course,living in a state of sin.

任何人想要以确定的方式产生随机随机数,则不异于活于罪恶之邦。

 John von Neumann

约翰˙˙纽曼


第一节 蒙地卡罗模拟法概要

对于一个不确定的随机现象,我们通常会以机率的方式加以描述。例如,一年后(期末)的大盘指数(PT),相对于今日(期初)指数(P0= 8,000)可能有60%的上涨。然而,如果想要有更进一步的说明,则我们可能要对随机现象中的变量,有更明确的假设。

我们可以假设随机变量X表一年后的对数报酬率,具有常态分配的性质,且其年平均数为4%,年标准偏差为30%。则X表示如下,

…………………………………………………(2.1.1)

由于常态分配的性质已广为人知,所以X的未来分布情况也可自然可以得知。例如,X的平均数为0.04。因此,一年后指数的平均数为,

再如,X的1%的单边最大损失为,

此时对应的一年后指数为,

换句话说,有1%的机率一年后的指数会跌到4139以下。


然而,如果我们创造了一张一年期的金融契约,它的期末偿付为,

…………………………………………………….(2.1.2)

我们想要知道此金融契约一年后1%的最大损失,或是期末偿付的平均数,那就不是一件简单的事情了。一方面,期末偿付函数为一具有max()函数形式的随机变量;另一方面,max()函数之中包含了期末指数的一次式与二次式。

但是,如果我们已经知道期末指数的分配形式(2.1),我们可以反复的由随机数中,抽取随机变量X值,X0,X1,X2,…,XN。再由X得到PT,代入(2.1.2)式的期末偿付,便可得到期末偿付的出象。据以描绘出期末偿付的分布型式,并求的相关的统计量,如平均数、标准偏差、1%最大损失等。

上述方法便是蒙地卡罗模拟法的基本精神,然而此法的成功与否,仰赖于下面条件。首先,随机变量X的分配假设是正确无误的。其次,随机数的抽取确实反映了随机随机数的要求。前者的正确性需要由财务理论与数据实证来回答。后者则须要数值方法与统计理论来回答。

在过去40年中,Black-Scholes的选择权定价理论,主导了前20年的金融市场,1993的Heston模型可说是另一个新的里程碑。本书将以Heston模型为主轴来说明,但是在进入第二篇的内容之前,我们还是以Black-Scholes模型做为程序说明与撰写对象。毕竟这是大部分金融从业人员都已熟悉的内容,也是现代金融的基石。


第二节 C#开发环境介绍与使用内建随机数

由于随机数的质量在仿真时至关紧要,因此我们须对计算机如何产生随机数,详加探究。我们先使用程序内建随机数,然后再使用市场上已有口碑的高质量随机数生成器。程序的撰写是必然的事,本节简单说明使用的环境,并测试我们的讨论内容。读者如果对开发环境不熟悉,建议找一本介绍VisualStudio与C#入门使用的书籍。

大部分的程序语言在内建的函数中,都有随机数函数。在C#亦有提供此一随机数对象,Random,此对象位于System的命名空间之下。使用时需先建立对象,对象初始化时可以给起始种子,也可以不给起始种子。如果不给起始种子,程序会以系统时间作为起始种子。

下面以Visual Studio2017作为开发环境,说明如何使用系统内建Random对象。首先,打开Visual Studio2017,从功能选单中《档案╱新增╱项目》的方法,产生CPUST方案以及CSRandom项目,选取控制台应用程序,按确定。


Visual Studio自动为我们完成项目框架的设定如上图,在中央的程序代码编辑区,输入下面的程序代码。

#001 static void Main(string[] args)

#002 {

#003     const int OBS =100000;

#004     Random Rnd = new Random(1234);

#005     double[] X = new double[OBS];

#006

#007     for (int i = 0; i< OBS; i++)

#008     {

#009        X[i] = Rnd.NextDouble();

#010     }

#011

#012     double Sum = 0.0;

#013     for (int i = 0; i< OBS; i++)

#014     {

#015        Sum = Sum + X[i];

#016     }

#017     double Mean = Sum / OBS;

#018     

#019     Sum = 0.0;

#020     for (int i = 0; i< OBS; i++)

#021     {

#022        Sum = Sum + (X[i] - Mean) * (X[i] - Mean);

#023     }

#024     double Var = Sum / (OBS - 1);

#025     

#026     Console.WriteLine("Meanof Uniform(0, 1) = " + Mean.ToString());

#027     Console.WriteLine("Varianceof Uniform(0, 1) = " + Var.ToString());

#028     Console.ReadKey();

#029 }

程序行表2.1

 

以鼠标点选左侧方案总管中的CSRandom项目,从功能选单中《建置╱建置CSRandom》的方法,编译项目。我们可以看到画面左下方的讯息列出现建置成功的讯息。按F5快捷键,执行程序画面如下。


 程序代码#003首先定义100,000个观察值,#004中产生Random对象,我们以1234作为起始随机数传入来初始化对象。#005宣告X数组储存产生的随机数值。#007~#010为呼叫产生随机数的回圈。我们在#009叫用NextDouble()方法,产生Uniform(0,1)的均等随机数,十万个。#012~#017计算X数组的平均数,#019~#024计算X数组的变异数。#026输出平均数,#027输出变异数。#028的用途是我们由VisualStudio中执行此程序后,不会输出后立刻关闭,它会等我们按下任一按键后,才会关闭。

由维基百科中可得知,Uniform(a, b)的均等随机数,平均数与变异数分别为,

相较于模拟的输出结果,误差分别为0.000871与0.000024。误差百分比为0.1742%与0.0288%。

 

 

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值