一、二叉树模型中的参数估计1.1 二叉树参数估计算法原理想要预测股价二叉树,在知道初始值的前提下,还需要知道模型中的的u 和d ,但对于一支只知道对应于日期的股票价格,我们应该进行怎样的数据处理呢?下面通过实证数据对二叉树模型中的参数进行估计。
原理:Hull-White 算法令21=p ,并用如下公式计算u 和d: t d u ii tdu i ∆=-∆+=+σμ2)(12)( 我们假设:kk k S X S S X S 11011++==,这里k X 是独立的伯努利随机变量,21]/Pr[]/[Pr 11=====--d S S u S S k k k k 则我们可以得出t u ∆和t ∆2σ的合理估计值为:∑∑=-=-=-=nk k k n k k S S n X n U 111)1/(1)1(1其中:])1/([1112212∑=----=nk k k U n S S n sU 和2s 是来自实际市场数据n S S S S ,,、、 210的样本均值和样本方差,我们可以得出u 和σ的估计值为:t s t Uu ∆≈∆≈σ 则:tt d t t u ∆-∆+=∆+∆+=σμσμ111.2举例应用我选用中国农业银行2013年的股票价格,具体数据见附件1.由表可知,001986.01001986.1=-=U ,010568.0=s ,这个二叉树中所用的t ∆和与数据的t ∆相同,公式u 和d 可以简化成:56.550.9914181 1.01255410==-+==++=S s U d s U u做4期二叉树图为:这里的t ∆是一天,我们通过选择更大的时间间隔,令7=∆t ,即以一周为一个时间段,则有:56.550.977293)7()7(1 1.033215)7()7(10==-+==++=S s U d s U u4期二叉树图变为:再15=∆t 令即以半个月为一个时间段,则有:1.07072)15()15(1=++=s U u988858.0)15()15(1=-+=s U d56.550=S4期二叉树图又变为:由于该题的t ∆可以改变,时间间隔越长,股价“分叉”得更快。
二、 几何布朗运动估计与模拟2.1几何布朗运动参数估计原理令)(t S 代表某股票在t 时刻的价格,由以下公式给出S 的模型。
SdB Sdt dS σμ+=其中,σμ、是常量,B 服从布朗运动,而该方程的解就是几何布朗运动。
即:])2/(ex p[20t B S S t t σμσ-+=其中,t B 是均值为0,方差为t 的正态随机变量,由此得到的就是股价的几何布朗运动模型。
我们将采用修正的股价模型对欧式看涨期权进行定价,在此之前,要对股价模型进行参数估计,即波动率σ和漂移率μ。
假设我们得到了在一段较长时间[0, T]内的股价数据记录,这段时间由n 个长度相等的子区间t ∆组成,再假设我们知道每个子区间末的股价,将股价表示为:S i :第i 个子区间末的股价 样本观测值为n+1个; 令U 表示均值,则:∑=-=ni iUn U 11样本方差用S 2表示,则:2112)()1(∑=---=ni iU Un S而U 的观测值的均值为t ∆-)2/(2σμ,方差为t ∆2σ。
即:t U ∆-=)2/(2σμt S ∆=22σ 最后算的参数μ和σ为:tS U ∆+=2/2μ及t S ∆=/σ而对于t B ,则需要随机产生一系列标准正态分布,通过累加处理获得计算所需要的值。
也可运用对数正态分布模型,即:2(/2)0T W TT S S eσμσ+-=其中,T W 是一个均值为0,方差为T 的随机正态分布变量,T W 的获取与t B 相仿。
2.2举例应用我选用中国农业银行2013年的股票价格,具体数据见附件2.计算股价,先随机生成均值为0,方差为n t ∆的正态分布随机数,而后进行处理生成预测值,结果如下:而后将预测值与实际值进行比较,得到:根据图可直观地看出,预测值的波动率比较大,整个曲线趋势很不平稳,因此需要进行修正;于是,再随机生成均值为0,方差为1的标准正态分布随机数,而后进行处理生成预测值,结果如下:而后将预测值与实际值进行比较,得到:由此可以看出,拟合程度还是很好的,可以用来预测未来几期的股票价格。
预测未来两个月的股价,结果如下:三、B-S 模型及多期二叉树的期权定价3.1.B-S 期权定价公式:假设有一股票现价为0S ,V 是看涨期权的价格,无风险利率股价漂移率股价波动率到期时间执行价=====r X μσT看涨期权V 值可表示为:)()(210d N Xe d N S V rT --= 其中:2/22011()[]2ln(/)(/2)x x N x P Z x e dx S X r T d T πσσ--∞=≤=++=⎰21d d Tσ=-对于欧式看跌期权的价格P ,可表示为:012()()rT P S N d Xe N d -=--+-;3.2举例应用我选用了2013年11月16日的执行价,而后通过运用BS 公式及多期二叉树计算期权价格的方式,将实际值与两方法的预测值进行比较,而后进行分析,详细数据见附件3。
计算结果数据:再将预测所得数据与实际值进行拟合比较,得到如下图:从该图主观地看出,三种期权的价格的趋势基本上一致,拟合程度也比较高,但对来说,BS 的拟合程度更好一点。
这样相对来说主观了一点,接着对数据进行再一次的处理分析:最后算的,多期二叉树的预测误差的方差为:0.162756979,而几何布朗运动的预测误差的方差为:0.15752995 ,由此也可以得出,几何布朗运动拟合程度更好一些。
四、对冲4.1做题思路计算对冲,即计算∆值,1()N d ∆=,而201d τσ=,对一只股票,在一年的时间里,假设我们每周进行一次对冲,那每周相应的对冲值又该如何计算呢?在解这个题目时,最重要的计算出0S 的值,在第一周时,0S 为初始价,但到了第二周,0S 有所变动,它的值为:20exp((/2))T T S S W T μμσ=+-,而对于τ,其值等于到期时间周数与总周期数的比值。
对于T W ,先产生随机数,而后再将它转换为正态分布随机数。
4.2举例应用对于附件2里的数据,T=0.51506849,S0=55.56,X=50,sigma=0.20203053, miu=0.724348005,r=0.04, 假设卖出1000股股票,在这样的情况下,实现对冲为:课程小结:对于金融数学这门课程,一个多星期的计算机操作,让我惊叹。
突然间才发现,这是一门综合性特别强的学科,才明白自己在某些知识点的掌握上拿捏得不是很好,所以做起来还是有一定的挑战性的,可能在学习理论知识的时候,这样的缺陷不是暴露的特别明显。
一开始决定编写C语言,是因为自己电脑上安装了这一软件,如果赶不上进度自己可以补一下,最后才发现自己这一举动是那么的正确,因为自己在C这方面学的不扎实,下课后,我还不得不窝在电脑前一次次修改程序,不过看到自己的程序可以完美实现的时候,真的真的特别开心,“废寝忘食”的程序员生活,稍稍体验了一把,才可以懂得他们为什么会有很大的情绪波动。
在做这个课程设计的时候,最麻烦的是计算积分与产生正态分布随机变量,这个涉及到了数值计算方法和概率统计的知识,自然,C语言是基础,在计算积分的时候,我运用了复合梯形公式,但在n的取值上遇到了一点问题,不能很好地把握它的取值。
在后面进行分析比较时,我运用了统计预测与决策的相关知识。
总的来说,这一个星期真的过的特别充实,懂得了时间的概念。
但是时间比较紧张,我们要做的内容又比较多,做的还是不够精细。
附录源程序如下:欧式看涨期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 200main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t,w,v;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");scanf("%f",&X);printf("请输入期数n:\n");scanf("%d",&n);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%.6lf ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]>X)a[n][j]=a[n][j]-X;elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);printf("%.6lf ",a[k][j]);}printf("\n");}printf("欧式看涨期权定价为: ");printf("%f \n",a[0][1]);}}欧式看跌期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 200main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t, w,v;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");scanf("%f",&X);printf("请输入期数n:\n");scanf("%d",&n);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%f ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]<X)a[n][j]=X-a[n][j];elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);printf("%f ",a[k][j]);}printf("\n");}printf("欧式看跌期权定价为: ");printf("%f \n",a[0][1]);}}欧式向上敲出障碍看跌期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 200main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t,w,v,Q;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");scanf("%f",&X);printf("请输入期数n:\n");scanf("%d",&n);printf("请输入向上敲出障碍期权Q:\n");scanf("%f",&Q);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%f ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]<X&&a[n][j]<Q)a[n][j]=X-a[n][j];elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){if(a[k][j]<Q)a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);elsea[k][j]=0;printf("%f ",a[k][j]);}printf("\n");}printf("欧式向上敲出障碍看跌期权定价为: ");printf("%f \n",a[0][1]);}}欧式向上敲出障碍看涨期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 200main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t,w,v,Q;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");scanf("%f",&X);printf("请输入期数n:\n");scanf("%d",&n);printf("请输入向上敲出障碍期权Q:\n");scanf("%f",&Q);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%f ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]>X&&a[n][j]<Q)a[n][j]=a[n][j]-X;elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){if(a[k][j]<Q)a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);elsea[k][j]=0;printf("%f ",a[k][j]);}printf("\n");}printf("欧式向上敲出障碍看涨期权定价为: ");printf("%f \n",a[0][1]);}}欧式向下敲出障碍看跌期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 200main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t,w,v,Q;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");printf("请输入期数n:\n");scanf("%d",&n);printf("请输入向下敲出障碍期权Q:\n"); scanf("%f",&Q);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%f ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]<X&&a[n][j]>Q)a[n][j]=X-a[n][j];elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){if(a[k][j]>Q)a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);elsea[k][j]=0;printf("%f ",a[k][j]);}}printf("欧式向下敲出障碍看跌期权定价为: ");printf("%f \n",a[0][1]);}}欧式向下敲出障碍看涨期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 200main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t,w,v,Q;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");scanf("%f",&X);printf("请输入期数n:\n");scanf("%d",&n);printf("请输入向下敲出障碍期权Q:\n");scanf("%f",&Q);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%f ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]>X&&a[n][j]>Q)a[n][j]=a[n][j]-X;elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){if(a[k][j]>Q)a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);elsea[k][j]=0;printf("%f ",a[k][j]);}printf("\n");}printf("欧式向下敲出障碍看涨期权定价为: ");printf("%f \n",a[0][1]);}}美式看跌期权:#include "stdio.h"#include "stdlib.h"#include "math.h"#define N 100main(){ int n,k,j;float s0,i,X,u,d,r,q,p,t,w,v,T;float a[N][N+1];printf("请输入初始价s0:\n");scanf("%f",&s0);printf("请输入每期利率i:\n");scanf("%f",&i);printf("请输入增长因子u:\n");scanf("%f",&u);printf("请输入下降因子d:\n");scanf("%f",&d);printf("请输入执行价X:\n");scanf("%f",&X);printf("请输入期数n:\n");scanf("%d",&n);r=exp(-i);q=(1/r-d)/(u-d);p=1-q;printf("股价二叉树为:\n");for(k=0;k<=n;k++){for(j=1;j<=k+1;j++){w=pow(u,j-1);v=pow(d,k-j+1);a[k][j]=s0*w*v;printf("%f ",a[k][j]);}printf("\n");}printf("期权二叉树为:\n");{for(j=n+1;j>=1;j--){w=pow(u,j-1);v=pow(d,n-j+1);a[k][j]=s0*w*v;if(a[n][j]<X)a[n][j]=X-a[n][j];elsea[n][j]=0;printf("%f ",a[n][j]);}printf("\n");for(k=n-1;k>=0;k--){for(j=k+1;j>=1;j--){T=X-a[k][j];a[k][j]=r*(p*a[k+1][j]+q*a[k+1][j+1]);if(T<a[k][j])a[k][j]=a[k][j];elsea[k][j]=T;printf("%f ",a[k][j]);}printf("\n");}printf("美式看跌期权定价为: ");printf("%f \n",a[0][1]);}}欧式看涨期权BS价格:#include<stdio.h>#include<math.h>#define d -1000#define pi 3.1415926double f(double x){return exp(-x*x/2);}double N(double b,double a,int n){double h,s1,s,s2=0;int k;for(k=1;k<n-1;k++){h=(b-a)/n;s1=a+k*h;s2=f(s1)+s2;}s=1/sqrt(2*pi)*h/2*(f(a)+2*s2+f(b));return (s);}main(){double s0,X,t,p,r,d1,d2,v;int n;printf("请输入股票初始价格s0:\n");scanf("%lf",&s0);printf("请输入执行价X:\n");scanf("%lf",&X);printf("请输入以年为单位的到期时间t:\n");scanf("%lf",&t);printf("请输入波动率p:\n");scanf("%lf",&p);printf("请输入无风险利率r:\n");scanf("%lf",&r);d1=(log(s0/X)+(r+p*p/2)*t)/(pow(t,0.5)*p);d2=d1-p*pow(t,0.5);printf("d1的值为:%lf\n",d1);printf("d2的值为:%lf\n",d2);printf("请输入合适划分的等份数n:\n");scanf("%d",&n);v=s0*N(d1,d,n)-X*exp(-r*t)*N(d2,d,n);printf("欧式看涨期权BS价格为:%lf\n",v);return 0;}欧式看跌期权BS价格:#include<stdio.h>#include<math.h>#define d -1000#define pi 3.1415926double f(double x){return exp(-x*x/2);}double N(double b,double a,int n){double h,s1,s,s2=0;int k;for(k=1;k<n-1;k++){h=(b-a)/n;s1=a+k*h;s2=f(s1)+s2;}s=1/sqrt(2*pi)*h/2*(f(a)+2*s2+f(b));return (s);}main(){double s0,X,t,p,r,d1,d2,v;int n;printf("请输入股票初始价格s0:\n");scanf("%lf",&s0);printf("请输入执行价X:\n");scanf("%lf",&X);printf("请输入以年为单位的到期时间t:\n");scanf("%lf",&t);printf("请输入波动率p:\n");scanf("%lf",&p);printf("请输入无风险利率r:\n");scanf("%lf",&r);d1=(log(s0/X)+(r+p*p/2)*t)/(pow(t,0.5)*p);d2=d1-p*pow(t,0.5);printf("d1的值为:%lf\n",d1);printf("d2的值为:%lf\n",d2);printf("请输入合适划分的等份数n:\n");scanf("%d",&n);v=-s0*N(-d1,d,n)+X*exp(-r*t)*N(-d2,d,n);printf("欧式看跌期权BS价格为:%lf\n",v);return 0;}。