本来想先写点理论的,但是这个其实本质涉及到B-Smodel。我觉得,二叉树depth取到无穷大,就是B-Smodel。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UserDefinedDataEXP
{
public enum BinomialType : uint
{
Additive = 1,
Multiplicative = 2,
}
//父类
public class BinomialLatticeStrategy
{
protected double u;
protected double d;
protected double p;
protected double s;
protected double r;
protected double k;
public BinomialType bType;
//构造器
public BinomialLatticeStrategy(double vol, double interest, double delta)
{
s = vol;
r = interest;
k = delta;
bType = BinomialType.Multiplicative;
}
// 根据rootValue(初始股票价格)得到结果树
public void UpdateLattice(Lattice<double> source, double rootValue)
{ // Find the depth of the lattice; this a Template Method Pattern
int si = source.MinIndex;
source[si, si] = rootValue;
// Loop from the min index to the end index
for (int n = source.MinIndex + 1; n <= source.MaxIndex; n++)
{
for (int i = 0; i < source.NumberColumns(n); i++)
{
source[n, i] = d * source[n - 1, i];
source[n, i + 1] = u * source[n - 1, i];
}
}
}
public double downValue() { return d; }
public double upValue() { return u; }
public double probValue() { return p; }
}
//CRRStrategy
public class CRRStrategy : BinomialLatticeStrategy
{
public CRRStrategy(double vol, double interest, double delta)
: base(vol, interest, delta)
{
u = Math.Exp(s*Math.Sqrt(delta)); // k是delta,即时间小段
d = 1 / u;
p = 0.5 + 0.5 * k / s * (r - 0.5 * s * s);
}
}
class BinomialMethod
{
// Simple model for GBM
// Underlying data structure
private Lattice<double> lattice; // Magic number == 2 means binomial
private BinomialLatticeStrategy str; // Reference to an algorithm(多态)
// The possibility to define constraints on top of the European
// option solution, e.g. early exercise, barriers
public delegate double ConstraintMethod(double Price, double S);
ConstraintMethod con;
bool constraintExists;
private double disc;
//构造器
public BinomialMethod (double discounting, BinomialLatticeStrategy strategy, int N)
{
disc = discounting;
str = strategy;
BuildLattice(N);
constraintExists = false;
}
public BinomialMethod(double discounting, BinomialLatticeStrategy strategy, int N, ConstraintMethod constraint)
{
disc = discounting;
str = strategy;
BuildLattice(N);
con = new ConstraintMethod(constraint);
constraintExists = true;
}
private void BuildLattice(int N)
{ // Build a binomial lattice
double val = 0.0;
lattice = new Lattice<double>(N, 2, val);
}
// 改变rootValue(初始值)= U,则生成Underlying的结果树!
public void modifyLattice(double U)
{ // Forward induction; building the tree
double down = str.downValue();
double up = str.upValue();
int si = lattice.MinIndex;
lattice[si, si] = U;
// Loop from the min index to the end index
for (int n = lattice.MinIndex + 1; n <= lattice.MaxIndex; n++)
{
for (int i = 0; i < lattice.NumberColumns(n) - 1; i++)
{
lattice[n, i] = down * lattice[n - 1, i];
lattice[n, i + 1] = up * lattice[n - 1, i];
}
}
// Postcondition: complete lattice for the underlying asset
}
//RHS是option在maturity时的payoff
public double getPrice(Vector<double> RHS)
{ // Backward induction; calculate the price based on
// discrete payoff function at t = T
double pr = str.probValue();
// Initialize the vector at the expiry date/MaxIndex
int ei = lattice.MaxIndex;
// Exception handling: sizes of RHS == size base vector
for (int i = 0; i < lattice.NumberColumns(ei); i++)
{
lattice[ei, i] = RHS[i];
}
double S; // Value at node [n,i] before overwrite
// Loop from the max index to the start (min) index
for (int n=lattice.MaxIndex - 1;n>=lattice.MinIndex; n--)
{
for (int i = 0; i < lattice.NumberColumns(n); i++)
{
S = lattice[n,i];
lattice[n, i] = disc * (pr * lattice[n + 1, i + 1]+ (1.0 - pr) * lattice[n + 1, i]);
// Now take early exercise into account if (constraintExists)
{
lattice[n, i] = con(lattice[n, i], S);
}
}
}
int si = lattice.MinIndex;
return lattice[si, si];
}
//得到树底部的underlying的价格们
public Vector<double> BasePyramidVector()
{
return lattice.BasePyramidVector();
}
// Underlying lattice
public Lattice<double> getLattice()
{
return lattice;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Globalization;
namespace UserDefinedDataEXP
{
class test
{
static void Main(string[] args)
{
int typeT = 2; // Trinomial Lattice Type
int depth = 100; // Number of periods of time
double val = 4.0;
Vector<double> xarr = new Vector<double>(depth + 1,0);
ExcelMechanisms exl = new ExcelMechanisms();
CRRStrategy bls=new CRRStrategy(0.16,0.05,1.0/depth);
BinomialMethod bm = new BinomialMethod(Math.Exp(-0.05/depth), bls, depth, cons);
//Underlying 初始价格为100
bm.modifyLattice(100);
//得到最后的underlying价格
xarr = bm.getLattice().PyramidVector(depth);
//Call Option payoff at maturity,执行价格为88元
for (int i = 0; i < xarr.MaxIndex+1; i++)
{
xarr[i] = Math.Max(0, xarr[i] - 88);
}
try
{
//exl.printLatticeInExcel(bm.getLattice(), xarr, "Lattice");
}
catch (Exception e)
{
Console.WriteLine(e);
}
//得到call option价格
Console.WriteLine(bm.getPrice(xarr));
Console.ReadLine();
}
static public double cons(double callprice, double stockprice)
{
return Math.Max(callprice, stockprice-88);
}
}
}