寒假兴致勃勃写了一个二叉树定价的类,本打算以后可以利用,然而实际上使用纯粹的二叉树在R中也能实现,并且不需要自己写,直接有现成的包。另外,许多奇异期权的定价比较复杂,如果纯粹用二叉树来模拟的话,计算量太大了,而且收敛性非常差,这时候就需要一些特定的算法比如forward shooting来进行操作。Anyway,还是纪念一下当时写了一个晚上的东西,而且后来我也没没有选择第二学期的期权课了,总感觉这些奇异的东西国内十年内都不会引进。:(
package Tree;
import java.lang.Math;
public class Node {
int level;
double price;
double option;
Node left;
Node right;
//构造函数
Node(){
this.level=0;
this.price=0;
this.option=0;
this.right=null;
this.left=null;
}
Node(int n,double p){
this.level=n;
this.price=p;
this.option=0;
this.right=null;
this.left=null;
}
//Method1:已某一个已存在的Node为起始,构建后面的二叉树
public static void insert(Node nd,Node ndleft,int steps, doubleup,double down){
if(steps>0){
if(ndleft==null){
nd.left=new Node();
nd.left.level=nd.level+1;
nd.left.price=nd.price*down;
nd.right=new Node();
nd.right.level=nd.level+1;
nd.right.price=nd.price*up;
insert(nd.left,nd.left.left,--steps,up,down);
steps++;
insert(nd.right,nd.left.right,--steps,up,down);
}
else{
nd.left=ndleft;
nd.right=new Node();
nd.right.level=nd.level+1;
nd.right.price=nd.price*up;
insert(nd.right,nd.left.right,--steps,up,down);
}
}
}
//Method2: 提取某Node的价格信息
public static double VisitPrice(Node nd){
System.out.println(String.format("%.3f", nd.price)+" ");
return nd.price;
}
//Method3: 修改某一个Node的股价
public static void SetPrice(Node nd,double p){
nd.price=p;
}
//Method4: 返回某个Node的期权价值
public static double VisitOption(Node nd){
System.out.println(String.format("%.3f", nd.option)+" ");
return nd.option;
}
public static void SetOption(Node nd,double opt){
nd.price=opt;
}
public static void upline(Node t){
if(t!=null){
//VisitPrice(t);
upline(t.right);
}
}
public static void traverse(Node t){
if(t!=null){
upline(t);
traverse(t.left);
}
}
public static int GetDepth(Node t){
if(t==null)
return 0;
else
return GetDepth(t.right)+1;
}
public static int NodeCounter(Node t){
if(t==null)
return 0;
else
return GetDepth(t)+NodeCounter(t.left);
}
public static Node getUp(Node t,int numUp){
Node temp=t;
if(numUp>0)
temp=getUp(t.right,--numUp);
return temp;//最后一个return之后就内存清空了,之前不需要的return不会return
}
public static Node getDown(Node t,int numDown){
Node temp=t;
if(numDown>0)
temp=getDown(t.left,--numDown);
return temp;
}
public static Node getNode(Node t,int numUp,int numDown){
Node temp=t;
temp=getDown(getUp(t,numUp),numDown);
return temp;
}
public static void Plant(Node t,double up,double down){
int n=GetDepth(t)-1;
insert(getUp(t,n),getUp(t,n).left,1,up,down);
}
//Method13: 在最后一排树之后再重种植一排新的树
public static void LinePlant(Node t,double up,double down){
//先得到原始树的深度,因为下面种了会改变,我默认对称树,只取了右上深度作为树的深度,没有进行左右取min
int round=GetDepth(t)-1;
Plant(t,up,down);//最右上角新种一棵小树苗
//编织下面的树木
for(int i=round;i>0;i--){
getNode(t,i-1,round-i+1).right=getNode(t,i,round-i).left;//连接上一个枝丫
getNode(t,i-1,round-i+1).left=newNode(getNode(t,i-1,round-i+1).level+1,getNode(t,i-1,round-i+1).price*down);//造一个向下单枝丫
}
}
public static void main(String[] args){
double spot=100;
double strike=100;
double interest=0.03;
double up=1.1;
double down=1/up;
Node root=new Node(1,100);
try{
insert(root,root.left,3,up,down);
System.out.println("the depth of the whole tree is"+GetDepth(root));
System.out.println("the total number of Nodes in the tree"+NodeCounter(root));
LinePlant(root,up,down);
System.out.println("the depth of the whole tree is"+GetDepth(root));
System.out.println("the total number of Nodes in the tree"+NodeCounter(root));
LinePlant(root,up,down);
System.out.println("the depth of the whole tree is"+GetDepth(root));
System.out.println("the total number of Nodes in the tree"+NodeCounter(root));
}
catch(Exception e){
System.out.println("Huston, we have a problem ! "+e);
}
}
}
In R: use foption package.
library(fOptions)
#Calculate the value of the option and plot
optionVals<-BinomialTreeOption(TypeFlag="ce",S=100,X=100,Time=3,r=0.03,b=0,sigma=0.2,n=5,title="binomial tree")
BinomialTreePlot(optionVals)