金融工程与并行计算:第二章 仿真法在财务工程的使用 Part 3
第四节 资产过程的描述与离散化
现代财务模型大都以连续交易作为分析的架构,亦即,交易是连续进行,两次交易间的时间间隔为无限小,因此称之为连续时间财务。然而,当我们要进行模拟时,却是必须将之离散化。这是因为在实际进行模拟时,我们只能以有限的步数,仿真期末资产可能的价格。也因此,每次模拟的时间跨距(Time Interval)是有限的,而非无限小。这种以有限间隔的仿真实作,取代模型中间隔无限小的假设,称之为离散化(Discretization),实务最常使用的是尤拉法(Euler Schemes)。另外尚有两个较为精细的方法,分别是Milstein Schemes与二阶法(Second-Order Method),然而由于效率上的考虑,实务上使用的机会不大。
一、尤拉法
以传统的Black-Scholes模型为例,
…………………………………………………………..(2.4.1)
最简单的离散化为尤拉法的离散化,
,
,
,
,
因此,可得下面的迭代模拟方程式。
…………………………………………(2.4.2)
(2.4.1)式可以改写如下,
……………………………………………………………….…(2.4.3)
(2.4.3)式的随机微分方程式,在给定期初资产价格S0下,可以求得期末价格ST的移转方程式如下,
…………………………………………....…(2.4.4)
由于,(2.4.4)式是公式解,因此不论时间跨距长短,都可以直接用来仿真期末价格。实务上,十万次的模拟是一般的要求。
(2.4.2)式的差分方程式,在给定期初资产价格S1下,可以求得期末价格S2的移转方程式如下,
……………………………………………(2.4.5)
通常,我们以一天走一步的方式来进行模拟。因此,如果到期时间为一年,则一条仿真的路径要走365步。十万条的路径应该是可以接受的模拟量。
二、Milstein法
三、二阶法
第五节 C#单资产风险中立的模拟
在CPUBSProcess方案中,STBSProcess项目,我们以Black-Scholes资产价格程序为仿真的对象,
然而,实际在进行模拟时,我们采用(2.4.5)式一天一步的方式来模拟,
模拟的期限为一年,为了配合一些市场上交易契约的条件,我们假定需要一个月进行一次的比价。
假定起始日为2014/7/1,我们首先计算未来十二个比价的日期,与2014/7/1相减,算出每一比价日期要走的步数。因此我们要记录2014/8/1,2014/9/1,2014/10/1,2014/11/1,2014/12/1,2015/1/1,2015/2/1,2015/3/1,2015/4/1,2015/5/1,2015/6/1,2015/7/1等日的汇率价格。下面程序使用两个循环来控制模拟的进行,外循环控制仿真的路径,一共512*256条路径。内回圈控制每一步的进行,一共365步,同时把12个比价日的汇率纪录下来。
一、风险中立订价理论:鞅性方法
令Rt为一证券之t期之报酬率, rt为无风险报酬率,RP表风险溢酬,令E[RP]=α。则一证券之报酬率包含无风险报酬率与风险溢酬两个成分。
…………………………............................…………...(2.5.1)
如果我们用Rt作为该证券之折现率,则此证券之t期市场价格可由下式求得,
……………………………………………...............................(2.5.2)
然而,由于Rt本身可能无法事前确定,因此我们不能直接使用(2.5.2)式计算证券t期之市场价格。
令t期无风险债券Bt =1,则Bt+1 =1+rt。令Xt = St / Bt,如果我们经过某种方式处理,得到Et[Xt+1]= Xt。由于rt可由市场上直接观察得到,因此Xt本身的计算没有困难。
Et[Xt+1|Xt ] = Xt,此性质称为鞅性(Martingale),又称之为一公平赌局(Fair Game)。如果我们将Xt视为t期末之财富,则t+1期末之财富的期望值Et[Xt+1|Xt ],等于t期末之财富。因此,t+1期的赌局是一个公平的赌局,参与者由此赌局赚得的财富期望值为零。
近代财务理论使用机率测度转换的方法,以零息债券价格为计价单位,得到鞅性的良好性质。由此性质,得到衍生商品定价的一般理论,这也提供我们使用仿真方法计算选择权价格理论基础。使我们回避掉估计证券风险溢酬的难题。下面说明模拟法实作的细节,至于有关鞅性定价理论的细节,有兴趣的读者可参考Neftci(2002)的说明。
二、实作的方法
考虑欧式选择权,依据风险中立定价法,到期日为T,目前时间为t=0,我们可以下式估算期初选择权价值,
…………………….…………………….............................(2.5.3)
若利率为固定不变,可简化为
……………………..……………….............................………(2.5.4)
模拟M次,求平均数可得估计值
…………………………………………………............................…(2.5.5)
依据风险中立定价法,股价过程为
若目前价格为S0,未来T的价格为ST,则Ln(ST)为一常态分配,其平均数与标准偏差分别为
,
…………….………..............................………….….(2.5.6)
Ln(ST/S0) 为服从下述之常态分配
…………….………………….................................(2.5.7)
估计值的误差为
…………………….…………….………...........................…….(2.5.8)
其中
……………………….....................................….(2.5.9)
三、Black-Scholes解析解公式
在Black-Scholes股票选择权的公式中,他们基于无套利的条件,使用了风险中立的评价与(2.4.1)的股价随机程序。其步骤为
1.假设股价的预期收益为无风险资产的收益率r。
2.计算选择权在到期日时预期的偿付。
3.以无风险资产的收益率折现该偿付。
藉由上述的分析,Black和Scholes利用偏微分方程式,推导出了不支付股利股票的欧式买、卖权公式。买权和卖权价格公式分别为
………………………………………….........................(2.5.10)
…………...………………………..........................…(2.5.11)
其中
………………………..………………..........................(2.5.12)
............................…………..……………..(2.5.13)
S = 目前股价,
K = 执行价格,
r = 融资利率为即期利率,
T = 距到期日的时间,
= 股价之波动性,
N(x)函数为标准常态变量之累积机率函数。
#001 namespace STBSProcess
#002 {
#003 public partial class Form1 : Form
#004 {
#005 public Form1()
#006 {
#007 InitializeComponent();
#008 }
#009 private voidbutton2_Click(object sender, EventArgs e)
#010 {
#011 Application.Exit();
#012 }
#013 const intBlocksPerGrid = 256;
#014 const intThreadsPerBlock = 512;
#015 static int NPath =ThreadsPerBlock * BlocksPerGrid; //131,072 Paths
#016 static int MStep =13;
#017 static DateTime RefDate;
#018 static List<DateTime> FixingDate;
#019 static int[]h_StepGrid;
#020 double[,] S = new double[NPath, MStep];
#021 double[] Value = new double[NPath];
#022 private voidbutton3_Click(object sender, EventArgs e)
#023 {
#024 double Asset = 100.0;
#025 double Strike = 100.0;
#026 double TTM = 1.0;
#027 double Sigma = 0.3;
#028 double Rate = 0.04;
#029 double Yield = 0.02;
#030 double dt = 1.0 / 365.0;
#031 // Analytic Benchmark
#032 double d1 = (Math.Log(Asset / Strike)
#033 + (Rate - Yield + 0.5 * Sigma * Sigma) * TTM)
#034 / (Sigma * Math.Sqrt(TTM));
#035 double d2 = d1 - Sigma * Math.Sqrt(TTM);
#036 double CValue = Asset * Math.Exp(-Yield* TTM) * DStat.NormDist(d1)
#037 - Strike * Math.Exp(-Rate * TTM) * DStat.NormDist(d2);
#038 double PValue = Strike * Math.Exp(-Rate* TTM) * DStat.NormDist(-d2)
#039 - Asset * Math.Exp(-Yield * TTM) * DStat.NormDist(-d1);
#040 //Random Rnd =new Random(1234);
#041 MersenneTwister Rnd = newMersenneTwister(1234);
#042 Stopwatch SW = new Stopwatch();
#043 RefDate = new DateTime(2014, 7, 1);
#044 FixingDate = new List<DateTime>();
#045 //MStep depend on the remaining FixingDayNumber, Including RefDate
#046 // 0, 1, 2,..., 12, 0 for RefDate
#047 for (inti = 0; i < MStep; i++)
#048 {
#049 FixingDate.Add(RefDate.AddMonths(i));
#050 }
#051 h_StepGrid = new int[MStep];
#052 for (inti = 0; i < MStep; i++)
#053 {
#054 TimeSpan TS = FixingDate[i].Subtract(RefDate);
#055 h_StepGrid[i] = (int)TS.TotalDays;
#056 }
#057 double s1, n1;
#058
#059 SW.Start();
#060 for (inti = 0; i < NPath; i++)
#061 {
#062 s1 = Asset;
#063 int diff = 0;
#064 S[i, 0] = s1;
#065 for (intj = 0; j < (MStep - 1); j++)
#066 {
#067 diff = h_StepGrid[j + 1] -h_StepGrid[j];
#068 for(int k = 0; k < diff; k++)
#069 {
#070 n1 =DStat.N_Inv(Rnd.NextDouble());
#071 s1 = s1 *Math.Exp(((Rate-Yield) - (Sigma*Sigma)/2.0) * dt
#072 + (Sigma *Math.Sqrt(dt) * n1));
#073 }
#074 S[i, j + 1] = s1;
#075 }
#076 Value[i] = Math.Max(s1 - Strike, 0);
#077 }
#078 double sum = 0.0;
#079 for (inti = 0; i < NPath; i++)
#080 {
#081 sum = sum + Value[i];
#082 }
#083 sum = (sum / NPath) * Math.Exp(-(Rate - Yield) * TTM);
#084 SW.Stop();
#085
#086 double gap = sum - CValue;
#087 double ratio = (gap / CValue) * 100.0;
#088 textBox1.Text = SW.ElapsedMilliseconds.ToString();
#089 textBox2.Text = CValue.ToString();
#090 textBox3.Text = sum.ToString();
#091 textBox4.Text = gap.ToString();
#092 textBox5.Text = ratio.ToString();
#093 listBox1.Items.Clear();
#094 for (intj = 0; j < MStep; j++)
#095 {
#096 listBox1.Items.Add(S[0, j].ToString());
#097 }
#098 }
#099 }
#100 }
程序行表2.5
执行结果如上图,运算时间约5.8秒,模拟值为12.8400,与解析解的理论值12.5677,误差值为0.2723,误差百分比约2.2%上下。我们也把前十个仿真路径的值,作图输出,可以看到整个路径上标的资产价格的变化。